/*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ "use strict"; var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var ts; (function (ts) { /* @internal */ var Comparison; (function (Comparison) { Comparison[Comparison["LessThan"] = -1] = "LessThan"; Comparison[Comparison["EqualTo"] = 0] = "EqualTo"; Comparison[Comparison["GreaterThan"] = 1] = "GreaterThan"; })(Comparison = ts.Comparison || (ts.Comparison = {})); // token > SyntaxKind.Identifer => token is a keyword // Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync var SyntaxKind; (function (SyntaxKind) { SyntaxKind[SyntaxKind["Unknown"] = 0] = "Unknown"; SyntaxKind[SyntaxKind["EndOfFileToken"] = 1] = "EndOfFileToken"; SyntaxKind[SyntaxKind["SingleLineCommentTrivia"] = 2] = "SingleLineCommentTrivia"; SyntaxKind[SyntaxKind["MultiLineCommentTrivia"] = 3] = "MultiLineCommentTrivia"; SyntaxKind[SyntaxKind["NewLineTrivia"] = 4] = "NewLineTrivia"; SyntaxKind[SyntaxKind["WhitespaceTrivia"] = 5] = "WhitespaceTrivia"; // We detect and preserve #! on the first line SyntaxKind[SyntaxKind["ShebangTrivia"] = 6] = "ShebangTrivia"; // We detect and provide better error recovery when we encounter a git merge marker. This // allows us to edit files with git-conflict markers in them in a much more pleasant manner. SyntaxKind[SyntaxKind["ConflictMarkerTrivia"] = 7] = "ConflictMarkerTrivia"; // Literals SyntaxKind[SyntaxKind["NumericLiteral"] = 8] = "NumericLiteral"; SyntaxKind[SyntaxKind["StringLiteral"] = 9] = "StringLiteral"; SyntaxKind[SyntaxKind["JsxText"] = 10] = "JsxText"; SyntaxKind[SyntaxKind["JsxTextAllWhiteSpaces"] = 11] = "JsxTextAllWhiteSpaces"; SyntaxKind[SyntaxKind["RegularExpressionLiteral"] = 12] = "RegularExpressionLiteral"; SyntaxKind[SyntaxKind["NoSubstitutionTemplateLiteral"] = 13] = "NoSubstitutionTemplateLiteral"; // Pseudo-literals SyntaxKind[SyntaxKind["TemplateHead"] = 14] = "TemplateHead"; SyntaxKind[SyntaxKind["TemplateMiddle"] = 15] = "TemplateMiddle"; SyntaxKind[SyntaxKind["TemplateTail"] = 16] = "TemplateTail"; // Punctuation SyntaxKind[SyntaxKind["OpenBraceToken"] = 17] = "OpenBraceToken"; SyntaxKind[SyntaxKind["CloseBraceToken"] = 18] = "CloseBraceToken"; SyntaxKind[SyntaxKind["OpenParenToken"] = 19] = "OpenParenToken"; SyntaxKind[SyntaxKind["CloseParenToken"] = 20] = "CloseParenToken"; SyntaxKind[SyntaxKind["OpenBracketToken"] = 21] = "OpenBracketToken"; SyntaxKind[SyntaxKind["CloseBracketToken"] = 22] = "CloseBracketToken"; SyntaxKind[SyntaxKind["DotToken"] = 23] = "DotToken"; SyntaxKind[SyntaxKind["DotDotDotToken"] = 24] = "DotDotDotToken"; SyntaxKind[SyntaxKind["SemicolonToken"] = 25] = "SemicolonToken"; SyntaxKind[SyntaxKind["CommaToken"] = 26] = "CommaToken"; SyntaxKind[SyntaxKind["LessThanToken"] = 27] = "LessThanToken"; SyntaxKind[SyntaxKind["LessThanSlashToken"] = 28] = "LessThanSlashToken"; SyntaxKind[SyntaxKind["GreaterThanToken"] = 29] = "GreaterThanToken"; SyntaxKind[SyntaxKind["LessThanEqualsToken"] = 30] = "LessThanEqualsToken"; SyntaxKind[SyntaxKind["GreaterThanEqualsToken"] = 31] = "GreaterThanEqualsToken"; SyntaxKind[SyntaxKind["EqualsEqualsToken"] = 32] = "EqualsEqualsToken"; SyntaxKind[SyntaxKind["ExclamationEqualsToken"] = 33] = "ExclamationEqualsToken"; SyntaxKind[SyntaxKind["EqualsEqualsEqualsToken"] = 34] = "EqualsEqualsEqualsToken"; SyntaxKind[SyntaxKind["ExclamationEqualsEqualsToken"] = 35] = "ExclamationEqualsEqualsToken"; SyntaxKind[SyntaxKind["EqualsGreaterThanToken"] = 36] = "EqualsGreaterThanToken"; SyntaxKind[SyntaxKind["PlusToken"] = 37] = "PlusToken"; SyntaxKind[SyntaxKind["MinusToken"] = 38] = "MinusToken"; SyntaxKind[SyntaxKind["AsteriskToken"] = 39] = "AsteriskToken"; SyntaxKind[SyntaxKind["AsteriskAsteriskToken"] = 40] = "AsteriskAsteriskToken"; SyntaxKind[SyntaxKind["SlashToken"] = 41] = "SlashToken"; SyntaxKind[SyntaxKind["PercentToken"] = 42] = "PercentToken"; SyntaxKind[SyntaxKind["PlusPlusToken"] = 43] = "PlusPlusToken"; SyntaxKind[SyntaxKind["MinusMinusToken"] = 44] = "MinusMinusToken"; SyntaxKind[SyntaxKind["LessThanLessThanToken"] = 45] = "LessThanLessThanToken"; SyntaxKind[SyntaxKind["GreaterThanGreaterThanToken"] = 46] = "GreaterThanGreaterThanToken"; SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanToken"] = 47] = "GreaterThanGreaterThanGreaterThanToken"; SyntaxKind[SyntaxKind["AmpersandToken"] = 48] = "AmpersandToken"; SyntaxKind[SyntaxKind["BarToken"] = 49] = "BarToken"; SyntaxKind[SyntaxKind["CaretToken"] = 50] = "CaretToken"; SyntaxKind[SyntaxKind["ExclamationToken"] = 51] = "ExclamationToken"; SyntaxKind[SyntaxKind["TildeToken"] = 52] = "TildeToken"; SyntaxKind[SyntaxKind["AmpersandAmpersandToken"] = 53] = "AmpersandAmpersandToken"; SyntaxKind[SyntaxKind["BarBarToken"] = 54] = "BarBarToken"; SyntaxKind[SyntaxKind["QuestionToken"] = 55] = "QuestionToken"; SyntaxKind[SyntaxKind["ColonToken"] = 56] = "ColonToken"; SyntaxKind[SyntaxKind["AtToken"] = 57] = "AtToken"; // Assignments SyntaxKind[SyntaxKind["EqualsToken"] = 58] = "EqualsToken"; SyntaxKind[SyntaxKind["PlusEqualsToken"] = 59] = "PlusEqualsToken"; SyntaxKind[SyntaxKind["MinusEqualsToken"] = 60] = "MinusEqualsToken"; SyntaxKind[SyntaxKind["AsteriskEqualsToken"] = 61] = "AsteriskEqualsToken"; SyntaxKind[SyntaxKind["AsteriskAsteriskEqualsToken"] = 62] = "AsteriskAsteriskEqualsToken"; SyntaxKind[SyntaxKind["SlashEqualsToken"] = 63] = "SlashEqualsToken"; SyntaxKind[SyntaxKind["PercentEqualsToken"] = 64] = "PercentEqualsToken"; SyntaxKind[SyntaxKind["LessThanLessThanEqualsToken"] = 65] = "LessThanLessThanEqualsToken"; SyntaxKind[SyntaxKind["GreaterThanGreaterThanEqualsToken"] = 66] = "GreaterThanGreaterThanEqualsToken"; SyntaxKind[SyntaxKind["GreaterThanGreaterThanGreaterThanEqualsToken"] = 67] = "GreaterThanGreaterThanGreaterThanEqualsToken"; SyntaxKind[SyntaxKind["AmpersandEqualsToken"] = 68] = "AmpersandEqualsToken"; SyntaxKind[SyntaxKind["BarEqualsToken"] = 69] = "BarEqualsToken"; SyntaxKind[SyntaxKind["CaretEqualsToken"] = 70] = "CaretEqualsToken"; // Identifiers SyntaxKind[SyntaxKind["Identifier"] = 71] = "Identifier"; // Reserved words SyntaxKind[SyntaxKind["BreakKeyword"] = 72] = "BreakKeyword"; SyntaxKind[SyntaxKind["CaseKeyword"] = 73] = "CaseKeyword"; SyntaxKind[SyntaxKind["CatchKeyword"] = 74] = "CatchKeyword"; SyntaxKind[SyntaxKind["ClassKeyword"] = 75] = "ClassKeyword"; SyntaxKind[SyntaxKind["ConstKeyword"] = 76] = "ConstKeyword"; SyntaxKind[SyntaxKind["ContinueKeyword"] = 77] = "ContinueKeyword"; SyntaxKind[SyntaxKind["DebuggerKeyword"] = 78] = "DebuggerKeyword"; SyntaxKind[SyntaxKind["DefaultKeyword"] = 79] = "DefaultKeyword"; SyntaxKind[SyntaxKind["DeleteKeyword"] = 80] = "DeleteKeyword"; SyntaxKind[SyntaxKind["DoKeyword"] = 81] = "DoKeyword"; SyntaxKind[SyntaxKind["ElseKeyword"] = 82] = "ElseKeyword"; SyntaxKind[SyntaxKind["EnumKeyword"] = 83] = "EnumKeyword"; SyntaxKind[SyntaxKind["ExportKeyword"] = 84] = "ExportKeyword"; SyntaxKind[SyntaxKind["ExtendsKeyword"] = 85] = "ExtendsKeyword"; SyntaxKind[SyntaxKind["FalseKeyword"] = 86] = "FalseKeyword"; SyntaxKind[SyntaxKind["FinallyKeyword"] = 87] = "FinallyKeyword"; SyntaxKind[SyntaxKind["ForKeyword"] = 88] = "ForKeyword"; SyntaxKind[SyntaxKind["FunctionKeyword"] = 89] = "FunctionKeyword"; SyntaxKind[SyntaxKind["IfKeyword"] = 90] = "IfKeyword"; SyntaxKind[SyntaxKind["ImportKeyword"] = 91] = "ImportKeyword"; SyntaxKind[SyntaxKind["InKeyword"] = 92] = "InKeyword"; SyntaxKind[SyntaxKind["InstanceOfKeyword"] = 93] = "InstanceOfKeyword"; SyntaxKind[SyntaxKind["NewKeyword"] = 94] = "NewKeyword"; SyntaxKind[SyntaxKind["NullKeyword"] = 95] = "NullKeyword"; SyntaxKind[SyntaxKind["ReturnKeyword"] = 96] = "ReturnKeyword"; SyntaxKind[SyntaxKind["SuperKeyword"] = 97] = "SuperKeyword"; SyntaxKind[SyntaxKind["SwitchKeyword"] = 98] = "SwitchKeyword"; SyntaxKind[SyntaxKind["ThisKeyword"] = 99] = "ThisKeyword"; SyntaxKind[SyntaxKind["ThrowKeyword"] = 100] = "ThrowKeyword"; SyntaxKind[SyntaxKind["TrueKeyword"] = 101] = "TrueKeyword"; SyntaxKind[SyntaxKind["TryKeyword"] = 102] = "TryKeyword"; SyntaxKind[SyntaxKind["TypeOfKeyword"] = 103] = "TypeOfKeyword"; SyntaxKind[SyntaxKind["VarKeyword"] = 104] = "VarKeyword"; SyntaxKind[SyntaxKind["VoidKeyword"] = 105] = "VoidKeyword"; SyntaxKind[SyntaxKind["WhileKeyword"] = 106] = "WhileKeyword"; SyntaxKind[SyntaxKind["WithKeyword"] = 107] = "WithKeyword"; // Strict mode reserved words SyntaxKind[SyntaxKind["ImplementsKeyword"] = 108] = "ImplementsKeyword"; SyntaxKind[SyntaxKind["InterfaceKeyword"] = 109] = "InterfaceKeyword"; SyntaxKind[SyntaxKind["LetKeyword"] = 110] = "LetKeyword"; SyntaxKind[SyntaxKind["PackageKeyword"] = 111] = "PackageKeyword"; SyntaxKind[SyntaxKind["PrivateKeyword"] = 112] = "PrivateKeyword"; SyntaxKind[SyntaxKind["ProtectedKeyword"] = 113] = "ProtectedKeyword"; SyntaxKind[SyntaxKind["PublicKeyword"] = 114] = "PublicKeyword"; SyntaxKind[SyntaxKind["StaticKeyword"] = 115] = "StaticKeyword"; SyntaxKind[SyntaxKind["YieldKeyword"] = 116] = "YieldKeyword"; // Contextual keywords SyntaxKind[SyntaxKind["AbstractKeyword"] = 117] = "AbstractKeyword"; SyntaxKind[SyntaxKind["AsKeyword"] = 118] = "AsKeyword"; SyntaxKind[SyntaxKind["AnyKeyword"] = 119] = "AnyKeyword"; SyntaxKind[SyntaxKind["AsyncKeyword"] = 120] = "AsyncKeyword"; SyntaxKind[SyntaxKind["AwaitKeyword"] = 121] = "AwaitKeyword"; SyntaxKind[SyntaxKind["BooleanKeyword"] = 122] = "BooleanKeyword"; SyntaxKind[SyntaxKind["ConstructorKeyword"] = 123] = "ConstructorKeyword"; SyntaxKind[SyntaxKind["DeclareKeyword"] = 124] = "DeclareKeyword"; SyntaxKind[SyntaxKind["GetKeyword"] = 125] = "GetKeyword"; SyntaxKind[SyntaxKind["IsKeyword"] = 126] = "IsKeyword"; SyntaxKind[SyntaxKind["KeyOfKeyword"] = 127] = "KeyOfKeyword"; SyntaxKind[SyntaxKind["ModuleKeyword"] = 128] = "ModuleKeyword"; SyntaxKind[SyntaxKind["NamespaceKeyword"] = 129] = "NamespaceKeyword"; SyntaxKind[SyntaxKind["NeverKeyword"] = 130] = "NeverKeyword"; SyntaxKind[SyntaxKind["ReadonlyKeyword"] = 131] = "ReadonlyKeyword"; SyntaxKind[SyntaxKind["RequireKeyword"] = 132] = "RequireKeyword"; SyntaxKind[SyntaxKind["NumberKeyword"] = 133] = "NumberKeyword"; SyntaxKind[SyntaxKind["ObjectKeyword"] = 134] = "ObjectKeyword"; SyntaxKind[SyntaxKind["SetKeyword"] = 135] = "SetKeyword"; SyntaxKind[SyntaxKind["StringKeyword"] = 136] = "StringKeyword"; SyntaxKind[SyntaxKind["SymbolKeyword"] = 137] = "SymbolKeyword"; SyntaxKind[SyntaxKind["TypeKeyword"] = 138] = "TypeKeyword"; SyntaxKind[SyntaxKind["UndefinedKeyword"] = 139] = "UndefinedKeyword"; SyntaxKind[SyntaxKind["UniqueKeyword"] = 140] = "UniqueKeyword"; SyntaxKind[SyntaxKind["FromKeyword"] = 141] = "FromKeyword"; SyntaxKind[SyntaxKind["GlobalKeyword"] = 142] = "GlobalKeyword"; SyntaxKind[SyntaxKind["OfKeyword"] = 143] = "OfKeyword"; // Parse tree nodes // Names SyntaxKind[SyntaxKind["QualifiedName"] = 144] = "QualifiedName"; SyntaxKind[SyntaxKind["ComputedPropertyName"] = 145] = "ComputedPropertyName"; // Signature elements SyntaxKind[SyntaxKind["TypeParameter"] = 146] = "TypeParameter"; SyntaxKind[SyntaxKind["Parameter"] = 147] = "Parameter"; SyntaxKind[SyntaxKind["Decorator"] = 148] = "Decorator"; // TypeMember SyntaxKind[SyntaxKind["PropertySignature"] = 149] = "PropertySignature"; SyntaxKind[SyntaxKind["PropertyDeclaration"] = 150] = "PropertyDeclaration"; SyntaxKind[SyntaxKind["MethodSignature"] = 151] = "MethodSignature"; SyntaxKind[SyntaxKind["MethodDeclaration"] = 152] = "MethodDeclaration"; SyntaxKind[SyntaxKind["Constructor"] = 153] = "Constructor"; SyntaxKind[SyntaxKind["GetAccessor"] = 154] = "GetAccessor"; SyntaxKind[SyntaxKind["SetAccessor"] = 155] = "SetAccessor"; SyntaxKind[SyntaxKind["CallSignature"] = 156] = "CallSignature"; SyntaxKind[SyntaxKind["ConstructSignature"] = 157] = "ConstructSignature"; SyntaxKind[SyntaxKind["IndexSignature"] = 158] = "IndexSignature"; // Type SyntaxKind[SyntaxKind["TypePredicate"] = 159] = "TypePredicate"; SyntaxKind[SyntaxKind["TypeReference"] = 160] = "TypeReference"; SyntaxKind[SyntaxKind["FunctionType"] = 161] = "FunctionType"; SyntaxKind[SyntaxKind["ConstructorType"] = 162] = "ConstructorType"; SyntaxKind[SyntaxKind["TypeQuery"] = 163] = "TypeQuery"; SyntaxKind[SyntaxKind["TypeLiteral"] = 164] = "TypeLiteral"; SyntaxKind[SyntaxKind["ArrayType"] = 165] = "ArrayType"; SyntaxKind[SyntaxKind["TupleType"] = 166] = "TupleType"; SyntaxKind[SyntaxKind["UnionType"] = 167] = "UnionType"; SyntaxKind[SyntaxKind["IntersectionType"] = 168] = "IntersectionType"; SyntaxKind[SyntaxKind["ParenthesizedType"] = 169] = "ParenthesizedType"; SyntaxKind[SyntaxKind["ThisType"] = 170] = "ThisType"; SyntaxKind[SyntaxKind["TypeOperator"] = 171] = "TypeOperator"; SyntaxKind[SyntaxKind["IndexedAccessType"] = 172] = "IndexedAccessType"; SyntaxKind[SyntaxKind["MappedType"] = 173] = "MappedType"; SyntaxKind[SyntaxKind["LiteralType"] = 174] = "LiteralType"; // Binding patterns SyntaxKind[SyntaxKind["ObjectBindingPattern"] = 175] = "ObjectBindingPattern"; SyntaxKind[SyntaxKind["ArrayBindingPattern"] = 176] = "ArrayBindingPattern"; SyntaxKind[SyntaxKind["BindingElement"] = 177] = "BindingElement"; // Expression SyntaxKind[SyntaxKind["ArrayLiteralExpression"] = 178] = "ArrayLiteralExpression"; SyntaxKind[SyntaxKind["ObjectLiteralExpression"] = 179] = "ObjectLiteralExpression"; SyntaxKind[SyntaxKind["PropertyAccessExpression"] = 180] = "PropertyAccessExpression"; SyntaxKind[SyntaxKind["ElementAccessExpression"] = 181] = "ElementAccessExpression"; SyntaxKind[SyntaxKind["CallExpression"] = 182] = "CallExpression"; SyntaxKind[SyntaxKind["NewExpression"] = 183] = "NewExpression"; SyntaxKind[SyntaxKind["TaggedTemplateExpression"] = 184] = "TaggedTemplateExpression"; SyntaxKind[SyntaxKind["TypeAssertionExpression"] = 185] = "TypeAssertionExpression"; SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 186] = "ParenthesizedExpression"; SyntaxKind[SyntaxKind["FunctionExpression"] = 187] = "FunctionExpression"; SyntaxKind[SyntaxKind["ArrowFunction"] = 188] = "ArrowFunction"; SyntaxKind[SyntaxKind["DeleteExpression"] = 189] = "DeleteExpression"; SyntaxKind[SyntaxKind["TypeOfExpression"] = 190] = "TypeOfExpression"; SyntaxKind[SyntaxKind["VoidExpression"] = 191] = "VoidExpression"; SyntaxKind[SyntaxKind["AwaitExpression"] = 192] = "AwaitExpression"; SyntaxKind[SyntaxKind["PrefixUnaryExpression"] = 193] = "PrefixUnaryExpression"; SyntaxKind[SyntaxKind["PostfixUnaryExpression"] = 194] = "PostfixUnaryExpression"; SyntaxKind[SyntaxKind["BinaryExpression"] = 195] = "BinaryExpression"; SyntaxKind[SyntaxKind["ConditionalExpression"] = 196] = "ConditionalExpression"; SyntaxKind[SyntaxKind["TemplateExpression"] = 197] = "TemplateExpression"; SyntaxKind[SyntaxKind["YieldExpression"] = 198] = "YieldExpression"; SyntaxKind[SyntaxKind["SpreadElement"] = 199] = "SpreadElement"; SyntaxKind[SyntaxKind["ClassExpression"] = 200] = "ClassExpression"; SyntaxKind[SyntaxKind["OmittedExpression"] = 201] = "OmittedExpression"; SyntaxKind[SyntaxKind["ExpressionWithTypeArguments"] = 202] = "ExpressionWithTypeArguments"; SyntaxKind[SyntaxKind["AsExpression"] = 203] = "AsExpression"; SyntaxKind[SyntaxKind["NonNullExpression"] = 204] = "NonNullExpression"; SyntaxKind[SyntaxKind["MetaProperty"] = 205] = "MetaProperty"; // Misc SyntaxKind[SyntaxKind["TemplateSpan"] = 206] = "TemplateSpan"; SyntaxKind[SyntaxKind["SemicolonClassElement"] = 207] = "SemicolonClassElement"; // Element SyntaxKind[SyntaxKind["Block"] = 208] = "Block"; SyntaxKind[SyntaxKind["VariableStatement"] = 209] = "VariableStatement"; SyntaxKind[SyntaxKind["EmptyStatement"] = 210] = "EmptyStatement"; SyntaxKind[SyntaxKind["ExpressionStatement"] = 211] = "ExpressionStatement"; SyntaxKind[SyntaxKind["IfStatement"] = 212] = "IfStatement"; SyntaxKind[SyntaxKind["DoStatement"] = 213] = "DoStatement"; SyntaxKind[SyntaxKind["WhileStatement"] = 214] = "WhileStatement"; SyntaxKind[SyntaxKind["ForStatement"] = 215] = "ForStatement"; SyntaxKind[SyntaxKind["ForInStatement"] = 216] = "ForInStatement"; SyntaxKind[SyntaxKind["ForOfStatement"] = 217] = "ForOfStatement"; SyntaxKind[SyntaxKind["ContinueStatement"] = 218] = "ContinueStatement"; SyntaxKind[SyntaxKind["BreakStatement"] = 219] = "BreakStatement"; SyntaxKind[SyntaxKind["ReturnStatement"] = 220] = "ReturnStatement"; SyntaxKind[SyntaxKind["WithStatement"] = 221] = "WithStatement"; SyntaxKind[SyntaxKind["SwitchStatement"] = 222] = "SwitchStatement"; SyntaxKind[SyntaxKind["LabeledStatement"] = 223] = "LabeledStatement"; SyntaxKind[SyntaxKind["ThrowStatement"] = 224] = "ThrowStatement"; SyntaxKind[SyntaxKind["TryStatement"] = 225] = "TryStatement"; SyntaxKind[SyntaxKind["DebuggerStatement"] = 226] = "DebuggerStatement"; SyntaxKind[SyntaxKind["VariableDeclaration"] = 227] = "VariableDeclaration"; SyntaxKind[SyntaxKind["VariableDeclarationList"] = 228] = "VariableDeclarationList"; SyntaxKind[SyntaxKind["FunctionDeclaration"] = 229] = "FunctionDeclaration"; SyntaxKind[SyntaxKind["ClassDeclaration"] = 230] = "ClassDeclaration"; SyntaxKind[SyntaxKind["InterfaceDeclaration"] = 231] = "InterfaceDeclaration"; SyntaxKind[SyntaxKind["TypeAliasDeclaration"] = 232] = "TypeAliasDeclaration"; SyntaxKind[SyntaxKind["EnumDeclaration"] = 233] = "EnumDeclaration"; SyntaxKind[SyntaxKind["ModuleDeclaration"] = 234] = "ModuleDeclaration"; SyntaxKind[SyntaxKind["ModuleBlock"] = 235] = "ModuleBlock"; SyntaxKind[SyntaxKind["CaseBlock"] = 236] = "CaseBlock"; SyntaxKind[SyntaxKind["NamespaceExportDeclaration"] = 237] = "NamespaceExportDeclaration"; SyntaxKind[SyntaxKind["ImportEqualsDeclaration"] = 238] = "ImportEqualsDeclaration"; SyntaxKind[SyntaxKind["ImportDeclaration"] = 239] = "ImportDeclaration"; SyntaxKind[SyntaxKind["ImportClause"] = 240] = "ImportClause"; SyntaxKind[SyntaxKind["NamespaceImport"] = 241] = "NamespaceImport"; SyntaxKind[SyntaxKind["NamedImports"] = 242] = "NamedImports"; SyntaxKind[SyntaxKind["ImportSpecifier"] = 243] = "ImportSpecifier"; SyntaxKind[SyntaxKind["ExportAssignment"] = 244] = "ExportAssignment"; SyntaxKind[SyntaxKind["ExportDeclaration"] = 245] = "ExportDeclaration"; SyntaxKind[SyntaxKind["NamedExports"] = 246] = "NamedExports"; SyntaxKind[SyntaxKind["ExportSpecifier"] = 247] = "ExportSpecifier"; SyntaxKind[SyntaxKind["MissingDeclaration"] = 248] = "MissingDeclaration"; // Module references SyntaxKind[SyntaxKind["ExternalModuleReference"] = 249] = "ExternalModuleReference"; // JSX SyntaxKind[SyntaxKind["JsxElement"] = 250] = "JsxElement"; SyntaxKind[SyntaxKind["JsxSelfClosingElement"] = 251] = "JsxSelfClosingElement"; SyntaxKind[SyntaxKind["JsxOpeningElement"] = 252] = "JsxOpeningElement"; SyntaxKind[SyntaxKind["JsxClosingElement"] = 253] = "JsxClosingElement"; SyntaxKind[SyntaxKind["JsxFragment"] = 254] = "JsxFragment"; SyntaxKind[SyntaxKind["JsxOpeningFragment"] = 255] = "JsxOpeningFragment"; SyntaxKind[SyntaxKind["JsxClosingFragment"] = 256] = "JsxClosingFragment"; SyntaxKind[SyntaxKind["JsxAttribute"] = 257] = "JsxAttribute"; SyntaxKind[SyntaxKind["JsxAttributes"] = 258] = "JsxAttributes"; SyntaxKind[SyntaxKind["JsxSpreadAttribute"] = 259] = "JsxSpreadAttribute"; SyntaxKind[SyntaxKind["JsxExpression"] = 260] = "JsxExpression"; // Clauses SyntaxKind[SyntaxKind["CaseClause"] = 261] = "CaseClause"; SyntaxKind[SyntaxKind["DefaultClause"] = 262] = "DefaultClause"; SyntaxKind[SyntaxKind["HeritageClause"] = 263] = "HeritageClause"; SyntaxKind[SyntaxKind["CatchClause"] = 264] = "CatchClause"; // Property assignments SyntaxKind[SyntaxKind["PropertyAssignment"] = 265] = "PropertyAssignment"; SyntaxKind[SyntaxKind["ShorthandPropertyAssignment"] = 266] = "ShorthandPropertyAssignment"; SyntaxKind[SyntaxKind["SpreadAssignment"] = 267] = "SpreadAssignment"; // Enum SyntaxKind[SyntaxKind["EnumMember"] = 268] = "EnumMember"; // Top-level nodes SyntaxKind[SyntaxKind["SourceFile"] = 269] = "SourceFile"; SyntaxKind[SyntaxKind["Bundle"] = 270] = "Bundle"; // JSDoc nodes SyntaxKind[SyntaxKind["JSDocTypeExpression"] = 271] = "JSDocTypeExpression"; // The * type SyntaxKind[SyntaxKind["JSDocAllType"] = 272] = "JSDocAllType"; // The ? type SyntaxKind[SyntaxKind["JSDocUnknownType"] = 273] = "JSDocUnknownType"; SyntaxKind[SyntaxKind["JSDocNullableType"] = 274] = "JSDocNullableType"; SyntaxKind[SyntaxKind["JSDocNonNullableType"] = 275] = "JSDocNonNullableType"; SyntaxKind[SyntaxKind["JSDocOptionalType"] = 276] = "JSDocOptionalType"; SyntaxKind[SyntaxKind["JSDocFunctionType"] = 277] = "JSDocFunctionType"; SyntaxKind[SyntaxKind["JSDocVariadicType"] = 278] = "JSDocVariadicType"; SyntaxKind[SyntaxKind["JSDocComment"] = 279] = "JSDocComment"; SyntaxKind[SyntaxKind["JSDocTypeLiteral"] = 280] = "JSDocTypeLiteral"; SyntaxKind[SyntaxKind["JSDocTag"] = 281] = "JSDocTag"; SyntaxKind[SyntaxKind["JSDocAugmentsTag"] = 282] = "JSDocAugmentsTag"; SyntaxKind[SyntaxKind["JSDocClassTag"] = 283] = "JSDocClassTag"; SyntaxKind[SyntaxKind["JSDocParameterTag"] = 284] = "JSDocParameterTag"; SyntaxKind[SyntaxKind["JSDocReturnTag"] = 285] = "JSDocReturnTag"; SyntaxKind[SyntaxKind["JSDocTypeTag"] = 286] = "JSDocTypeTag"; SyntaxKind[SyntaxKind["JSDocTemplateTag"] = 287] = "JSDocTemplateTag"; SyntaxKind[SyntaxKind["JSDocTypedefTag"] = 288] = "JSDocTypedefTag"; SyntaxKind[SyntaxKind["JSDocPropertyTag"] = 289] = "JSDocPropertyTag"; // Synthesized list SyntaxKind[SyntaxKind["SyntaxList"] = 290] = "SyntaxList"; // Transformation nodes SyntaxKind[SyntaxKind["NotEmittedStatement"] = 291] = "NotEmittedStatement"; SyntaxKind[SyntaxKind["PartiallyEmittedExpression"] = 292] = "PartiallyEmittedExpression"; SyntaxKind[SyntaxKind["CommaListExpression"] = 293] = "CommaListExpression"; SyntaxKind[SyntaxKind["MergeDeclarationMarker"] = 294] = "MergeDeclarationMarker"; SyntaxKind[SyntaxKind["EndOfDeclarationMarker"] = 295] = "EndOfDeclarationMarker"; // Enum value count SyntaxKind[SyntaxKind["Count"] = 296] = "Count"; // Markers SyntaxKind[SyntaxKind["FirstAssignment"] = 58] = "FirstAssignment"; SyntaxKind[SyntaxKind["LastAssignment"] = 70] = "LastAssignment"; SyntaxKind[SyntaxKind["FirstCompoundAssignment"] = 59] = "FirstCompoundAssignment"; SyntaxKind[SyntaxKind["LastCompoundAssignment"] = 70] = "LastCompoundAssignment"; SyntaxKind[SyntaxKind["FirstReservedWord"] = 72] = "FirstReservedWord"; SyntaxKind[SyntaxKind["LastReservedWord"] = 107] = "LastReservedWord"; SyntaxKind[SyntaxKind["FirstKeyword"] = 72] = "FirstKeyword"; SyntaxKind[SyntaxKind["LastKeyword"] = 143] = "LastKeyword"; SyntaxKind[SyntaxKind["FirstFutureReservedWord"] = 108] = "FirstFutureReservedWord"; SyntaxKind[SyntaxKind["LastFutureReservedWord"] = 116] = "LastFutureReservedWord"; SyntaxKind[SyntaxKind["FirstTypeNode"] = 159] = "FirstTypeNode"; SyntaxKind[SyntaxKind["LastTypeNode"] = 174] = "LastTypeNode"; SyntaxKind[SyntaxKind["FirstPunctuation"] = 17] = "FirstPunctuation"; SyntaxKind[SyntaxKind["LastPunctuation"] = 70] = "LastPunctuation"; SyntaxKind[SyntaxKind["FirstToken"] = 0] = "FirstToken"; SyntaxKind[SyntaxKind["LastToken"] = 143] = "LastToken"; SyntaxKind[SyntaxKind["FirstTriviaToken"] = 2] = "FirstTriviaToken"; SyntaxKind[SyntaxKind["LastTriviaToken"] = 7] = "LastTriviaToken"; SyntaxKind[SyntaxKind["FirstLiteralToken"] = 8] = "FirstLiteralToken"; SyntaxKind[SyntaxKind["LastLiteralToken"] = 13] = "LastLiteralToken"; SyntaxKind[SyntaxKind["FirstTemplateToken"] = 13] = "FirstTemplateToken"; SyntaxKind[SyntaxKind["LastTemplateToken"] = 16] = "LastTemplateToken"; SyntaxKind[SyntaxKind["FirstBinaryOperator"] = 27] = "FirstBinaryOperator"; SyntaxKind[SyntaxKind["LastBinaryOperator"] = 70] = "LastBinaryOperator"; SyntaxKind[SyntaxKind["FirstNode"] = 144] = "FirstNode"; SyntaxKind[SyntaxKind["FirstJSDocNode"] = 271] = "FirstJSDocNode"; SyntaxKind[SyntaxKind["LastJSDocNode"] = 289] = "LastJSDocNode"; SyntaxKind[SyntaxKind["FirstJSDocTagNode"] = 281] = "FirstJSDocTagNode"; SyntaxKind[SyntaxKind["LastJSDocTagNode"] = 289] = "LastJSDocTagNode"; /* @internal */ SyntaxKind[SyntaxKind["FirstContextualKeyword"] = 117] = "FirstContextualKeyword"; /* @internal */ SyntaxKind[SyntaxKind["LastContextualKeyword"] = 143] = "LastContextualKeyword"; })(SyntaxKind = ts.SyntaxKind || (ts.SyntaxKind = {})); var NodeFlags; (function (NodeFlags) { NodeFlags[NodeFlags["None"] = 0] = "None"; NodeFlags[NodeFlags["Let"] = 1] = "Let"; NodeFlags[NodeFlags["Const"] = 2] = "Const"; NodeFlags[NodeFlags["NestedNamespace"] = 4] = "NestedNamespace"; NodeFlags[NodeFlags["Synthesized"] = 8] = "Synthesized"; NodeFlags[NodeFlags["Namespace"] = 16] = "Namespace"; NodeFlags[NodeFlags["ExportContext"] = 32] = "ExportContext"; NodeFlags[NodeFlags["ContainsThis"] = 64] = "ContainsThis"; NodeFlags[NodeFlags["HasImplicitReturn"] = 128] = "HasImplicitReturn"; NodeFlags[NodeFlags["HasExplicitReturn"] = 256] = "HasExplicitReturn"; NodeFlags[NodeFlags["GlobalAugmentation"] = 512] = "GlobalAugmentation"; NodeFlags[NodeFlags["HasAsyncFunctions"] = 1024] = "HasAsyncFunctions"; NodeFlags[NodeFlags["DisallowInContext"] = 2048] = "DisallowInContext"; NodeFlags[NodeFlags["YieldContext"] = 4096] = "YieldContext"; NodeFlags[NodeFlags["DecoratorContext"] = 8192] = "DecoratorContext"; NodeFlags[NodeFlags["AwaitContext"] = 16384] = "AwaitContext"; NodeFlags[NodeFlags["ThisNodeHasError"] = 32768] = "ThisNodeHasError"; NodeFlags[NodeFlags["JavaScriptFile"] = 65536] = "JavaScriptFile"; NodeFlags[NodeFlags["ThisNodeOrAnySubNodesHasError"] = 131072] = "ThisNodeOrAnySubNodesHasError"; NodeFlags[NodeFlags["HasAggregatedChildData"] = 262144] = "HasAggregatedChildData"; // This flag will be set when the parser encounters a dynamic import expression so that module resolution // will not have to walk the tree if the flag is not set. However, this flag is just a approximation because // once it is set, the flag never gets cleared (hence why it's named "PossiblyContainsDynamicImport"). // During editing, if dynamic import is removed, incremental parsing will *NOT* update this flag. This means that the tree will always be traversed // during module resolution. However, the removal operation should not occur often and in the case of the // removal, it is likely that users will add the import anyway. // The advantage of this approach is its simplicity. For the case of batch compilation, // we guarantee that users won't have to pay the price of walking the tree if a dynamic import isn't used. /* @internal */ NodeFlags[NodeFlags["PossiblyContainsDynamicImport"] = 524288] = "PossiblyContainsDynamicImport"; NodeFlags[NodeFlags["JSDoc"] = 1048576] = "JSDoc"; /* @internal */ NodeFlags[NodeFlags["Ambient"] = 2097152] = "Ambient"; /* @internal */ NodeFlags[NodeFlags["InWithStatement"] = 4194304] = "InWithStatement"; NodeFlags[NodeFlags["BlockScoped"] = 3] = "BlockScoped"; NodeFlags[NodeFlags["ReachabilityCheckFlags"] = 384] = "ReachabilityCheckFlags"; NodeFlags[NodeFlags["ReachabilityAndEmitFlags"] = 1408] = "ReachabilityAndEmitFlags"; // Parsing context flags NodeFlags[NodeFlags["ContextFlags"] = 6387712] = "ContextFlags"; // Exclude these flags when parsing a Type NodeFlags[NodeFlags["TypeExcludesFlags"] = 20480] = "TypeExcludesFlags"; })(NodeFlags = ts.NodeFlags || (ts.NodeFlags = {})); var ModifierFlags; (function (ModifierFlags) { ModifierFlags[ModifierFlags["None"] = 0] = "None"; ModifierFlags[ModifierFlags["Export"] = 1] = "Export"; ModifierFlags[ModifierFlags["Ambient"] = 2] = "Ambient"; ModifierFlags[ModifierFlags["Public"] = 4] = "Public"; ModifierFlags[ModifierFlags["Private"] = 8] = "Private"; ModifierFlags[ModifierFlags["Protected"] = 16] = "Protected"; ModifierFlags[ModifierFlags["Static"] = 32] = "Static"; ModifierFlags[ModifierFlags["Readonly"] = 64] = "Readonly"; ModifierFlags[ModifierFlags["Abstract"] = 128] = "Abstract"; ModifierFlags[ModifierFlags["Async"] = 256] = "Async"; ModifierFlags[ModifierFlags["Default"] = 512] = "Default"; ModifierFlags[ModifierFlags["Const"] = 2048] = "Const"; ModifierFlags[ModifierFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags"; ModifierFlags[ModifierFlags["AccessibilityModifier"] = 28] = "AccessibilityModifier"; // Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property. ModifierFlags[ModifierFlags["ParameterPropertyModifier"] = 92] = "ParameterPropertyModifier"; ModifierFlags[ModifierFlags["NonPublicAccessibilityModifier"] = 24] = "NonPublicAccessibilityModifier"; ModifierFlags[ModifierFlags["TypeScriptModifier"] = 2270] = "TypeScriptModifier"; ModifierFlags[ModifierFlags["ExportDefault"] = 513] = "ExportDefault"; })(ModifierFlags = ts.ModifierFlags || (ts.ModifierFlags = {})); var JsxFlags; (function (JsxFlags) { JsxFlags[JsxFlags["None"] = 0] = "None"; /** An element from a named property of the JSX.IntrinsicElements interface */ JsxFlags[JsxFlags["IntrinsicNamedElement"] = 1] = "IntrinsicNamedElement"; /** An element inferred from the string index signature of the JSX.IntrinsicElements interface */ JsxFlags[JsxFlags["IntrinsicIndexedElement"] = 2] = "IntrinsicIndexedElement"; JsxFlags[JsxFlags["IntrinsicElement"] = 3] = "IntrinsicElement"; })(JsxFlags = ts.JsxFlags || (ts.JsxFlags = {})); /* @internal */ var RelationComparisonResult; (function (RelationComparisonResult) { RelationComparisonResult[RelationComparisonResult["Succeeded"] = 1] = "Succeeded"; RelationComparisonResult[RelationComparisonResult["Failed"] = 2] = "Failed"; RelationComparisonResult[RelationComparisonResult["FailedAndReported"] = 3] = "FailedAndReported"; })(RelationComparisonResult = ts.RelationComparisonResult || (ts.RelationComparisonResult = {})); /*@internal*/ var GeneratedIdentifierKind; (function (GeneratedIdentifierKind) { GeneratedIdentifierKind[GeneratedIdentifierKind["None"] = 0] = "None"; GeneratedIdentifierKind[GeneratedIdentifierKind["Auto"] = 1] = "Auto"; GeneratedIdentifierKind[GeneratedIdentifierKind["Loop"] = 2] = "Loop"; GeneratedIdentifierKind[GeneratedIdentifierKind["Unique"] = 3] = "Unique"; GeneratedIdentifierKind[GeneratedIdentifierKind["Node"] = 4] = "Node"; })(GeneratedIdentifierKind = ts.GeneratedIdentifierKind || (ts.GeneratedIdentifierKind = {})); /* @internal */ var TokenFlags; (function (TokenFlags) { TokenFlags[TokenFlags["None"] = 0] = "None"; TokenFlags[TokenFlags["PrecedingLineBreak"] = 1] = "PrecedingLineBreak"; TokenFlags[TokenFlags["PrecedingJSDocComment"] = 2] = "PrecedingJSDocComment"; TokenFlags[TokenFlags["Unterminated"] = 4] = "Unterminated"; TokenFlags[TokenFlags["ExtendedUnicodeEscape"] = 8] = "ExtendedUnicodeEscape"; TokenFlags[TokenFlags["Scientific"] = 16] = "Scientific"; TokenFlags[TokenFlags["Octal"] = 32] = "Octal"; TokenFlags[TokenFlags["HexSpecifier"] = 64] = "HexSpecifier"; TokenFlags[TokenFlags["BinarySpecifier"] = 128] = "BinarySpecifier"; TokenFlags[TokenFlags["OctalSpecifier"] = 256] = "OctalSpecifier"; TokenFlags[TokenFlags["BinaryOrOctalSpecifier"] = 384] = "BinaryOrOctalSpecifier"; TokenFlags[TokenFlags["NumericLiteralFlags"] = 496] = "NumericLiteralFlags"; })(TokenFlags = ts.TokenFlags || (ts.TokenFlags = {})); var FlowFlags; (function (FlowFlags) { FlowFlags[FlowFlags["Unreachable"] = 1] = "Unreachable"; FlowFlags[FlowFlags["Start"] = 2] = "Start"; FlowFlags[FlowFlags["BranchLabel"] = 4] = "BranchLabel"; FlowFlags[FlowFlags["LoopLabel"] = 8] = "LoopLabel"; FlowFlags[FlowFlags["Assignment"] = 16] = "Assignment"; FlowFlags[FlowFlags["TrueCondition"] = 32] = "TrueCondition"; FlowFlags[FlowFlags["FalseCondition"] = 64] = "FalseCondition"; FlowFlags[FlowFlags["SwitchClause"] = 128] = "SwitchClause"; FlowFlags[FlowFlags["ArrayMutation"] = 256] = "ArrayMutation"; FlowFlags[FlowFlags["Referenced"] = 512] = "Referenced"; FlowFlags[FlowFlags["Shared"] = 1024] = "Shared"; FlowFlags[FlowFlags["PreFinally"] = 2048] = "PreFinally"; FlowFlags[FlowFlags["AfterFinally"] = 4096] = "AfterFinally"; FlowFlags[FlowFlags["Label"] = 12] = "Label"; FlowFlags[FlowFlags["Condition"] = 96] = "Condition"; })(FlowFlags = ts.FlowFlags || (ts.FlowFlags = {})); var OperationCanceledException = /** @class */ (function () { function OperationCanceledException() { } return OperationCanceledException; }()); ts.OperationCanceledException = OperationCanceledException; /* @internal */ var StructureIsReused; (function (StructureIsReused) { StructureIsReused[StructureIsReused["Not"] = 0] = "Not"; StructureIsReused[StructureIsReused["SafeModules"] = 1] = "SafeModules"; StructureIsReused[StructureIsReused["Completely"] = 2] = "Completely"; })(StructureIsReused = ts.StructureIsReused || (ts.StructureIsReused = {})); /** Return code used by getEmitOutput function to indicate status of the function */ var ExitStatus; (function (ExitStatus) { // Compiler ran successfully. Either this was a simple do-nothing compilation (for example, // when -version or -help was provided, or this was a normal compilation, no diagnostics // were produced, and all outputs were generated successfully. ExitStatus[ExitStatus["Success"] = 0] = "Success"; // Diagnostics were produced and because of them no code was generated. ExitStatus[ExitStatus["DiagnosticsPresent_OutputsSkipped"] = 1] = "DiagnosticsPresent_OutputsSkipped"; // Diagnostics were produced and outputs were generated in spite of them. ExitStatus[ExitStatus["DiagnosticsPresent_OutputsGenerated"] = 2] = "DiagnosticsPresent_OutputsGenerated"; })(ExitStatus = ts.ExitStatus || (ts.ExitStatus = {})); var NodeBuilderFlags; (function (NodeBuilderFlags) { NodeBuilderFlags[NodeBuilderFlags["None"] = 0] = "None"; // Options NodeBuilderFlags[NodeBuilderFlags["NoTruncation"] = 1] = "NoTruncation"; NodeBuilderFlags[NodeBuilderFlags["WriteArrayAsGenericType"] = 2] = "WriteArrayAsGenericType"; NodeBuilderFlags[NodeBuilderFlags["WriteTypeArgumentsOfSignature"] = 32] = "WriteTypeArgumentsOfSignature"; NodeBuilderFlags[NodeBuilderFlags["UseFullyQualifiedType"] = 64] = "UseFullyQualifiedType"; NodeBuilderFlags[NodeBuilderFlags["SuppressAnyReturnType"] = 256] = "SuppressAnyReturnType"; NodeBuilderFlags[NodeBuilderFlags["WriteTypeParametersInQualifiedName"] = 512] = "WriteTypeParametersInQualifiedName"; // Error handling NodeBuilderFlags[NodeBuilderFlags["AllowThisInObjectLiteral"] = 1024] = "AllowThisInObjectLiteral"; NodeBuilderFlags[NodeBuilderFlags["AllowQualifedNameInPlaceOfIdentifier"] = 2048] = "AllowQualifedNameInPlaceOfIdentifier"; NodeBuilderFlags[NodeBuilderFlags["AllowAnonymousIdentifier"] = 8192] = "AllowAnonymousIdentifier"; NodeBuilderFlags[NodeBuilderFlags["AllowEmptyUnionOrIntersection"] = 16384] = "AllowEmptyUnionOrIntersection"; NodeBuilderFlags[NodeBuilderFlags["AllowEmptyTuple"] = 32768] = "AllowEmptyTuple"; NodeBuilderFlags[NodeBuilderFlags["IgnoreErrors"] = 60416] = "IgnoreErrors"; // State NodeBuilderFlags[NodeBuilderFlags["InObjectTypeLiteral"] = 1048576] = "InObjectTypeLiteral"; NodeBuilderFlags[NodeBuilderFlags["InTypeAlias"] = 8388608] = "InTypeAlias"; })(NodeBuilderFlags = ts.NodeBuilderFlags || (ts.NodeBuilderFlags = {})); var TypeFormatFlags; (function (TypeFormatFlags) { TypeFormatFlags[TypeFormatFlags["None"] = 0] = "None"; TypeFormatFlags[TypeFormatFlags["WriteArrayAsGenericType"] = 1] = "WriteArrayAsGenericType"; TypeFormatFlags[TypeFormatFlags["UseTypeOfFunction"] = 4] = "UseTypeOfFunction"; TypeFormatFlags[TypeFormatFlags["NoTruncation"] = 8] = "NoTruncation"; TypeFormatFlags[TypeFormatFlags["WriteArrowStyleSignature"] = 16] = "WriteArrowStyleSignature"; TypeFormatFlags[TypeFormatFlags["WriteOwnNameForAnyLike"] = 32] = "WriteOwnNameForAnyLike"; TypeFormatFlags[TypeFormatFlags["WriteTypeArgumentsOfSignature"] = 64] = "WriteTypeArgumentsOfSignature"; TypeFormatFlags[TypeFormatFlags["InElementType"] = 128] = "InElementType"; TypeFormatFlags[TypeFormatFlags["UseFullyQualifiedType"] = 256] = "UseFullyQualifiedType"; TypeFormatFlags[TypeFormatFlags["InFirstTypeArgument"] = 512] = "InFirstTypeArgument"; TypeFormatFlags[TypeFormatFlags["InTypeAlias"] = 1024] = "InTypeAlias"; TypeFormatFlags[TypeFormatFlags["SuppressAnyReturnType"] = 4096] = "SuppressAnyReturnType"; TypeFormatFlags[TypeFormatFlags["AddUndefined"] = 8192] = "AddUndefined"; TypeFormatFlags[TypeFormatFlags["WriteClassExpressionAsTypeLiteral"] = 16384] = "WriteClassExpressionAsTypeLiteral"; TypeFormatFlags[TypeFormatFlags["InArrayType"] = 32768] = "InArrayType"; TypeFormatFlags[TypeFormatFlags["UseAliasDefinedOutsideCurrentScope"] = 65536] = "UseAliasDefinedOutsideCurrentScope"; // even though `T` can't be accessed in the current scope. TypeFormatFlags[TypeFormatFlags["AllowUniqueESSymbolType"] = 131072] = "AllowUniqueESSymbolType"; })(TypeFormatFlags = ts.TypeFormatFlags || (ts.TypeFormatFlags = {})); var SymbolFormatFlags; (function (SymbolFormatFlags) { SymbolFormatFlags[SymbolFormatFlags["None"] = 0] = "None"; // Write symbols's type argument if it is instantiated symbol // eg. class C { p: T } <-- Show p as C.p here // var a: C; // var p = a.p; <--- Here p is property of C so show it as C.p instead of just C.p SymbolFormatFlags[SymbolFormatFlags["WriteTypeParametersOrArguments"] = 1] = "WriteTypeParametersOrArguments"; // Use only external alias information to get the symbol name in the given context // eg. module m { export class c { } } import x = m.c; // When this flag is specified m.c will be used to refer to the class instead of alias symbol x SymbolFormatFlags[SymbolFormatFlags["UseOnlyExternalAliasing"] = 2] = "UseOnlyExternalAliasing"; })(SymbolFormatFlags = ts.SymbolFormatFlags || (ts.SymbolFormatFlags = {})); /* @internal */ var SymbolAccessibility; (function (SymbolAccessibility) { SymbolAccessibility[SymbolAccessibility["Accessible"] = 0] = "Accessible"; SymbolAccessibility[SymbolAccessibility["NotAccessible"] = 1] = "NotAccessible"; SymbolAccessibility[SymbolAccessibility["CannotBeNamed"] = 2] = "CannotBeNamed"; })(SymbolAccessibility = ts.SymbolAccessibility || (ts.SymbolAccessibility = {})); /* @internal */ var SyntheticSymbolKind; (function (SyntheticSymbolKind) { SyntheticSymbolKind[SyntheticSymbolKind["UnionOrIntersection"] = 0] = "UnionOrIntersection"; SyntheticSymbolKind[SyntheticSymbolKind["Spread"] = 1] = "Spread"; })(SyntheticSymbolKind = ts.SyntheticSymbolKind || (ts.SyntheticSymbolKind = {})); var TypePredicateKind; (function (TypePredicateKind) { TypePredicateKind[TypePredicateKind["This"] = 0] = "This"; TypePredicateKind[TypePredicateKind["Identifier"] = 1] = "Identifier"; })(TypePredicateKind = ts.TypePredicateKind || (ts.TypePredicateKind = {})); /** Indicates how to serialize the name for a TypeReferenceNode when emitting decorator metadata */ /* @internal */ var TypeReferenceSerializationKind; (function (TypeReferenceSerializationKind) { TypeReferenceSerializationKind[TypeReferenceSerializationKind["Unknown"] = 0] = "Unknown"; // should be emitted using a safe fallback. TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithConstructSignatureAndValue"] = 1] = "TypeWithConstructSignatureAndValue"; // function that can be reached at runtime (e.g. a `class` // declaration or a `var` declaration for the static side // of a type, such as the global `Promise` type in lib.d.ts). TypeReferenceSerializationKind[TypeReferenceSerializationKind["VoidNullableOrNeverType"] = 2] = "VoidNullableOrNeverType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["NumberLikeType"] = 3] = "NumberLikeType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["StringLikeType"] = 4] = "StringLikeType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["BooleanType"] = 5] = "BooleanType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["ArrayLikeType"] = 6] = "ArrayLikeType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["ESSymbolType"] = 7] = "ESSymbolType"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["Promise"] = 8] = "Promise"; TypeReferenceSerializationKind[TypeReferenceSerializationKind["TypeWithCallSignature"] = 9] = "TypeWithCallSignature"; // with call signatures. TypeReferenceSerializationKind[TypeReferenceSerializationKind["ObjectType"] = 10] = "ObjectType"; })(TypeReferenceSerializationKind = ts.TypeReferenceSerializationKind || (ts.TypeReferenceSerializationKind = {})); var SymbolFlags; (function (SymbolFlags) { SymbolFlags[SymbolFlags["None"] = 0] = "None"; SymbolFlags[SymbolFlags["FunctionScopedVariable"] = 1] = "FunctionScopedVariable"; SymbolFlags[SymbolFlags["BlockScopedVariable"] = 2] = "BlockScopedVariable"; SymbolFlags[SymbolFlags["Property"] = 4] = "Property"; SymbolFlags[SymbolFlags["EnumMember"] = 8] = "EnumMember"; SymbolFlags[SymbolFlags["Function"] = 16] = "Function"; SymbolFlags[SymbolFlags["Class"] = 32] = "Class"; SymbolFlags[SymbolFlags["Interface"] = 64] = "Interface"; SymbolFlags[SymbolFlags["ConstEnum"] = 128] = "ConstEnum"; SymbolFlags[SymbolFlags["RegularEnum"] = 256] = "RegularEnum"; SymbolFlags[SymbolFlags["ValueModule"] = 512] = "ValueModule"; SymbolFlags[SymbolFlags["NamespaceModule"] = 1024] = "NamespaceModule"; SymbolFlags[SymbolFlags["TypeLiteral"] = 2048] = "TypeLiteral"; SymbolFlags[SymbolFlags["ObjectLiteral"] = 4096] = "ObjectLiteral"; SymbolFlags[SymbolFlags["Method"] = 8192] = "Method"; SymbolFlags[SymbolFlags["Constructor"] = 16384] = "Constructor"; SymbolFlags[SymbolFlags["GetAccessor"] = 32768] = "GetAccessor"; SymbolFlags[SymbolFlags["SetAccessor"] = 65536] = "SetAccessor"; SymbolFlags[SymbolFlags["Signature"] = 131072] = "Signature"; SymbolFlags[SymbolFlags["TypeParameter"] = 262144] = "TypeParameter"; SymbolFlags[SymbolFlags["TypeAlias"] = 524288] = "TypeAlias"; SymbolFlags[SymbolFlags["ExportValue"] = 1048576] = "ExportValue"; SymbolFlags[SymbolFlags["Alias"] = 2097152] = "Alias"; SymbolFlags[SymbolFlags["Prototype"] = 4194304] = "Prototype"; SymbolFlags[SymbolFlags["ExportStar"] = 8388608] = "ExportStar"; SymbolFlags[SymbolFlags["Optional"] = 16777216] = "Optional"; SymbolFlags[SymbolFlags["Transient"] = 33554432] = "Transient"; SymbolFlags[SymbolFlags["JSContainer"] = 67108864] = "JSContainer"; /* @internal */ SymbolFlags[SymbolFlags["All"] = 67108863] = "All"; SymbolFlags[SymbolFlags["Enum"] = 384] = "Enum"; SymbolFlags[SymbolFlags["Variable"] = 3] = "Variable"; SymbolFlags[SymbolFlags["Value"] = 107455] = "Value"; SymbolFlags[SymbolFlags["Type"] = 793064] = "Type"; SymbolFlags[SymbolFlags["Namespace"] = 1920] = "Namespace"; SymbolFlags[SymbolFlags["Module"] = 1536] = "Module"; SymbolFlags[SymbolFlags["Accessor"] = 98304] = "Accessor"; // Variables can be redeclared, but can not redeclare a block-scoped declaration with the // same name, or any other value that is not a variable, e.g. ValueModule or Class SymbolFlags[SymbolFlags["FunctionScopedVariableExcludes"] = 107454] = "FunctionScopedVariableExcludes"; // Block-scoped declarations are not allowed to be re-declared // they can not merge with anything in the value space SymbolFlags[SymbolFlags["BlockScopedVariableExcludes"] = 107455] = "BlockScopedVariableExcludes"; SymbolFlags[SymbolFlags["ParameterExcludes"] = 107455] = "ParameterExcludes"; SymbolFlags[SymbolFlags["PropertyExcludes"] = 0] = "PropertyExcludes"; SymbolFlags[SymbolFlags["EnumMemberExcludes"] = 900095] = "EnumMemberExcludes"; SymbolFlags[SymbolFlags["FunctionExcludes"] = 106927] = "FunctionExcludes"; SymbolFlags[SymbolFlags["ClassExcludes"] = 899519] = "ClassExcludes"; SymbolFlags[SymbolFlags["InterfaceExcludes"] = 792968] = "InterfaceExcludes"; SymbolFlags[SymbolFlags["RegularEnumExcludes"] = 899327] = "RegularEnumExcludes"; SymbolFlags[SymbolFlags["ConstEnumExcludes"] = 899967] = "ConstEnumExcludes"; SymbolFlags[SymbolFlags["ValueModuleExcludes"] = 106639] = "ValueModuleExcludes"; SymbolFlags[SymbolFlags["NamespaceModuleExcludes"] = 0] = "NamespaceModuleExcludes"; SymbolFlags[SymbolFlags["MethodExcludes"] = 99263] = "MethodExcludes"; SymbolFlags[SymbolFlags["GetAccessorExcludes"] = 41919] = "GetAccessorExcludes"; SymbolFlags[SymbolFlags["SetAccessorExcludes"] = 74687] = "SetAccessorExcludes"; SymbolFlags[SymbolFlags["TypeParameterExcludes"] = 530920] = "TypeParameterExcludes"; SymbolFlags[SymbolFlags["TypeAliasExcludes"] = 793064] = "TypeAliasExcludes"; SymbolFlags[SymbolFlags["AliasExcludes"] = 2097152] = "AliasExcludes"; SymbolFlags[SymbolFlags["ModuleMember"] = 2623475] = "ModuleMember"; SymbolFlags[SymbolFlags["ExportHasLocal"] = 944] = "ExportHasLocal"; SymbolFlags[SymbolFlags["HasExports"] = 1952] = "HasExports"; SymbolFlags[SymbolFlags["HasMembers"] = 6240] = "HasMembers"; SymbolFlags[SymbolFlags["BlockScoped"] = 418] = "BlockScoped"; SymbolFlags[SymbolFlags["PropertyOrAccessor"] = 98308] = "PropertyOrAccessor"; SymbolFlags[SymbolFlags["ClassMember"] = 106500] = "ClassMember"; /* @internal */ // The set of things we consider semantically classifiable. Used to speed up the LS during // classification. SymbolFlags[SymbolFlags["Classifiable"] = 2885600] = "Classifiable"; /* @internal */ SymbolFlags[SymbolFlags["LateBindingContainer"] = 6240] = "LateBindingContainer"; })(SymbolFlags = ts.SymbolFlags || (ts.SymbolFlags = {})); /* @internal */ var EnumKind; (function (EnumKind) { EnumKind[EnumKind["Numeric"] = 0] = "Numeric"; EnumKind[EnumKind["Literal"] = 1] = "Literal"; // Literal enum (each member has a TypeFlags.EnumLiteral type) })(EnumKind = ts.EnumKind || (ts.EnumKind = {})); /* @internal */ var CheckFlags; (function (CheckFlags) { CheckFlags[CheckFlags["Instantiated"] = 1] = "Instantiated"; CheckFlags[CheckFlags["SyntheticProperty"] = 2] = "SyntheticProperty"; CheckFlags[CheckFlags["SyntheticMethod"] = 4] = "SyntheticMethod"; CheckFlags[CheckFlags["Readonly"] = 8] = "Readonly"; CheckFlags[CheckFlags["Partial"] = 16] = "Partial"; CheckFlags[CheckFlags["HasNonUniformType"] = 32] = "HasNonUniformType"; CheckFlags[CheckFlags["ContainsPublic"] = 64] = "ContainsPublic"; CheckFlags[CheckFlags["ContainsProtected"] = 128] = "ContainsProtected"; CheckFlags[CheckFlags["ContainsPrivate"] = 256] = "ContainsPrivate"; CheckFlags[CheckFlags["ContainsStatic"] = 512] = "ContainsStatic"; CheckFlags[CheckFlags["Late"] = 1024] = "Late"; CheckFlags[CheckFlags["Synthetic"] = 6] = "Synthetic"; })(CheckFlags = ts.CheckFlags || (ts.CheckFlags = {})); var InternalSymbolName; (function (InternalSymbolName) { InternalSymbolName["Call"] = "__call"; InternalSymbolName["Constructor"] = "__constructor"; InternalSymbolName["New"] = "__new"; InternalSymbolName["Index"] = "__index"; InternalSymbolName["ExportStar"] = "__export"; InternalSymbolName["Global"] = "__global"; InternalSymbolName["Missing"] = "__missing"; InternalSymbolName["Type"] = "__type"; InternalSymbolName["Object"] = "__object"; InternalSymbolName["JSXAttributes"] = "__jsxAttributes"; InternalSymbolName["Class"] = "__class"; InternalSymbolName["Function"] = "__function"; InternalSymbolName["Computed"] = "__computed"; InternalSymbolName["Resolving"] = "__resolving__"; InternalSymbolName["ExportEquals"] = "export="; InternalSymbolName["Default"] = "default"; })(InternalSymbolName = ts.InternalSymbolName || (ts.InternalSymbolName = {})); /* @internal */ var NodeCheckFlags; (function (NodeCheckFlags) { NodeCheckFlags[NodeCheckFlags["TypeChecked"] = 1] = "TypeChecked"; NodeCheckFlags[NodeCheckFlags["LexicalThis"] = 2] = "LexicalThis"; NodeCheckFlags[NodeCheckFlags["CaptureThis"] = 4] = "CaptureThis"; NodeCheckFlags[NodeCheckFlags["CaptureNewTarget"] = 8] = "CaptureNewTarget"; NodeCheckFlags[NodeCheckFlags["SuperInstance"] = 256] = "SuperInstance"; NodeCheckFlags[NodeCheckFlags["SuperStatic"] = 512] = "SuperStatic"; NodeCheckFlags[NodeCheckFlags["ContextChecked"] = 1024] = "ContextChecked"; NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuper"] = 2048] = "AsyncMethodWithSuper"; NodeCheckFlags[NodeCheckFlags["AsyncMethodWithSuperBinding"] = 4096] = "AsyncMethodWithSuperBinding"; NodeCheckFlags[NodeCheckFlags["CaptureArguments"] = 8192] = "CaptureArguments"; NodeCheckFlags[NodeCheckFlags["EnumValuesComputed"] = 16384] = "EnumValuesComputed"; NodeCheckFlags[NodeCheckFlags["LexicalModuleMergesWithClass"] = 32768] = "LexicalModuleMergesWithClass"; NodeCheckFlags[NodeCheckFlags["LoopWithCapturedBlockScopedBinding"] = 65536] = "LoopWithCapturedBlockScopedBinding"; NodeCheckFlags[NodeCheckFlags["CapturedBlockScopedBinding"] = 131072] = "CapturedBlockScopedBinding"; NodeCheckFlags[NodeCheckFlags["BlockScopedBindingInLoop"] = 262144] = "BlockScopedBindingInLoop"; NodeCheckFlags[NodeCheckFlags["ClassWithBodyScopedClassBinding"] = 524288] = "ClassWithBodyScopedClassBinding"; NodeCheckFlags[NodeCheckFlags["BodyScopedClassBinding"] = 1048576] = "BodyScopedClassBinding"; NodeCheckFlags[NodeCheckFlags["NeedsLoopOutParameter"] = 2097152] = "NeedsLoopOutParameter"; NodeCheckFlags[NodeCheckFlags["AssignmentsMarked"] = 4194304] = "AssignmentsMarked"; NodeCheckFlags[NodeCheckFlags["ClassWithConstructorReference"] = 8388608] = "ClassWithConstructorReference"; NodeCheckFlags[NodeCheckFlags["ConstructorReferenceInClass"] = 16777216] = "ConstructorReferenceInClass"; })(NodeCheckFlags = ts.NodeCheckFlags || (ts.NodeCheckFlags = {})); var TypeFlags; (function (TypeFlags) { TypeFlags[TypeFlags["Any"] = 1] = "Any"; TypeFlags[TypeFlags["String"] = 2] = "String"; TypeFlags[TypeFlags["Number"] = 4] = "Number"; TypeFlags[TypeFlags["Boolean"] = 8] = "Boolean"; TypeFlags[TypeFlags["Enum"] = 16] = "Enum"; TypeFlags[TypeFlags["StringLiteral"] = 32] = "StringLiteral"; TypeFlags[TypeFlags["NumberLiteral"] = 64] = "NumberLiteral"; TypeFlags[TypeFlags["BooleanLiteral"] = 128] = "BooleanLiteral"; TypeFlags[TypeFlags["EnumLiteral"] = 256] = "EnumLiteral"; TypeFlags[TypeFlags["ESSymbol"] = 512] = "ESSymbol"; TypeFlags[TypeFlags["UniqueESSymbol"] = 1024] = "UniqueESSymbol"; TypeFlags[TypeFlags["Void"] = 2048] = "Void"; TypeFlags[TypeFlags["Undefined"] = 4096] = "Undefined"; TypeFlags[TypeFlags["Null"] = 8192] = "Null"; TypeFlags[TypeFlags["Never"] = 16384] = "Never"; TypeFlags[TypeFlags["TypeParameter"] = 32768] = "TypeParameter"; TypeFlags[TypeFlags["Object"] = 65536] = "Object"; TypeFlags[TypeFlags["Union"] = 131072] = "Union"; TypeFlags[TypeFlags["Intersection"] = 262144] = "Intersection"; TypeFlags[TypeFlags["Index"] = 524288] = "Index"; TypeFlags[TypeFlags["IndexedAccess"] = 1048576] = "IndexedAccess"; /* @internal */ TypeFlags[TypeFlags["FreshLiteral"] = 2097152] = "FreshLiteral"; /* @internal */ TypeFlags[TypeFlags["ContainsWideningType"] = 4194304] = "ContainsWideningType"; /* @internal */ TypeFlags[TypeFlags["ContainsObjectLiteral"] = 8388608] = "ContainsObjectLiteral"; /* @internal */ TypeFlags[TypeFlags["ContainsAnyFunctionType"] = 16777216] = "ContainsAnyFunctionType"; TypeFlags[TypeFlags["NonPrimitive"] = 33554432] = "NonPrimitive"; /* @internal */ TypeFlags[TypeFlags["JsxAttributes"] = 67108864] = "JsxAttributes"; TypeFlags[TypeFlags["MarkerType"] = 134217728] = "MarkerType"; /* @internal */ TypeFlags[TypeFlags["Nullable"] = 12288] = "Nullable"; TypeFlags[TypeFlags["Literal"] = 224] = "Literal"; TypeFlags[TypeFlags["Unit"] = 13536] = "Unit"; TypeFlags[TypeFlags["StringOrNumberLiteral"] = 96] = "StringOrNumberLiteral"; /* @internal */ TypeFlags[TypeFlags["StringOrNumberLiteralOrUnique"] = 1120] = "StringOrNumberLiteralOrUnique"; /* @internal */ TypeFlags[TypeFlags["DefinitelyFalsy"] = 14560] = "DefinitelyFalsy"; TypeFlags[TypeFlags["PossiblyFalsy"] = 14574] = "PossiblyFalsy"; /* @internal */ TypeFlags[TypeFlags["Intrinsic"] = 33585807] = "Intrinsic"; /* @internal */ TypeFlags[TypeFlags["Primitive"] = 16382] = "Primitive"; TypeFlags[TypeFlags["StringLike"] = 524322] = "StringLike"; TypeFlags[TypeFlags["NumberLike"] = 84] = "NumberLike"; TypeFlags[TypeFlags["BooleanLike"] = 136] = "BooleanLike"; TypeFlags[TypeFlags["EnumLike"] = 272] = "EnumLike"; TypeFlags[TypeFlags["ESSymbolLike"] = 1536] = "ESSymbolLike"; TypeFlags[TypeFlags["UnionOrIntersection"] = 393216] = "UnionOrIntersection"; TypeFlags[TypeFlags["StructuredType"] = 458752] = "StructuredType"; TypeFlags[TypeFlags["StructuredOrTypeVariable"] = 2064384] = "StructuredOrTypeVariable"; TypeFlags[TypeFlags["TypeVariable"] = 1081344] = "TypeVariable"; // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never TypeFlags[TypeFlags["Narrowable"] = 35620607] = "Narrowable"; TypeFlags[TypeFlags["NotUnionOrUnit"] = 33620481] = "NotUnionOrUnit"; /* @internal */ TypeFlags[TypeFlags["RequiresWidening"] = 12582912] = "RequiresWidening"; /* @internal */ TypeFlags[TypeFlags["PropagatingFlags"] = 29360128] = "PropagatingFlags"; })(TypeFlags = ts.TypeFlags || (ts.TypeFlags = {})); var ObjectFlags; (function (ObjectFlags) { ObjectFlags[ObjectFlags["Class"] = 1] = "Class"; ObjectFlags[ObjectFlags["Interface"] = 2] = "Interface"; ObjectFlags[ObjectFlags["Reference"] = 4] = "Reference"; ObjectFlags[ObjectFlags["Tuple"] = 8] = "Tuple"; ObjectFlags[ObjectFlags["Anonymous"] = 16] = "Anonymous"; ObjectFlags[ObjectFlags["Mapped"] = 32] = "Mapped"; ObjectFlags[ObjectFlags["Instantiated"] = 64] = "Instantiated"; ObjectFlags[ObjectFlags["ObjectLiteral"] = 128] = "ObjectLiteral"; ObjectFlags[ObjectFlags["EvolvingArray"] = 256] = "EvolvingArray"; ObjectFlags[ObjectFlags["ObjectLiteralPatternWithComputedProperties"] = 512] = "ObjectLiteralPatternWithComputedProperties"; ObjectFlags[ObjectFlags["ContainsSpread"] = 1024] = "ContainsSpread"; ObjectFlags[ObjectFlags["ClassOrInterface"] = 3] = "ClassOrInterface"; })(ObjectFlags = ts.ObjectFlags || (ts.ObjectFlags = {})); /* @internal */ var Variance; (function (Variance) { Variance[Variance["Invariant"] = 0] = "Invariant"; Variance[Variance["Covariant"] = 1] = "Covariant"; Variance[Variance["Contravariant"] = 2] = "Contravariant"; Variance[Variance["Bivariant"] = 3] = "Bivariant"; Variance[Variance["Independent"] = 4] = "Independent"; })(Variance = ts.Variance || (ts.Variance = {})); var SignatureKind; (function (SignatureKind) { SignatureKind[SignatureKind["Call"] = 0] = "Call"; SignatureKind[SignatureKind["Construct"] = 1] = "Construct"; })(SignatureKind = ts.SignatureKind || (ts.SignatureKind = {})); var IndexKind; (function (IndexKind) { IndexKind[IndexKind["String"] = 0] = "String"; IndexKind[IndexKind["Number"] = 1] = "Number"; })(IndexKind = ts.IndexKind || (ts.IndexKind = {})); var InferencePriority; (function (InferencePriority) { InferencePriority[InferencePriority["Contravariant"] = 1] = "Contravariant"; InferencePriority[InferencePriority["NakedTypeVariable"] = 2] = "NakedTypeVariable"; InferencePriority[InferencePriority["MappedType"] = 4] = "MappedType"; InferencePriority[InferencePriority["ReturnType"] = 8] = "ReturnType"; InferencePriority[InferencePriority["NeverType"] = 16] = "NeverType"; })(InferencePriority = ts.InferencePriority || (ts.InferencePriority = {})); var InferenceFlags; (function (InferenceFlags) { InferenceFlags[InferenceFlags["InferUnionTypes"] = 1] = "InferUnionTypes"; InferenceFlags[InferenceFlags["NoDefault"] = 2] = "NoDefault"; InferenceFlags[InferenceFlags["AnyDefault"] = 4] = "AnyDefault"; })(InferenceFlags = ts.InferenceFlags || (ts.InferenceFlags = {})); /** * Ternary values are defined such that * x & y is False if either x or y is False. * x & y is Maybe if either x or y is Maybe, but neither x or y is False. * x & y is True if both x and y are True. * x | y is False if both x and y are False. * x | y is Maybe if either x or y is Maybe, but neither x or y is True. * x | y is True if either x or y is True. */ var Ternary; (function (Ternary) { Ternary[Ternary["False"] = 0] = "False"; Ternary[Ternary["Maybe"] = 1] = "Maybe"; Ternary[Ternary["True"] = -1] = "True"; })(Ternary = ts.Ternary || (ts.Ternary = {})); /* @internal */ var SpecialPropertyAssignmentKind; (function (SpecialPropertyAssignmentKind) { SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["None"] = 0] = "None"; /// exports.name = expr SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ExportsProperty"] = 1] = "ExportsProperty"; /// module.exports = expr SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ModuleExports"] = 2] = "ModuleExports"; /// className.prototype.name = expr SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["PrototypeProperty"] = 3] = "PrototypeProperty"; /// this.name = expr SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["ThisProperty"] = 4] = "ThisProperty"; // F.name = expr SpecialPropertyAssignmentKind[SpecialPropertyAssignmentKind["Property"] = 5] = "Property"; })(SpecialPropertyAssignmentKind = ts.SpecialPropertyAssignmentKind || (ts.SpecialPropertyAssignmentKind = {})); var DiagnosticCategory; (function (DiagnosticCategory) { DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning"; DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error"; DiagnosticCategory[DiagnosticCategory["Message"] = 2] = "Message"; })(DiagnosticCategory = ts.DiagnosticCategory || (ts.DiagnosticCategory = {})); var ModuleResolutionKind; (function (ModuleResolutionKind) { ModuleResolutionKind[ModuleResolutionKind["Classic"] = 1] = "Classic"; ModuleResolutionKind[ModuleResolutionKind["NodeJs"] = 2] = "NodeJs"; })(ModuleResolutionKind = ts.ModuleResolutionKind || (ts.ModuleResolutionKind = {})); var ModuleKind; (function (ModuleKind) { ModuleKind[ModuleKind["None"] = 0] = "None"; ModuleKind[ModuleKind["CommonJS"] = 1] = "CommonJS"; ModuleKind[ModuleKind["AMD"] = 2] = "AMD"; ModuleKind[ModuleKind["UMD"] = 3] = "UMD"; ModuleKind[ModuleKind["System"] = 4] = "System"; ModuleKind[ModuleKind["ES2015"] = 5] = "ES2015"; ModuleKind[ModuleKind["ESNext"] = 6] = "ESNext"; })(ModuleKind = ts.ModuleKind || (ts.ModuleKind = {})); var JsxEmit; (function (JsxEmit) { JsxEmit[JsxEmit["None"] = 0] = "None"; JsxEmit[JsxEmit["Preserve"] = 1] = "Preserve"; JsxEmit[JsxEmit["React"] = 2] = "React"; JsxEmit[JsxEmit["ReactNative"] = 3] = "ReactNative"; })(JsxEmit = ts.JsxEmit || (ts.JsxEmit = {})); var NewLineKind; (function (NewLineKind) { NewLineKind[NewLineKind["CarriageReturnLineFeed"] = 0] = "CarriageReturnLineFeed"; NewLineKind[NewLineKind["LineFeed"] = 1] = "LineFeed"; })(NewLineKind = ts.NewLineKind || (ts.NewLineKind = {})); var ScriptKind; (function (ScriptKind) { ScriptKind[ScriptKind["Unknown"] = 0] = "Unknown"; ScriptKind[ScriptKind["JS"] = 1] = "JS"; ScriptKind[ScriptKind["JSX"] = 2] = "JSX"; ScriptKind[ScriptKind["TS"] = 3] = "TS"; ScriptKind[ScriptKind["TSX"] = 4] = "TSX"; ScriptKind[ScriptKind["External"] = 5] = "External"; ScriptKind[ScriptKind["JSON"] = 6] = "JSON"; })(ScriptKind = ts.ScriptKind || (ts.ScriptKind = {})); var ScriptTarget; (function (ScriptTarget) { ScriptTarget[ScriptTarget["ES3"] = 0] = "ES3"; ScriptTarget[ScriptTarget["ES5"] = 1] = "ES5"; ScriptTarget[ScriptTarget["ES2015"] = 2] = "ES2015"; ScriptTarget[ScriptTarget["ES2016"] = 3] = "ES2016"; ScriptTarget[ScriptTarget["ES2017"] = 4] = "ES2017"; ScriptTarget[ScriptTarget["ES2018"] = 5] = "ES2018"; ScriptTarget[ScriptTarget["ESNext"] = 6] = "ESNext"; ScriptTarget[ScriptTarget["Latest"] = 6] = "Latest"; })(ScriptTarget = ts.ScriptTarget || (ts.ScriptTarget = {})); var LanguageVariant; (function (LanguageVariant) { LanguageVariant[LanguageVariant["Standard"] = 0] = "Standard"; LanguageVariant[LanguageVariant["JSX"] = 1] = "JSX"; })(LanguageVariant = ts.LanguageVariant || (ts.LanguageVariant = {})); /* @internal */ var DiagnosticStyle; (function (DiagnosticStyle) { DiagnosticStyle[DiagnosticStyle["Simple"] = 0] = "Simple"; DiagnosticStyle[DiagnosticStyle["Pretty"] = 1] = "Pretty"; })(DiagnosticStyle = ts.DiagnosticStyle || (ts.DiagnosticStyle = {})); var WatchDirectoryFlags; (function (WatchDirectoryFlags) { WatchDirectoryFlags[WatchDirectoryFlags["None"] = 0] = "None"; WatchDirectoryFlags[WatchDirectoryFlags["Recursive"] = 1] = "Recursive"; })(WatchDirectoryFlags = ts.WatchDirectoryFlags || (ts.WatchDirectoryFlags = {})); /* @internal */ var CharacterCodes; (function (CharacterCodes) { CharacterCodes[CharacterCodes["nullCharacter"] = 0] = "nullCharacter"; CharacterCodes[CharacterCodes["maxAsciiCharacter"] = 127] = "maxAsciiCharacter"; CharacterCodes[CharacterCodes["lineFeed"] = 10] = "lineFeed"; CharacterCodes[CharacterCodes["carriageReturn"] = 13] = "carriageReturn"; CharacterCodes[CharacterCodes["lineSeparator"] = 8232] = "lineSeparator"; CharacterCodes[CharacterCodes["paragraphSeparator"] = 8233] = "paragraphSeparator"; CharacterCodes[CharacterCodes["nextLine"] = 133] = "nextLine"; // Unicode 3.0 space characters CharacterCodes[CharacterCodes["space"] = 32] = "space"; CharacterCodes[CharacterCodes["nonBreakingSpace"] = 160] = "nonBreakingSpace"; CharacterCodes[CharacterCodes["enQuad"] = 8192] = "enQuad"; CharacterCodes[CharacterCodes["emQuad"] = 8193] = "emQuad"; CharacterCodes[CharacterCodes["enSpace"] = 8194] = "enSpace"; CharacterCodes[CharacterCodes["emSpace"] = 8195] = "emSpace"; CharacterCodes[CharacterCodes["threePerEmSpace"] = 8196] = "threePerEmSpace"; CharacterCodes[CharacterCodes["fourPerEmSpace"] = 8197] = "fourPerEmSpace"; CharacterCodes[CharacterCodes["sixPerEmSpace"] = 8198] = "sixPerEmSpace"; CharacterCodes[CharacterCodes["figureSpace"] = 8199] = "figureSpace"; CharacterCodes[CharacterCodes["punctuationSpace"] = 8200] = "punctuationSpace"; CharacterCodes[CharacterCodes["thinSpace"] = 8201] = "thinSpace"; CharacterCodes[CharacterCodes["hairSpace"] = 8202] = "hairSpace"; CharacterCodes[CharacterCodes["zeroWidthSpace"] = 8203] = "zeroWidthSpace"; CharacterCodes[CharacterCodes["narrowNoBreakSpace"] = 8239] = "narrowNoBreakSpace"; CharacterCodes[CharacterCodes["ideographicSpace"] = 12288] = "ideographicSpace"; CharacterCodes[CharacterCodes["mathematicalSpace"] = 8287] = "mathematicalSpace"; CharacterCodes[CharacterCodes["ogham"] = 5760] = "ogham"; CharacterCodes[CharacterCodes["_"] = 95] = "_"; CharacterCodes[CharacterCodes["$"] = 36] = "$"; CharacterCodes[CharacterCodes["_0"] = 48] = "_0"; CharacterCodes[CharacterCodes["_1"] = 49] = "_1"; CharacterCodes[CharacterCodes["_2"] = 50] = "_2"; CharacterCodes[CharacterCodes["_3"] = 51] = "_3"; CharacterCodes[CharacterCodes["_4"] = 52] = "_4"; CharacterCodes[CharacterCodes["_5"] = 53] = "_5"; CharacterCodes[CharacterCodes["_6"] = 54] = "_6"; CharacterCodes[CharacterCodes["_7"] = 55] = "_7"; CharacterCodes[CharacterCodes["_8"] = 56] = "_8"; CharacterCodes[CharacterCodes["_9"] = 57] = "_9"; CharacterCodes[CharacterCodes["a"] = 97] = "a"; CharacterCodes[CharacterCodes["b"] = 98] = "b"; CharacterCodes[CharacterCodes["c"] = 99] = "c"; CharacterCodes[CharacterCodes["d"] = 100] = "d"; CharacterCodes[CharacterCodes["e"] = 101] = "e"; CharacterCodes[CharacterCodes["f"] = 102] = "f"; CharacterCodes[CharacterCodes["g"] = 103] = "g"; CharacterCodes[CharacterCodes["h"] = 104] = "h"; CharacterCodes[CharacterCodes["i"] = 105] = "i"; CharacterCodes[CharacterCodes["j"] = 106] = "j"; CharacterCodes[CharacterCodes["k"] = 107] = "k"; CharacterCodes[CharacterCodes["l"] = 108] = "l"; CharacterCodes[CharacterCodes["m"] = 109] = "m"; CharacterCodes[CharacterCodes["n"] = 110] = "n"; CharacterCodes[CharacterCodes["o"] = 111] = "o"; CharacterCodes[CharacterCodes["p"] = 112] = "p"; CharacterCodes[CharacterCodes["q"] = 113] = "q"; CharacterCodes[CharacterCodes["r"] = 114] = "r"; CharacterCodes[CharacterCodes["s"] = 115] = "s"; CharacterCodes[CharacterCodes["t"] = 116] = "t"; CharacterCodes[CharacterCodes["u"] = 117] = "u"; CharacterCodes[CharacterCodes["v"] = 118] = "v"; CharacterCodes[CharacterCodes["w"] = 119] = "w"; CharacterCodes[CharacterCodes["x"] = 120] = "x"; CharacterCodes[CharacterCodes["y"] = 121] = "y"; CharacterCodes[CharacterCodes["z"] = 122] = "z"; CharacterCodes[CharacterCodes["A"] = 65] = "A"; CharacterCodes[CharacterCodes["B"] = 66] = "B"; CharacterCodes[CharacterCodes["C"] = 67] = "C"; CharacterCodes[CharacterCodes["D"] = 68] = "D"; CharacterCodes[CharacterCodes["E"] = 69] = "E"; CharacterCodes[CharacterCodes["F"] = 70] = "F"; CharacterCodes[CharacterCodes["G"] = 71] = "G"; CharacterCodes[CharacterCodes["H"] = 72] = "H"; CharacterCodes[CharacterCodes["I"] = 73] = "I"; CharacterCodes[CharacterCodes["J"] = 74] = "J"; CharacterCodes[CharacterCodes["K"] = 75] = "K"; CharacterCodes[CharacterCodes["L"] = 76] = "L"; CharacterCodes[CharacterCodes["M"] = 77] = "M"; CharacterCodes[CharacterCodes["N"] = 78] = "N"; CharacterCodes[CharacterCodes["O"] = 79] = "O"; CharacterCodes[CharacterCodes["P"] = 80] = "P"; CharacterCodes[CharacterCodes["Q"] = 81] = "Q"; CharacterCodes[CharacterCodes["R"] = 82] = "R"; CharacterCodes[CharacterCodes["S"] = 83] = "S"; CharacterCodes[CharacterCodes["T"] = 84] = "T"; CharacterCodes[CharacterCodes["U"] = 85] = "U"; CharacterCodes[CharacterCodes["V"] = 86] = "V"; CharacterCodes[CharacterCodes["W"] = 87] = "W"; CharacterCodes[CharacterCodes["X"] = 88] = "X"; CharacterCodes[CharacterCodes["Y"] = 89] = "Y"; CharacterCodes[CharacterCodes["Z"] = 90] = "Z"; CharacterCodes[CharacterCodes["ampersand"] = 38] = "ampersand"; CharacterCodes[CharacterCodes["asterisk"] = 42] = "asterisk"; CharacterCodes[CharacterCodes["at"] = 64] = "at"; CharacterCodes[CharacterCodes["backslash"] = 92] = "backslash"; CharacterCodes[CharacterCodes["backtick"] = 96] = "backtick"; CharacterCodes[CharacterCodes["bar"] = 124] = "bar"; CharacterCodes[CharacterCodes["caret"] = 94] = "caret"; CharacterCodes[CharacterCodes["closeBrace"] = 125] = "closeBrace"; CharacterCodes[CharacterCodes["closeBracket"] = 93] = "closeBracket"; CharacterCodes[CharacterCodes["closeParen"] = 41] = "closeParen"; CharacterCodes[CharacterCodes["colon"] = 58] = "colon"; CharacterCodes[CharacterCodes["comma"] = 44] = "comma"; CharacterCodes[CharacterCodes["dot"] = 46] = "dot"; CharacterCodes[CharacterCodes["doubleQuote"] = 34] = "doubleQuote"; CharacterCodes[CharacterCodes["equals"] = 61] = "equals"; CharacterCodes[CharacterCodes["exclamation"] = 33] = "exclamation"; CharacterCodes[CharacterCodes["greaterThan"] = 62] = "greaterThan"; CharacterCodes[CharacterCodes["hash"] = 35] = "hash"; CharacterCodes[CharacterCodes["lessThan"] = 60] = "lessThan"; CharacterCodes[CharacterCodes["minus"] = 45] = "minus"; CharacterCodes[CharacterCodes["openBrace"] = 123] = "openBrace"; CharacterCodes[CharacterCodes["openBracket"] = 91] = "openBracket"; CharacterCodes[CharacterCodes["openParen"] = 40] = "openParen"; CharacterCodes[CharacterCodes["percent"] = 37] = "percent"; CharacterCodes[CharacterCodes["plus"] = 43] = "plus"; CharacterCodes[CharacterCodes["question"] = 63] = "question"; CharacterCodes[CharacterCodes["semicolon"] = 59] = "semicolon"; CharacterCodes[CharacterCodes["singleQuote"] = 39] = "singleQuote"; CharacterCodes[CharacterCodes["slash"] = 47] = "slash"; CharacterCodes[CharacterCodes["tilde"] = 126] = "tilde"; CharacterCodes[CharacterCodes["backspace"] = 8] = "backspace"; CharacterCodes[CharacterCodes["formFeed"] = 12] = "formFeed"; CharacterCodes[CharacterCodes["byteOrderMark"] = 65279] = "byteOrderMark"; CharacterCodes[CharacterCodes["tab"] = 9] = "tab"; CharacterCodes[CharacterCodes["verticalTab"] = 11] = "verticalTab"; })(CharacterCodes = ts.CharacterCodes || (ts.CharacterCodes = {})); var Extension; (function (Extension) { Extension["Ts"] = ".ts"; Extension["Tsx"] = ".tsx"; Extension["Dts"] = ".d.ts"; Extension["Js"] = ".js"; Extension["Jsx"] = ".jsx"; Extension["Json"] = ".json"; })(Extension = ts.Extension || (ts.Extension = {})); /* @internal */ var TransformFlags; (function (TransformFlags) { TransformFlags[TransformFlags["None"] = 0] = "None"; // Facts // - Flags used to indicate that a node or subtree contains syntax that requires transformation. TransformFlags[TransformFlags["TypeScript"] = 1] = "TypeScript"; TransformFlags[TransformFlags["ContainsTypeScript"] = 2] = "ContainsTypeScript"; TransformFlags[TransformFlags["ContainsJsx"] = 4] = "ContainsJsx"; TransformFlags[TransformFlags["ContainsESNext"] = 8] = "ContainsESNext"; TransformFlags[TransformFlags["ContainsES2017"] = 16] = "ContainsES2017"; TransformFlags[TransformFlags["ContainsES2016"] = 32] = "ContainsES2016"; TransformFlags[TransformFlags["ES2015"] = 64] = "ES2015"; TransformFlags[TransformFlags["ContainsES2015"] = 128] = "ContainsES2015"; TransformFlags[TransformFlags["Generator"] = 256] = "Generator"; TransformFlags[TransformFlags["ContainsGenerator"] = 512] = "ContainsGenerator"; TransformFlags[TransformFlags["DestructuringAssignment"] = 1024] = "DestructuringAssignment"; TransformFlags[TransformFlags["ContainsDestructuringAssignment"] = 2048] = "ContainsDestructuringAssignment"; // Markers // - Flags used to indicate that a subtree contains a specific transformation. TransformFlags[TransformFlags["ContainsDecorators"] = 4096] = "ContainsDecorators"; TransformFlags[TransformFlags["ContainsPropertyInitializer"] = 8192] = "ContainsPropertyInitializer"; TransformFlags[TransformFlags["ContainsLexicalThis"] = 16384] = "ContainsLexicalThis"; TransformFlags[TransformFlags["ContainsCapturedLexicalThis"] = 32768] = "ContainsCapturedLexicalThis"; TransformFlags[TransformFlags["ContainsLexicalThisInComputedPropertyName"] = 65536] = "ContainsLexicalThisInComputedPropertyName"; TransformFlags[TransformFlags["ContainsDefaultValueAssignments"] = 131072] = "ContainsDefaultValueAssignments"; TransformFlags[TransformFlags["ContainsParameterPropertyAssignments"] = 262144] = "ContainsParameterPropertyAssignments"; TransformFlags[TransformFlags["ContainsSpread"] = 524288] = "ContainsSpread"; TransformFlags[TransformFlags["ContainsObjectSpread"] = 1048576] = "ContainsObjectSpread"; TransformFlags[TransformFlags["ContainsRest"] = 524288] = "ContainsRest"; TransformFlags[TransformFlags["ContainsObjectRest"] = 1048576] = "ContainsObjectRest"; TransformFlags[TransformFlags["ContainsComputedPropertyName"] = 2097152] = "ContainsComputedPropertyName"; TransformFlags[TransformFlags["ContainsBlockScopedBinding"] = 4194304] = "ContainsBlockScopedBinding"; TransformFlags[TransformFlags["ContainsBindingPattern"] = 8388608] = "ContainsBindingPattern"; TransformFlags[TransformFlags["ContainsYield"] = 16777216] = "ContainsYield"; TransformFlags[TransformFlags["ContainsHoistedDeclarationOrCompletion"] = 33554432] = "ContainsHoistedDeclarationOrCompletion"; TransformFlags[TransformFlags["ContainsDynamicImport"] = 67108864] = "ContainsDynamicImport"; // Please leave this as 1 << 29. // It is the maximum bit we can set before we outgrow the size of a v8 small integer (SMI) on an x86 system. // It is a good reminder of how much room we have left TransformFlags[TransformFlags["HasComputedFlags"] = 536870912] = "HasComputedFlags"; // Assertions // - Bitmasks that are used to assert facts about the syntax of a node and its subtree. TransformFlags[TransformFlags["AssertTypeScript"] = 3] = "AssertTypeScript"; TransformFlags[TransformFlags["AssertJsx"] = 4] = "AssertJsx"; TransformFlags[TransformFlags["AssertESNext"] = 8] = "AssertESNext"; TransformFlags[TransformFlags["AssertES2017"] = 16] = "AssertES2017"; TransformFlags[TransformFlags["AssertES2016"] = 32] = "AssertES2016"; TransformFlags[TransformFlags["AssertES2015"] = 192] = "AssertES2015"; TransformFlags[TransformFlags["AssertGenerator"] = 768] = "AssertGenerator"; TransformFlags[TransformFlags["AssertDestructuringAssignment"] = 3072] = "AssertDestructuringAssignment"; // Scope Exclusions // - Bitmasks that exclude flags from propagating out of a specific context // into the subtree flags of their container. TransformFlags[TransformFlags["NodeExcludes"] = 536872257] = "NodeExcludes"; TransformFlags[TransformFlags["ArrowFunctionExcludes"] = 601249089] = "ArrowFunctionExcludes"; TransformFlags[TransformFlags["FunctionExcludes"] = 601281857] = "FunctionExcludes"; TransformFlags[TransformFlags["ConstructorExcludes"] = 601015617] = "ConstructorExcludes"; TransformFlags[TransformFlags["MethodOrAccessorExcludes"] = 601015617] = "MethodOrAccessorExcludes"; TransformFlags[TransformFlags["ClassExcludes"] = 539358529] = "ClassExcludes"; TransformFlags[TransformFlags["ModuleExcludes"] = 574674241] = "ModuleExcludes"; TransformFlags[TransformFlags["TypeExcludes"] = -3] = "TypeExcludes"; TransformFlags[TransformFlags["ObjectLiteralExcludes"] = 540087617] = "ObjectLiteralExcludes"; TransformFlags[TransformFlags["ArrayLiteralOrCallOrNewExcludes"] = 537396545] = "ArrayLiteralOrCallOrNewExcludes"; TransformFlags[TransformFlags["VariableDeclarationListExcludes"] = 546309441] = "VariableDeclarationListExcludes"; TransformFlags[TransformFlags["ParameterExcludes"] = 536872257] = "ParameterExcludes"; TransformFlags[TransformFlags["CatchClauseExcludes"] = 537920833] = "CatchClauseExcludes"; TransformFlags[TransformFlags["BindingPatternExcludes"] = 537396545] = "BindingPatternExcludes"; // Masks // - Additional bitmasks TransformFlags[TransformFlags["TypeScriptClassSyntaxMask"] = 274432] = "TypeScriptClassSyntaxMask"; TransformFlags[TransformFlags["ES2015FunctionSyntaxMask"] = 163840] = "ES2015FunctionSyntaxMask"; })(TransformFlags = ts.TransformFlags || (ts.TransformFlags = {})); var EmitFlags; (function (EmitFlags) { EmitFlags[EmitFlags["SingleLine"] = 1] = "SingleLine"; EmitFlags[EmitFlags["AdviseOnEmitNode"] = 2] = "AdviseOnEmitNode"; EmitFlags[EmitFlags["NoSubstitution"] = 4] = "NoSubstitution"; EmitFlags[EmitFlags["CapturesThis"] = 8] = "CapturesThis"; EmitFlags[EmitFlags["NoLeadingSourceMap"] = 16] = "NoLeadingSourceMap"; EmitFlags[EmitFlags["NoTrailingSourceMap"] = 32] = "NoTrailingSourceMap"; EmitFlags[EmitFlags["NoSourceMap"] = 48] = "NoSourceMap"; EmitFlags[EmitFlags["NoNestedSourceMaps"] = 64] = "NoNestedSourceMaps"; EmitFlags[EmitFlags["NoTokenLeadingSourceMaps"] = 128] = "NoTokenLeadingSourceMaps"; EmitFlags[EmitFlags["NoTokenTrailingSourceMaps"] = 256] = "NoTokenTrailingSourceMaps"; EmitFlags[EmitFlags["NoTokenSourceMaps"] = 384] = "NoTokenSourceMaps"; EmitFlags[EmitFlags["NoLeadingComments"] = 512] = "NoLeadingComments"; EmitFlags[EmitFlags["NoTrailingComments"] = 1024] = "NoTrailingComments"; EmitFlags[EmitFlags["NoComments"] = 1536] = "NoComments"; EmitFlags[EmitFlags["NoNestedComments"] = 2048] = "NoNestedComments"; EmitFlags[EmitFlags["HelperName"] = 4096] = "HelperName"; EmitFlags[EmitFlags["ExportName"] = 8192] = "ExportName"; EmitFlags[EmitFlags["LocalName"] = 16384] = "LocalName"; EmitFlags[EmitFlags["InternalName"] = 32768] = "InternalName"; EmitFlags[EmitFlags["Indented"] = 65536] = "Indented"; EmitFlags[EmitFlags["NoIndentation"] = 131072] = "NoIndentation"; EmitFlags[EmitFlags["AsyncFunctionBody"] = 262144] = "AsyncFunctionBody"; EmitFlags[EmitFlags["ReuseTempVariableScope"] = 524288] = "ReuseTempVariableScope"; EmitFlags[EmitFlags["CustomPrologue"] = 1048576] = "CustomPrologue"; EmitFlags[EmitFlags["NoHoisting"] = 2097152] = "NoHoisting"; EmitFlags[EmitFlags["HasEndOfDeclarationMarker"] = 4194304] = "HasEndOfDeclarationMarker"; EmitFlags[EmitFlags["Iterator"] = 8388608] = "Iterator"; EmitFlags[EmitFlags["NoAsciiEscaping"] = 16777216] = "NoAsciiEscaping"; /*@internal*/ EmitFlags[EmitFlags["TypeScriptClassWrapper"] = 33554432] = "TypeScriptClassWrapper"; })(EmitFlags = ts.EmitFlags || (ts.EmitFlags = {})); /** * Used by the checker, this enum keeps track of external emit helpers that should be type * checked. */ /* @internal */ var ExternalEmitHelpers; (function (ExternalEmitHelpers) { ExternalEmitHelpers[ExternalEmitHelpers["Extends"] = 1] = "Extends"; ExternalEmitHelpers[ExternalEmitHelpers["Assign"] = 2] = "Assign"; ExternalEmitHelpers[ExternalEmitHelpers["Rest"] = 4] = "Rest"; ExternalEmitHelpers[ExternalEmitHelpers["Decorate"] = 8] = "Decorate"; ExternalEmitHelpers[ExternalEmitHelpers["Metadata"] = 16] = "Metadata"; ExternalEmitHelpers[ExternalEmitHelpers["Param"] = 32] = "Param"; ExternalEmitHelpers[ExternalEmitHelpers["Awaiter"] = 64] = "Awaiter"; ExternalEmitHelpers[ExternalEmitHelpers["Generator"] = 128] = "Generator"; ExternalEmitHelpers[ExternalEmitHelpers["Values"] = 256] = "Values"; ExternalEmitHelpers[ExternalEmitHelpers["Read"] = 512] = "Read"; ExternalEmitHelpers[ExternalEmitHelpers["Spread"] = 1024] = "Spread"; ExternalEmitHelpers[ExternalEmitHelpers["Await"] = 2048] = "Await"; ExternalEmitHelpers[ExternalEmitHelpers["AsyncGenerator"] = 4096] = "AsyncGenerator"; ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegator"] = 8192] = "AsyncDelegator"; ExternalEmitHelpers[ExternalEmitHelpers["AsyncValues"] = 16384] = "AsyncValues"; ExternalEmitHelpers[ExternalEmitHelpers["ExportStar"] = 32768] = "ExportStar"; ExternalEmitHelpers[ExternalEmitHelpers["MakeTemplateObject"] = 65536] = "MakeTemplateObject"; ExternalEmitHelpers[ExternalEmitHelpers["FirstEmitHelper"] = 1] = "FirstEmitHelper"; ExternalEmitHelpers[ExternalEmitHelpers["LastEmitHelper"] = 65536] = "LastEmitHelper"; // Helpers included by ES2015 for..of ExternalEmitHelpers[ExternalEmitHelpers["ForOfIncludes"] = 256] = "ForOfIncludes"; // Helpers included by ES2017 for..await..of ExternalEmitHelpers[ExternalEmitHelpers["ForAwaitOfIncludes"] = 16384] = "ForAwaitOfIncludes"; // Helpers included by ES2017 async generators ExternalEmitHelpers[ExternalEmitHelpers["AsyncGeneratorIncludes"] = 6144] = "AsyncGeneratorIncludes"; // Helpers included by yield* in ES2017 async generators ExternalEmitHelpers[ExternalEmitHelpers["AsyncDelegatorIncludes"] = 26624] = "AsyncDelegatorIncludes"; // Helpers included by ES2015 spread ExternalEmitHelpers[ExternalEmitHelpers["SpreadIncludes"] = 1536] = "SpreadIncludes"; })(ExternalEmitHelpers = ts.ExternalEmitHelpers || (ts.ExternalEmitHelpers = {})); var EmitHint; (function (EmitHint) { EmitHint[EmitHint["SourceFile"] = 0] = "SourceFile"; EmitHint[EmitHint["Expression"] = 1] = "Expression"; EmitHint[EmitHint["IdentifierName"] = 2] = "IdentifierName"; EmitHint[EmitHint["MappedTypeParameter"] = 3] = "MappedTypeParameter"; EmitHint[EmitHint["Unspecified"] = 4] = "Unspecified"; })(EmitHint = ts.EmitHint || (ts.EmitHint = {})); })(ts || (ts = {})); /*@internal*/ var ts; (function (ts) { /** Gets a timestamp with (at least) ms resolution */ ts.timestamp = typeof performance !== "undefined" && performance.now ? function () { return performance.now(); } : Date.now ? Date.now : function () { return +(new Date()); }; })(ts || (ts = {})); /*@internal*/ /** Performance measurements for the compiler. */ (function (ts) { var performance; (function (performance) { // NOTE: cannot use ts.noop as core.ts loads after this var profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true ? onProfilerEvent : function () { }; var enabled = false; var profilerStart = 0; var counts; var marks; var measures; /** * Marks a performance event. * * @param markName The name of the mark. */ function mark(markName) { if (enabled) { marks.set(markName, ts.timestamp()); counts.set(markName, (counts.get(markName) || 0) + 1); profilerEvent(markName); } } performance.mark = mark; /** * Adds a performance measurement with the specified name. * * @param measureName The name of the performance measurement. * @param startMarkName The name of the starting mark. If not supplied, the point at which the * profiler was enabled is used. * @param endMarkName The name of the ending mark. If not supplied, the current timestamp is * used. */ function measure(measureName, startMarkName, endMarkName) { if (enabled) { var end = endMarkName && marks.get(endMarkName) || ts.timestamp(); var start = startMarkName && marks.get(startMarkName) || profilerStart; measures.set(measureName, (measures.get(measureName) || 0) + (end - start)); } } performance.measure = measure; /** * Gets the number of times a marker was encountered. * * @param markName The name of the mark. */ function getCount(markName) { return counts && counts.get(markName) || 0; } performance.getCount = getCount; /** * Gets the total duration of all measurements with the supplied name. * * @param measureName The name of the measure whose durations should be accumulated. */ function getDuration(measureName) { return measures && measures.get(measureName) || 0; } performance.getDuration = getDuration; /** * Iterate over each measure, performing some action * * @param cb The action to perform for each measure */ function forEachMeasure(cb) { measures.forEach(function (measure, key) { cb(key, measure); }); } performance.forEachMeasure = forEachMeasure; /** Enables (and resets) performance measurements for the compiler. */ function enable() { counts = ts.createMap(); marks = ts.createMap(); measures = ts.createMap(); enabled = true; profilerStart = ts.timestamp(); } performance.enable = enable; /** Disables performance measurements for the compiler. */ function disable() { enabled = false; } performance.disable = disable; })(performance = ts.performance || (ts.performance = {})); })(ts || (ts = {})); /// /// var ts; (function (ts) { // WARNING: The script `configureNightly.ts` uses a regexp to parse out these values. // If changing the text in this section, be sure to test `configureNightly` too. ts.versionMajorMinor = "2.7"; /** The version of the TypeScript compiler release */ ts.version = ts.versionMajorMinor + ".0"; })(ts || (ts = {})); (function (ts) { function isExternalModuleNameRelative(moduleName) { // TypeScript 1.0 spec (April 2014): 11.2.1 // An external module name is "relative" if the first term is "." or "..". // Update: We also consider a path like `C:\foo.ts` "relative" because we do not search for it in `node_modules` or treat it as an ambient module. return ts.pathIsRelative(moduleName) || ts.isRootedDiskPath(moduleName); } ts.isExternalModuleNameRelative = isExternalModuleNameRelative; })(ts || (ts = {})); /* @internal */ (function (ts) { /** Create a MapLike with good performance. */ function createDictionaryObject() { var map = Object.create(/*prototype*/ null); // tslint:disable-line:no-null-keyword // Using 'delete' on an object causes V8 to put the object in dictionary mode. // This disables creation of hidden classes, which are expensive when an object is // constantly changing shape. map.__ = undefined; delete map.__; return map; } /** Create a new map. If a template object is provided, the map will copy entries from it. */ function createMap() { return new MapCtr(); } ts.createMap = createMap; /** Create a new escaped identifier map. */ function createUnderscoreEscapedMap() { return new MapCtr(); } ts.createUnderscoreEscapedMap = createUnderscoreEscapedMap; function createSymbolTable(symbols) { var result = createMap(); if (symbols) { for (var _i = 0, symbols_1 = symbols; _i < symbols_1.length; _i++) { var symbol = symbols_1[_i]; result.set(symbol.escapedName, symbol); } } return result; } ts.createSymbolTable = createSymbolTable; function createMapFromTemplate(template) { var map = new MapCtr(); // Copies keys/values from template. Note that for..in will not throw if // template is undefined, and instead will just exit the loop. for (var key in template) { if (hasOwnProperty.call(template, key)) { map.set(key, template[key]); } } return map; } ts.createMapFromTemplate = createMapFromTemplate; // Internet Explorer's Map doesn't support iteration, so don't use it. // tslint:disable-next-line no-in-operator variable-name var MapCtr = typeof Map !== "undefined" && "entries" in Map.prototype ? Map : shimMap(); // Keep the class inside a function so it doesn't get compiled if it's not used. function shimMap() { var MapIterator = /** @class */ (function () { function MapIterator(data, selector) { this.index = 0; this.data = data; this.selector = selector; this.keys = Object.keys(data); } MapIterator.prototype.next = function () { var index = this.index; if (index < this.keys.length) { this.index++; return { value: this.selector(this.data, this.keys[index]), done: false }; } return { value: undefined, done: true }; }; return MapIterator; }()); return /** @class */ (function () { function class_1() { this.data = createDictionaryObject(); this.size = 0; } class_1.prototype.get = function (key) { return this.data[key]; }; class_1.prototype.set = function (key, value) { if (!this.has(key)) { this.size++; } this.data[key] = value; return this; }; class_1.prototype.has = function (key) { // tslint:disable-next-line:no-in-operator return key in this.data; }; class_1.prototype.delete = function (key) { if (this.has(key)) { this.size--; delete this.data[key]; return true; } return false; }; class_1.prototype.clear = function () { this.data = createDictionaryObject(); this.size = 0; }; class_1.prototype.keys = function () { return new MapIterator(this.data, function (_data, key) { return key; }); }; class_1.prototype.values = function () { return new MapIterator(this.data, function (data, key) { return data[key]; }); }; class_1.prototype.entries = function () { return new MapIterator(this.data, function (data, key) { return [key, data[key]]; }); }; class_1.prototype.forEach = function (action) { for (var key in this.data) { action(this.data[key], key); } }; return class_1; }()); } function toPath(fileName, basePath, getCanonicalFileName) { var nonCanonicalizedPath = isRootedDiskPath(fileName) ? normalizePath(fileName) : getNormalizedAbsolutePath(fileName, basePath); return getCanonicalFileName(nonCanonicalizedPath); } ts.toPath = toPath; function length(array) { return array ? array.length : 0; } ts.length = length; /** * Iterates through 'array' by index and performs the callback on each element of array until the callback * returns a truthy value, then returns that value. * If no such value is found, the callback is applied to each element of array and undefined is returned. */ function forEach(array, callback) { if (array) { for (var i = 0; i < array.length; i++) { var result = callback(array[i], i); if (result) { return result; } } } return undefined; } ts.forEach = forEach; /** Like `forEach`, but suitable for use with numbers and strings (which may be falsy). */ function firstDefined(array, callback) { for (var i = 0; i < array.length; i++) { var result = callback(array[i], i); if (result !== undefined) { return result; } } return undefined; } ts.firstDefined = firstDefined; function findAncestor(node, callback) { while (node) { var result = callback(node); if (result === "quit") { return undefined; } else if (result) { return node; } node = node.parent; } return undefined; } ts.findAncestor = findAncestor; function zipWith(arrayA, arrayB, callback) { var result = []; Debug.assert(arrayA.length === arrayB.length); for (var i = 0; i < arrayA.length; i++) { result.push(callback(arrayA[i], arrayB[i], i)); } return result; } ts.zipWith = zipWith; function zipToMap(keys, values) { Debug.assert(keys.length === values.length); var map = createMap(); for (var i = 0; i < keys.length; ++i) { map.set(keys[i], values[i]); } return map; } ts.zipToMap = zipToMap; /** * Iterates through `array` by index and performs the callback on each element of array until the callback * returns a falsey value, then returns false. * If no such value is found, the callback is applied to each element of array and `true` is returned. */ function every(array, callback) { if (array) { for (var i = 0; i < array.length; i++) { if (!callback(array[i], i)) { return false; } } } return true; } ts.every = every; function find(array, predicate) { for (var i = 0; i < array.length; i++) { var value = array[i]; if (predicate(value, i)) { return value; } } return undefined; } ts.find = find; function findLast(array, predicate) { for (var i = array.length - 1; i >= 0; i--) { var value = array[i]; if (predicate(value, i)) { return value; } } return undefined; } ts.findLast = findLast; /** Works like Array.prototype.findIndex, returning `-1` if no element satisfying the predicate is found. */ function findIndex(array, predicate) { for (var i = 0; i < array.length; i++) { if (predicate(array[i], i)) { return i; } } return -1; } ts.findIndex = findIndex; /** * Returns the first truthy result of `callback`, or else fails. * This is like `forEach`, but never returns undefined. */ function findMap(array, callback) { for (var i = 0; i < array.length; i++) { var result = callback(array[i], i); if (result) { return result; } } Debug.fail(); } ts.findMap = findMap; function contains(array, value, equalityComparer) { if (equalityComparer === void 0) { equalityComparer = equateValues; } if (array) { for (var _i = 0, array_1 = array; _i < array_1.length; _i++) { var v = array_1[_i]; if (equalityComparer(v, value)) { return true; } } } return false; } ts.contains = contains; function indexOf(array, value) { if (array) { for (var i = 0; i < array.length; i++) { if (array[i] === value) { return i; } } } return -1; } ts.indexOf = indexOf; function indexOfAnyCharCode(text, charCodes, start) { for (var i = start || 0; i < text.length; i++) { if (contains(charCodes, text.charCodeAt(i))) { return i; } } return -1; } ts.indexOfAnyCharCode = indexOfAnyCharCode; function countWhere(array, predicate) { var count = 0; if (array) { for (var i = 0; i < array.length; i++) { var v = array[i]; if (predicate(v, i)) { count++; } } } return count; } ts.countWhere = countWhere; function filter(array, f) { if (array) { var len = array.length; var i = 0; while (i < len && f(array[i])) i++; if (i < len) { var result = array.slice(0, i); i++; while (i < len) { var item = array[i]; if (f(item)) { result.push(item); } i++; } return result; } } return array; } ts.filter = filter; function filterMutate(array, f) { var outIndex = 0; for (var i = 0; i < array.length; i++) { if (f(array[i], i, array)) { array[outIndex] = array[i]; outIndex++; } } array.length = outIndex; } ts.filterMutate = filterMutate; function clear(array) { array.length = 0; } ts.clear = clear; function map(array, f) { var result; if (array) { result = []; for (var i = 0; i < array.length; i++) { result.push(f(array[i], i)); } } return result; } ts.map = map; function mapIterator(iter, mapFn) { return { next: next }; function next() { var iterRes = iter.next(); return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false }; } } ts.mapIterator = mapIterator; function sameMap(array, f) { var result; if (array) { for (var i = 0; i < array.length; i++) { if (result) { result.push(f(array[i], i)); } else { var item = array[i]; var mapped = f(item, i); if (item !== mapped) { result = array.slice(0, i); result.push(mapped); } } } } return result || array; } ts.sameMap = sameMap; /** * Flattens an array containing a mix of array or non-array elements. * * @param array The array to flatten. */ function flatten(array) { var result; if (array) { result = []; for (var _i = 0, array_2 = array; _i < array_2.length; _i++) { var v = array_2[_i]; if (v) { if (isArray(v)) { addRange(result, v); } else { result.push(v); } } } } return result; } ts.flatten = flatten; /** * Maps an array. If the mapped value is an array, it is spread into the result. * * @param array The array to map. * @param mapfn The callback used to map the result into one or more values. */ function flatMap(array, mapfn) { var result; if (array) { result = []; for (var i = 0; i < array.length; i++) { var v = mapfn(array[i], i); if (v) { if (isArray(v)) { addRange(result, v); } else { result.push(v); } } } } return result; } ts.flatMap = flatMap; function flatMapIter(iter, mapfn) { var result = []; while (true) { var _a = iter.next(), value = _a.value, done = _a.done; if (done) break; var res = mapfn(value); if (res) { if (isArray(res)) { result.push.apply(result, res); } else { result.push(res); } } } return result; } ts.flatMapIter = flatMapIter; function sameFlatMap(array, mapfn) { var result; if (array) { for (var i = 0; i < array.length; i++) { var item = array[i]; var mapped = mapfn(item, i); if (result || item !== mapped || isArray(mapped)) { if (!result) { result = array.slice(0, i); } if (isArray(mapped)) { addRange(result, mapped); } else { result.push(mapped); } } } } return result || array; } ts.sameFlatMap = sameFlatMap; function mapDefined(array, mapFn) { var result = []; if (array) { for (var i = 0; i < array.length; i++) { var item = array[i]; var mapped = mapFn(item, i); if (mapped !== undefined) { result.push(mapped); } } } return result; } ts.mapDefined = mapDefined; function mapDefinedIter(iter, mapFn) { var result = []; while (true) { var _a = iter.next(), value = _a.value, done = _a.done; if (done) break; var res = mapFn(value); if (res !== undefined) { result.push(res); } } return result; } ts.mapDefinedIter = mapDefinedIter; /** * Computes the first matching span of elements and returns a tuple of the first span * and the remaining elements. */ function span(array, f) { if (array) { for (var i = 0; i < array.length; i++) { if (!f(array[i], i)) { return [array.slice(0, i), array.slice(i)]; } } return [array.slice(0), []]; } return undefined; } ts.span = span; /** * Maps contiguous spans of values with the same key. * * @param array The array to map. * @param keyfn A callback used to select the key for an element. * @param mapfn A callback used to map a contiguous chunk of values to a single value. */ function spanMap(array, keyfn, mapfn) { var result; if (array) { result = []; var len = array.length; var previousKey = void 0; var key = void 0; var start = 0; var pos = 0; while (start < len) { while (pos < len) { var value = array[pos]; key = keyfn(value, pos); if (pos === 0) { previousKey = key; } else if (key !== previousKey) { break; } pos++; } if (start < pos) { var v = mapfn(array.slice(start, pos), previousKey, start, pos); if (v) { result.push(v); } start = pos; } previousKey = key; pos++; } } return result; } ts.spanMap = spanMap; function mapEntries(map, f) { if (!map) { return undefined; } var result = createMap(); map.forEach(function (value, key) { var _a = f(key, value), newKey = _a[0], newValue = _a[1]; result.set(newKey, newValue); }); return result; } ts.mapEntries = mapEntries; function some(array, predicate) { if (array) { if (predicate) { for (var _i = 0, array_3 = array; _i < array_3.length; _i++) { var v = array_3[_i]; if (predicate(v)) { return true; } } } else { return array.length > 0; } } return false; } ts.some = some; function concatenate(array1, array2) { if (!some(array2)) return array1; if (!some(array1)) return array2; return array1.concat(array2); } ts.concatenate = concatenate; function deduplicateRelational(array, equalityComparer, comparer) { // Perform a stable sort of the array. This ensures the first entry in a list of // duplicates remains the first entry in the result. var indices = array.map(function (_, i) { return i; }); stableSortIndices(array, indices, comparer); var last = array[indices[0]]; var deduplicated = [indices[0]]; for (var i = 1; i < indices.length; i++) { var index = indices[i]; var item = array[index]; if (!equalityComparer(last, item)) { deduplicated.push(index); last = item; } } // restore original order deduplicated.sort(); return deduplicated.map(function (i) { return array[i]; }); } function deduplicateEquality(array, equalityComparer) { var result = []; for (var _i = 0, array_4 = array; _i < array_4.length; _i++) { var item = array_4[_i]; pushIfUnique(result, item, equalityComparer); } return result; } /** * Deduplicates an unsorted array. * @param equalityComparer An optional `EqualityComparer` used to determine if two values are duplicates. * @param comparer An optional `Comparer` used to sort entries before comparison, though the * result will remain in the original order in `array`. */ function deduplicate(array, equalityComparer, comparer) { return !array ? undefined : array.length === 0 ? [] : array.length === 1 ? array.slice() : comparer ? deduplicateRelational(array, equalityComparer, comparer) : deduplicateEquality(array, equalityComparer); } ts.deduplicate = deduplicate; /** * Deduplicates an array that has already been sorted. */ function deduplicateSorted(array, comparer) { if (!array) return undefined; if (array.length === 0) return []; var last = array[0]; var deduplicated = [last]; for (var i = 1; i < array.length; i++) { var next = array[i]; switch (comparer(next, last)) { // equality comparison case true: // relational comparison case 0 /* EqualTo */: continue; case -1 /* LessThan */: // If `array` is sorted, `next` should **never** be less than `last`. return Debug.fail("Array is unsorted."); } deduplicated.push(last = next); } return deduplicated; } function sortAndDeduplicate(array, comparer, equalityComparer) { return deduplicateSorted(sort(array, comparer), equalityComparer || comparer); } ts.sortAndDeduplicate = sortAndDeduplicate; function arrayIsEqualTo(array1, array2, equalityComparer) { if (equalityComparer === void 0) { equalityComparer = equateValues; } if (!array1 || !array2) { return array1 === array2; } if (array1.length !== array2.length) { return false; } for (var i = 0; i < array1.length; i++) { if (!equalityComparer(array1[i], array2[i])) { return false; } } return true; } ts.arrayIsEqualTo = arrayIsEqualTo; function changesAffectModuleResolution(oldOptions, newOptions) { return !oldOptions || (oldOptions.module !== newOptions.module) || (oldOptions.moduleResolution !== newOptions.moduleResolution) || (oldOptions.noResolve !== newOptions.noResolve) || (oldOptions.target !== newOptions.target) || (oldOptions.noLib !== newOptions.noLib) || (oldOptions.jsx !== newOptions.jsx) || (oldOptions.allowJs !== newOptions.allowJs) || (oldOptions.rootDir !== newOptions.rootDir) || (oldOptions.configFilePath !== newOptions.configFilePath) || (oldOptions.baseUrl !== newOptions.baseUrl) || (oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) || !arrayIsEqualTo(oldOptions.lib, newOptions.lib) || !arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) || !arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) || !equalOwnProperties(oldOptions.paths, newOptions.paths); } ts.changesAffectModuleResolution = changesAffectModuleResolution; function compact(array) { var result; if (array) { for (var i = 0; i < array.length; i++) { var v = array[i]; if (result || !v) { if (!result) { result = array.slice(0, i); } if (v) { result.push(v); } } } } return result || array; } ts.compact = compact; /** * Gets the relative complement of `arrayA` with respect to `arrayB`, returning the elements that * are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted * based on the provided comparer. */ function relativeComplement(arrayA, arrayB, comparer) { if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB; var result = []; loopB: for (var offsetA = 0, offsetB = 0; offsetB < arrayB.length; offsetB++) { if (offsetB > 0) { // Ensure `arrayB` is properly sorted. Debug.assertGreaterThanOrEqual(comparer(arrayB[offsetB], arrayB[offsetB - 1]), 0 /* EqualTo */); } loopA: for (var startA = offsetA; offsetA < arrayA.length; offsetA++) { if (offsetA > startA) { // Ensure `arrayA` is properly sorted. We only need to perform this check if // `offsetA` has changed since we entered the loop. Debug.assertGreaterThanOrEqual(comparer(arrayA[offsetA], arrayA[offsetA - 1]), 0 /* EqualTo */); } switch (comparer(arrayB[offsetB], arrayA[offsetA])) { case -1 /* LessThan */: // If B is less than A, B does not exist in arrayA. Add B to the result and // move to the next element in arrayB without changing the current position // in arrayA. result.push(arrayB[offsetB]); continue loopB; case 0 /* EqualTo */: // If B is equal to A, B exists in arrayA. Move to the next element in // arrayB without adding B to the result or changing the current position // in arrayA. continue loopB; case 1 /* GreaterThan */: // If B is greater than A, we need to keep looking for B in arrayA. Move to // the next element in arrayA and recheck. continue loopA; } } } return result; } ts.relativeComplement = relativeComplement; function sum(array, prop) { var result = 0; for (var _i = 0, array_5 = array; _i < array_5.length; _i++) { var v = array_5[_i]; // Note: we need the following type assertion because of GH #17069 result += v[prop]; } return result; } ts.sum = sum; /** * Appends a value to an array, returning the array. * * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array * is created if `value` was appended. * @param value The value to append to the array. If `value` is `undefined`, nothing is * appended. */ function append(to, value) { if (value === undefined) return to; if (to === undefined) return [value]; to.push(value); return to; } ts.append = append; /** * Gets the actual offset into an array for a relative offset. Negative offsets indicate a * position offset from the end of the array. */ function toOffset(array, offset) { return offset < 0 ? array.length + offset : offset; } /** * Appends a range of value to an array, returning the array. * * @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array * is created if `value` was appended. * @param from The values to append to the array. If `from` is `undefined`, nothing is * appended. If an element of `from` is `undefined`, that element is not appended. * @param start The offset in `from` at which to start copying values. * @param end The offset in `from` at which to stop copying values (non-inclusive). */ function addRange(to, from, start, end) { if (from === undefined || from.length === 0) return to; if (to === undefined) return from.slice(start, end); start = start === undefined ? 0 : toOffset(from, start); end = end === undefined ? from.length : toOffset(from, end); for (var i = start; i < end && i < from.length; i++) { if (from[i] !== undefined) { to.push(from[i]); } } return to; } ts.addRange = addRange; /** * @return Whether the value was added. */ function pushIfUnique(array, toAdd, equalityComparer) { if (contains(array, toAdd, equalityComparer)) { return false; } else { array.push(toAdd); return true; } } ts.pushIfUnique = pushIfUnique; /** * Unlike `pushIfUnique`, this can take `undefined` as an input, and returns a new array. */ function appendIfUnique(array, toAdd, equalityComparer) { if (array) { pushIfUnique(array, toAdd, equalityComparer); return array; } else { return [toAdd]; } } ts.appendIfUnique = appendIfUnique; function stableSortIndices(array, indices, comparer) { // sort indices by value then position indices.sort(function (x, y) { return comparer(array[x], array[y]) || compareValues(x, y); }); } /** * Returns a new sorted array. */ function sort(array, comparer) { return array.slice().sort(comparer); } ts.sort = sort; function best(iter, isBetter) { var x = iter.next(); if (x.done) { return undefined; } var best = x.value; while (true) { var _a = iter.next(), value = _a.value, done = _a.done; if (done) { return best; } if (isBetter(value, best)) { best = value; } } } ts.best = best; function arrayIterator(array) { var i = 0; return { next: function () { if (i === array.length) { return { value: undefined, done: true }; } else { i++; return { value: array[i - 1], done: false }; } } }; } ts.arrayIterator = arrayIterator; /** * Stable sort of an array. Elements equal to each other maintain their relative position in the array. */ function stableSort(array, comparer) { var indices = array.map(function (_, i) { return i; }); stableSortIndices(array, indices, comparer); return indices.map(function (i) { return array[i]; }); } ts.stableSort = stableSort; function rangeEquals(array1, array2, pos, end) { while (pos < end) { if (array1[pos] !== array2[pos]) { return false; } pos++; } return true; } ts.rangeEquals = rangeEquals; /** * Returns the element at a specific offset in an array if non-empty, `undefined` otherwise. * A negative offset indicates the element should be retrieved from the end of the array. */ function elementAt(array, offset) { if (array) { offset = toOffset(array, offset); if (offset < array.length) { return array[offset]; } } return undefined; } ts.elementAt = elementAt; /** * Returns the first element of an array if non-empty, `undefined` otherwise. */ function firstOrUndefined(array) { return elementAt(array, 0); } ts.firstOrUndefined = firstOrUndefined; function first(array) { Debug.assert(array.length !== 0); return array[0]; } ts.first = first; /** * Returns the last element of an array if non-empty, `undefined` otherwise. */ function lastOrUndefined(array) { return elementAt(array, -1); } ts.lastOrUndefined = lastOrUndefined; function last(array) { Debug.assert(array.length !== 0); return array[array.length - 1]; } ts.last = last; /** * Returns the only element of an array if it contains only one element, `undefined` otherwise. */ function singleOrUndefined(array) { return array && array.length === 1 ? array[0] : undefined; } ts.singleOrUndefined = singleOrUndefined; function singleOrMany(array) { return array && array.length === 1 ? array[0] : array; } ts.singleOrMany = singleOrMany; function replaceElement(array, index, value) { var result = array.slice(0); result[index] = value; return result; } ts.replaceElement = replaceElement; /** * Performs a binary search, finding the index at which `value` occurs in `array`. * If no such index is found, returns the 2's-complement of first index at which * `array[index]` exceeds `value`. * @param array A sorted array whose first element must be no larger than number * @param value The value to be searched for in the array. * @param keySelector A callback used to select the search key from `value` and each element of * `array`. * @param keyComparer A callback used to compare two keys in a sorted array. * @param offset An offset into `array` at which to start the search. */ function binarySearch(array, value, keySelector, keyComparer, offset) { if (!array || array.length === 0) { return -1; } var low = offset || 0; var high = array.length - 1; var key = keySelector(value); while (low <= high) { var middle = low + ((high - low) >> 1); var midKey = keySelector(array[middle]); switch (keyComparer(midKey, key)) { case -1 /* LessThan */: low = middle + 1; break; case 0 /* EqualTo */: return middle; case 1 /* GreaterThan */: high = middle - 1; break; } } return ~low; } ts.binarySearch = binarySearch; function reduceLeft(array, f, initial, start, count) { if (array && array.length > 0) { var size = array.length; if (size > 0) { var pos = start === undefined || start < 0 ? 0 : start; var end = count === undefined || pos + count > size - 1 ? size - 1 : pos + count; var result = void 0; if (arguments.length <= 2) { result = array[pos]; pos++; } else { result = initial; } while (pos <= end) { result = f(result, array[pos], pos); pos++; } return result; } } return initial; } ts.reduceLeft = reduceLeft; var hasOwnProperty = Object.prototype.hasOwnProperty; /** * Indicates whether a map-like contains an own property with the specified key. * * @param map A map-like. * @param key A property key. */ function hasProperty(map, key) { return hasOwnProperty.call(map, key); } ts.hasProperty = hasProperty; /** * Gets the value of an owned property in a map-like. * * @param map A map-like. * @param key A property key. */ function getProperty(map, key) { return hasOwnProperty.call(map, key) ? map[key] : undefined; } ts.getProperty = getProperty; /** * Gets the owned, enumerable property keys of a map-like. */ function getOwnKeys(map) { var keys = []; for (var key in map) { if (hasOwnProperty.call(map, key)) { keys.push(key); } } return keys; } ts.getOwnKeys = getOwnKeys; function getOwnValues(sparseArray) { var values = []; for (var key in sparseArray) { if (hasOwnProperty.call(sparseArray, key)) { values.push(sparseArray[key]); } } return values; } ts.getOwnValues = getOwnValues; function arrayFrom(iterator, map) { var result = []; for (var _a = iterator.next(), value = _a.value, done = _a.done; !done; _b = iterator.next(), value = _b.value, done = _b.done, _b) { result.push(map ? map(value) : value); } return result; var _b; } ts.arrayFrom = arrayFrom; function forEachEntry(map, callback) { var iterator = map.entries(); for (var _a = iterator.next(), pair = _a.value, done = _a.done; !done; _b = iterator.next(), pair = _b.value, done = _b.done, _b) { var key = pair[0], value = pair[1]; var result = callback(value, key); if (result) { return result; } } return undefined; var _b; } ts.forEachEntry = forEachEntry; function forEachKey(map, callback) { var iterator = map.keys(); for (var _a = iterator.next(), key = _a.value, done = _a.done; !done; _b = iterator.next(), key = _b.value, done = _b.done, _b) { var result = callback(key); if (result) { return result; } } return undefined; var _b; } ts.forEachKey = forEachKey; function copyEntries(source, target) { source.forEach(function (value, key) { target.set(key, value); }); } ts.copyEntries = copyEntries; function assign(t) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } for (var _a = 0, args_1 = args; _a < args_1.length; _a++) { var arg = args_1[_a]; for (var p in arg) { if (hasProperty(arg, p)) { t[p] = arg[p]; } } } return t; } ts.assign = assign; /** * Performs a shallow equality comparison of the contents of two map-likes. * * @param left A map-like whose properties should be compared. * @param right A map-like whose properties should be compared. */ function equalOwnProperties(left, right, equalityComparer) { if (equalityComparer === void 0) { equalityComparer = equateValues; } if (left === right) return true; if (!left || !right) return false; for (var key in left) { if (hasOwnProperty.call(left, key)) { if (!hasOwnProperty.call(right, key) === undefined) return false; if (!equalityComparer(left[key], right[key])) return false; } } for (var key in right) { if (hasOwnProperty.call(right, key)) { if (!hasOwnProperty.call(left, key)) return false; } } return true; } ts.equalOwnProperties = equalOwnProperties; function arrayToMap(array, makeKey, makeValue) { var result = createMap(); for (var _i = 0, array_6 = array; _i < array_6.length; _i++) { var value = array_6[_i]; result.set(makeKey(value), makeValue ? makeValue(value) : value); } return result; } ts.arrayToMap = arrayToMap; function arrayToNumericMap(array, makeKey, makeValue) { var result = []; for (var _i = 0, array_7 = array; _i < array_7.length; _i++) { var value = array_7[_i]; result[makeKey(value)] = makeValue ? makeValue(value) : value; } return result; } ts.arrayToNumericMap = arrayToNumericMap; function arrayToSet(array, makeKey) { return arrayToMap(array, makeKey || (function (s) { return s; }), function () { return true; }); } ts.arrayToSet = arrayToSet; function cloneMap(map) { var clone = createMap(); copyEntries(map, clone); return clone; } ts.cloneMap = cloneMap; function clone(object) { var result = {}; for (var id in object) { if (hasOwnProperty.call(object, id)) { result[id] = object[id]; } } return result; } ts.clone = clone; function extend(first, second) { var result = {}; for (var id in second) { if (hasOwnProperty.call(second, id)) { result[id] = second[id]; } } for (var id in first) { if (hasOwnProperty.call(first, id)) { result[id] = first[id]; } } return result; } ts.extend = extend; function createMultiMap() { var map = createMap(); map.add = multiMapAdd; map.remove = multiMapRemove; return map; } ts.createMultiMap = createMultiMap; function multiMapAdd(key, value) { var values = this.get(key); if (values) { values.push(value); } else { this.set(key, values = [value]); } return values; } function multiMapRemove(key, value) { var values = this.get(key); if (values) { unorderedRemoveItem(values, value); if (!values.length) { this.delete(key); } } } /** * Tests whether a value is an array. */ function isArray(value) { return Array.isArray ? Array.isArray(value) : value instanceof Array; } ts.isArray = isArray; function toArray(value) { return isArray(value) ? value : [value]; } ts.toArray = toArray; /** * Tests whether a value is string */ function isString(text) { return typeof text === "string"; } ts.isString = isString; function tryCast(value, test) { return value !== undefined && test(value) ? value : undefined; } ts.tryCast = tryCast; function cast(value, test) { if (value !== undefined && test(value)) return value; Debug.fail("Invalid cast. The supplied value did not pass the test '" + Debug.getFunctionName(test) + "'."); } ts.cast = cast; /** Does nothing. */ function noop(_) { } // tslint:disable-line no-empty ts.noop = noop; /** Do nothing and return false */ function returnFalse() { return false; } ts.returnFalse = returnFalse; /** Do nothing and return true */ function returnTrue() { return true; } ts.returnTrue = returnTrue; /** Returns its argument. */ function identity(x) { return x; } ts.identity = identity; /** Throws an error because a function is not implemented. */ function notImplemented() { throw new Error("Not implemented"); } ts.notImplemented = notImplemented; function memoize(callback) { var value; return function () { if (callback) { value = callback(); callback = undefined; } return value; }; } ts.memoize = memoize; function chain(a, b, c, d, e) { if (e) { var args_2 = []; for (var i = 0; i < arguments.length; i++) { args_2[i] = arguments[i]; } return function (t) { return compose.apply(void 0, map(args_2, function (f) { return f(t); })); }; } else if (d) { return function (t) { return compose(a(t), b(t), c(t), d(t)); }; } else if (c) { return function (t) { return compose(a(t), b(t), c(t)); }; } else if (b) { return function (t) { return compose(a(t), b(t)); }; } else if (a) { return function (t) { return compose(a(t)); }; } else { return function (_) { return function (u) { return u; }; }; } } ts.chain = chain; function compose(a, b, c, d, e) { if (e) { var args_3 = []; for (var i = 0; i < arguments.length; i++) { args_3[i] = arguments[i]; } return function (t) { return reduceLeft(args_3, function (u, f) { return f(u); }, t); }; } else if (d) { return function (t) { return d(c(b(a(t)))); }; } else if (c) { return function (t) { return c(b(a(t))); }; } else if (b) { return function (t) { return b(a(t)); }; } else if (a) { return function (t) { return a(t); }; } else { return function (t) { return t; }; } } ts.compose = compose; function formatStringFromArgs(text, args, baseIndex) { baseIndex = baseIndex || 0; return text.replace(/{(\d+)}/g, function (_match, index) { return args[+index + baseIndex]; }); } ts.formatStringFromArgs = formatStringFromArgs; ts.localizedDiagnosticMessages = undefined; function getLocaleSpecificMessage(message) { return ts.localizedDiagnosticMessages && ts.localizedDiagnosticMessages[message.key] || message.message; } ts.getLocaleSpecificMessage = getLocaleSpecificMessage; function createFileDiagnostic(file, start, length, message) { Debug.assertGreaterThanOrEqual(start, 0); Debug.assertGreaterThanOrEqual(length, 0); if (file) { Debug.assertLessThanOrEqual(start, file.text.length); Debug.assertLessThanOrEqual(start + length, file.text.length); } var text = getLocaleSpecificMessage(message); if (arguments.length > 4) { text = formatStringFromArgs(text, arguments, 4); } return { file: file, start: start, length: length, messageText: text, category: message.category, code: message.code, }; } ts.createFileDiagnostic = createFileDiagnostic; /* internal */ function formatMessage(_dummy, message) { var text = getLocaleSpecificMessage(message); if (arguments.length > 2) { text = formatStringFromArgs(text, arguments, 2); } return text; } ts.formatMessage = formatMessage; function createCompilerDiagnostic(message) { var text = getLocaleSpecificMessage(message); if (arguments.length > 1) { text = formatStringFromArgs(text, arguments, 1); } return { file: undefined, start: undefined, length: undefined, messageText: text, category: message.category, code: message.code }; } ts.createCompilerDiagnostic = createCompilerDiagnostic; function createCompilerDiagnosticFromMessageChain(chain) { return { file: undefined, start: undefined, length: undefined, code: chain.code, category: chain.category, messageText: chain.next ? chain : chain.messageText }; } ts.createCompilerDiagnosticFromMessageChain = createCompilerDiagnosticFromMessageChain; function chainDiagnosticMessages(details, message) { var text = getLocaleSpecificMessage(message); if (arguments.length > 2) { text = formatStringFromArgs(text, arguments, 2); } return { messageText: text, category: message.category, code: message.code, next: details }; } ts.chainDiagnosticMessages = chainDiagnosticMessages; function concatenateDiagnosticMessageChains(headChain, tailChain) { var lastChain = headChain; while (lastChain.next) { lastChain = lastChain.next; } lastChain.next = tailChain; return headChain; } ts.concatenateDiagnosticMessageChains = concatenateDiagnosticMessageChains; function equateValues(a, b) { return a === b; } ts.equateValues = equateValues; /** * Compare the equality of two strings using a case-sensitive ordinal comparison. * * Case-sensitive comparisons compare both strings one code-point at a time using the integer * value of each code-point after applying `toUpperCase` to each string. We always map both * strings to their upper-case form as some unicode characters do not properly round-trip to * lowercase (such as `ẞ` (German sharp capital s)). */ function equateStringsCaseInsensitive(a, b) { return a === b || a !== undefined && b !== undefined && a.toUpperCase() === b.toUpperCase(); } ts.equateStringsCaseInsensitive = equateStringsCaseInsensitive; /** * Compare the equality of two strings using a case-sensitive ordinal comparison. * * Case-sensitive comparisons compare both strings one code-point at a time using the * integer value of each code-point. */ function equateStringsCaseSensitive(a, b) { return equateValues(a, b); } ts.equateStringsCaseSensitive = equateStringsCaseSensitive; function compareComparableValues(a, b) { return a === b ? 0 /* EqualTo */ : a === undefined ? -1 /* LessThan */ : b === undefined ? 1 /* GreaterThan */ : a < b ? -1 /* LessThan */ : 1 /* GreaterThan */; } /** * Compare two numeric values for their order relative to each other. * To compare strings, use any of the `compareStrings` functions. */ function compareValues(a, b) { return compareComparableValues(a, b); } ts.compareValues = compareValues; /** * Compare two strings using a case-insensitive ordinal comparison. * * Ordinal comparisons are based on the difference between the unicode code points of both * strings. Characters with multiple unicode representations are considered unequal. Ordinal * comparisons provide predictable ordering, but place "a" after "B". * * Case-insensitive comparisons compare both strings one code-point at a time using the integer * value of each code-point after applying `toUpperCase` to each string. We always map both * strings to their upper-case form as some unicode characters do not properly round-trip to * lowercase (such as `ẞ` (German sharp capital s)). */ function compareStringsCaseInsensitive(a, b) { if (a === b) return 0 /* EqualTo */; if (a === undefined) return -1 /* LessThan */; if (b === undefined) return 1 /* GreaterThan */; a = a.toUpperCase(); b = b.toUpperCase(); return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */; } ts.compareStringsCaseInsensitive = compareStringsCaseInsensitive; /** * Compare two strings using a case-sensitive ordinal comparison. * * Ordinal comparisons are based on the difference between the unicode code points of both * strings. Characters with multiple unicode representations are considered unequal. Ordinal * comparisons provide predictable ordering, but place "a" after "B". * * Case-sensitive comparisons compare both strings one code-point at a time using the integer * value of each code-point. */ function compareStringsCaseSensitive(a, b) { return compareComparableValues(a, b); } ts.compareStringsCaseSensitive = compareStringsCaseSensitive; /** * Creates a string comparer for use with string collation in the UI. */ var createUIStringComparer = (function () { var defaultComparer; var enUSComparer; var stringComparerFactory = getStringComparerFactory(); return createStringComparer; function compareWithCallback(a, b, comparer) { if (a === b) return 0 /* EqualTo */; if (a === undefined) return -1 /* LessThan */; if (b === undefined) return 1 /* GreaterThan */; var value = comparer(a, b); return value < 0 ? -1 /* LessThan */ : value > 0 ? 1 /* GreaterThan */ : 0 /* EqualTo */; } function createIntlCollatorStringComparer(locale) { // Intl.Collator.prototype.compare is bound to the collator. See NOTE in // http://www.ecma-international.org/ecma-402/2.0/#sec-Intl.Collator.prototype.compare var comparer = new Intl.Collator(locale, { usage: "sort", sensitivity: "variant" }).compare; return function (a, b) { return compareWithCallback(a, b, comparer); }; } function createLocaleCompareStringComparer(locale) { // if the locale is not the default locale (`undefined`), use the fallback comparer. if (locale !== undefined) return createFallbackStringComparer(); return function (a, b) { return compareWithCallback(a, b, compareStrings); }; function compareStrings(a, b) { return a.localeCompare(b); } } function createFallbackStringComparer() { // An ordinal comparison puts "A" after "b", but for the UI we want "A" before "b". // We first sort case insensitively. So "Aaa" will come before "baa". // Then we sort case sensitively, so "aaa" will come before "Aaa". // // For case insensitive comparisons we always map both strings to their // upper-case form as some unicode characters do not properly round-trip to // lowercase (such as `ẞ` (German sharp capital s)). return function (a, b) { return compareWithCallback(a, b, compareDictionaryOrder); }; function compareDictionaryOrder(a, b) { return compareStrings(a.toUpperCase(), b.toUpperCase()) || compareStrings(a, b); } function compareStrings(a, b) { return a < b ? -1 /* LessThan */ : a > b ? 1 /* GreaterThan */ : 0 /* EqualTo */; } } function getStringComparerFactory() { // If the host supports Intl, we use it for comparisons using the default locale. if (typeof Intl === "object" && typeof Intl.Collator === "function") { return createIntlCollatorStringComparer; } // If the host does not support Intl, we fall back to localeCompare. // localeCompare in Node v0.10 is just an ordinal comparison, so don't use it. if (typeof String.prototype.localeCompare === "function" && typeof String.prototype.toLocaleUpperCase === "function" && "a".localeCompare("B") < 0) { return createLocaleCompareStringComparer; } // Otherwise, fall back to ordinal comparison: return createFallbackStringComparer; } function createStringComparer(locale) { // Hold onto common string comparers. This avoids constantly reallocating comparers during // tests. if (locale === undefined) { return defaultComparer || (defaultComparer = stringComparerFactory(locale)); } else if (locale === "en-US") { return enUSComparer || (enUSComparer = stringComparerFactory(locale)); } else { return stringComparerFactory(locale); } } })(); var uiComparerCaseSensitive; var uiLocale; function getUILocale() { return uiLocale; } ts.getUILocale = getUILocale; function setUILocale(value) { if (uiLocale !== value) { uiLocale = value; uiComparerCaseSensitive = undefined; } } ts.setUILocale = setUILocale; /** * Compare two strings in a using the case-sensitive sort behavior of the UI locale. * * Ordering is not predictable between different host locales, but is best for displaying * ordered data for UI presentation. Characters with multiple unicode representations may * be considered equal. * * Case-sensitive comparisons compare strings that differ in base characters, or * accents/diacritic marks, or case as unequal. */ function compareStringsCaseSensitiveUI(a, b) { var comparer = uiComparerCaseSensitive || (uiComparerCaseSensitive = createUIStringComparer(uiLocale)); return comparer(a, b); } ts.compareStringsCaseSensitiveUI = compareStringsCaseSensitiveUI; function compareProperties(a, b, key, comparer) { return a === b ? 0 /* EqualTo */ : a === undefined ? -1 /* LessThan */ : b === undefined ? 1 /* GreaterThan */ : comparer(a[key], b[key]); } ts.compareProperties = compareProperties; function getDiagnosticFileName(diagnostic) { return diagnostic.file ? diagnostic.file.fileName : undefined; } function compareDiagnostics(d1, d2) { return compareStringsCaseSensitive(getDiagnosticFileName(d1), getDiagnosticFileName(d2)) || compareValues(d1.start, d2.start) || compareValues(d1.length, d2.length) || compareValues(d1.code, d2.code) || compareMessageText(d1.messageText, d2.messageText) || 0 /* EqualTo */; } ts.compareDiagnostics = compareDiagnostics; function compareMessageText(text1, text2) { while (text1 && text2) { // We still have both chains. var string1 = isString(text1) ? text1 : text1.messageText; var string2 = isString(text2) ? text2 : text2.messageText; var res = compareStringsCaseSensitive(string1, string2); if (res) { return res; } text1 = isString(text1) ? undefined : text1.next; text2 = isString(text2) ? undefined : text2.next; } if (!text1 && !text2) { // if the chains are done, then these messages are the same. return 0 /* EqualTo */; } // We still have one chain remaining. The shorter chain should come first. return text1 ? 1 /* GreaterThan */ : -1 /* LessThan */; } function sortAndDeduplicateDiagnostics(diagnostics) { return sortAndDeduplicate(diagnostics, compareDiagnostics); } ts.sortAndDeduplicateDiagnostics = sortAndDeduplicateDiagnostics; 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; } // Per RFC 1738 'file' URI schema has the shape file:/// // if is omitted then it is assumed that host value is 'localhost', // however slash after the omitted is not removed. // file:///folder1/file1 - this is a correct URI // file://folder2/file2 - this is an incorrect URI if (path.lastIndexOf("file:///", 0) === 0) { return "file:///".length; } var idx = path.indexOf("://"); if (idx !== -1) { return idx + "://".length; } return 0; } ts.getRootLength = getRootLength; /** * Internally, we represent paths as strings with '/' as the directory separator. * When we make system calls (eg: LanguageServiceHost.getDirectory()), * we expect the host to correctly handle paths in our specified format. */ ts.directorySeparator = "/"; var directorySeparatorCharCode = 47 /* slash */; function getNormalizedParts(normalizedSlashedPath, rootLength) { var parts = normalizedSlashedPath.substr(rootLength).split(ts.directorySeparator); var normalized = []; for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { var part = parts_1[_i]; if (part !== ".") { if (part === ".." && normalized.length > 0 && lastOrUndefined(normalized) !== "..") { normalized.pop(); } else { // A part may be an empty string (which is 'falsy') if the path had consecutive slashes, // e.g. "path//file.ts". Drop these before re-joining the parts. if (part) { normalized.push(part); } } } } return normalized; } function normalizePath(path) { return normalizePathAndParts(path).path; } ts.normalizePath = normalizePath; function normalizePathAndParts(path) { path = normalizeSlashes(path); var rootLength = getRootLength(path); var root = path.substr(0, rootLength); var parts = getNormalizedParts(path, rootLength); if (parts.length) { var joinedParts = root + parts.join(ts.directorySeparator); return { path: pathEndsWithDirectorySeparator(path) ? joinedParts + ts.directorySeparator : joinedParts, parts: parts }; } else { return { path: root, parts: parts }; } } ts.normalizePathAndParts = normalizePathAndParts; /** A path ending with '/' refers to a directory only, never a file. */ function pathEndsWithDirectorySeparator(path) { return path.charCodeAt(path.length - 1) === directorySeparatorCharCode; } ts.pathEndsWithDirectorySeparator = pathEndsWithDirectorySeparator; function getDirectoryPath(path) { return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(ts.directorySeparator))); } ts.getDirectoryPath = getDirectoryPath; function isUrl(path) { return path && !isRootedDiskPath(path) && stringContains(path, "://"); } ts.isUrl = isUrl; function pathIsRelative(path) { return /^\.\.?($|[\\/])/.test(path); } ts.pathIsRelative = pathIsRelative; /** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */ function moduleHasNonRelativeName(moduleName) { return !ts.isExternalModuleNameRelative(moduleName); } ts.moduleHasNonRelativeName = moduleHasNonRelativeName; function getEmitScriptTarget(compilerOptions) { return compilerOptions.target || 0 /* ES3 */; } ts.getEmitScriptTarget = getEmitScriptTarget; function getEmitModuleKind(compilerOptions) { return typeof compilerOptions.module === "number" ? compilerOptions.module : getEmitScriptTarget(compilerOptions) >= 2 /* ES2015 */ ? ts.ModuleKind.ES2015 : ts.ModuleKind.CommonJS; } ts.getEmitModuleKind = getEmitModuleKind; function getEmitModuleResolutionKind(compilerOptions) { var moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { moduleResolution = getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic; } return moduleResolution; } ts.getEmitModuleResolutionKind = getEmitModuleResolutionKind; function getAllowSyntheticDefaultImports(compilerOptions) { var moduleKind = getEmitModuleKind(compilerOptions); return compilerOptions.allowSyntheticDefaultImports !== undefined ? compilerOptions.allowSyntheticDefaultImports : moduleKind === ts.ModuleKind.System; } ts.getAllowSyntheticDefaultImports = getAllowSyntheticDefaultImports; function getStrictOptionValue(compilerOptions, flag) { return compilerOptions[flag] === undefined ? compilerOptions.strict : compilerOptions[flag]; } ts.getStrictOptionValue = getStrictOptionValue; function hasZeroOrOneAsteriskCharacter(str) { var seenAsterisk = false; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) === 42 /* asterisk */) { if (!seenAsterisk) { seenAsterisk = true; } else { // have already seen asterisk return false; } } } return true; } ts.hasZeroOrOneAsteriskCharacter = hasZeroOrOneAsteriskCharacter; function isRootedDiskPath(path) { return path && getRootLength(path) !== 0; } ts.isRootedDiskPath = isRootedDiskPath; function convertToRelativePath(absoluteOrRelativePath, basePath, getCanonicalFileName) { return !isRootedDiskPath(absoluteOrRelativePath) ? absoluteOrRelativePath : getRelativePathToDirectoryOrUrl(basePath, absoluteOrRelativePath, basePath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); } ts.convertToRelativePath = convertToRelativePath; function normalizedPathComponents(path, rootLength) { var normalizedParts = getNormalizedParts(path, rootLength); return [path.substr(0, rootLength)].concat(normalizedParts); } function getNormalizedPathComponents(path, currentDirectory) { path = normalizeSlashes(path); var rootLength = getRootLength(path); if (rootLength === 0) { // If the path is not rooted it is relative to current directory path = combinePaths(normalizeSlashes(currentDirectory), path); rootLength = getRootLength(path); } return normalizedPathComponents(path, rootLength); } ts.getNormalizedPathComponents = getNormalizedPathComponents; function getNormalizedAbsolutePath(fileName, currentDirectory) { return getNormalizedPathFromPathComponents(getNormalizedPathComponents(fileName, currentDirectory)); } ts.getNormalizedAbsolutePath = getNormalizedAbsolutePath; function getNormalizedPathFromPathComponents(pathComponents) { if (pathComponents && pathComponents.length) { return pathComponents[0] + pathComponents.slice(1).join(ts.directorySeparator); } } ts.getNormalizedPathFromPathComponents = getNormalizedPathFromPathComponents; function getNormalizedPathComponentsOfUrl(url) { // Get root length of http://www.website.com/folder1/folder2/ // In this example the root is: http://www.website.com/ // normalized path components should be ["http://www.website.com/", "folder1", "folder2"] var urlLength = url.length; // Initial root length is http:// part var rootLength = url.indexOf("://") + "://".length; while (rootLength < urlLength) { // Consume all immediate slashes in the protocol // eg.initial rootlength is just file:// but it needs to consume another "/" in file:/// if (url.charCodeAt(rootLength) === 47 /* slash */) { rootLength++; } else { // non slash character means we continue proceeding to next component of root search break; } } // there are no parts after http:// just return current string as the pathComponent if (rootLength === urlLength) { return [url]; } // Find the index of "/" after website.com so the root can be http://www.website.com/ (from existing http://) var indexOfNextSlash = url.indexOf(ts.directorySeparator, rootLength); if (indexOfNextSlash !== -1) { // Found the "/" after the website.com so the root is length of http://www.website.com/ // and get components after the root normally like any other folder components rootLength = indexOfNextSlash + 1; return normalizedPathComponents(url, rootLength); } else { // Can't find the host assume the rest of the string as component // but make sure we append "/" to it as root is not joined using "/" // eg. if url passed in was http://website.com we want to use root as [http://website.com/] // so that other path manipulations will be correct and it can be merged with relative paths correctly return [url + ts.directorySeparator]; } } function getNormalizedPathOrUrlComponents(pathOrUrl, currentDirectory) { if (isUrl(pathOrUrl)) { return getNormalizedPathComponentsOfUrl(pathOrUrl); } else { return getNormalizedPathComponents(pathOrUrl, currentDirectory); } } function getRelativePathToDirectoryOrUrl(directoryPathOrUrl, relativeOrAbsolutePath, currentDirectory, getCanonicalFileName, isAbsolutePathAnUrl) { var pathComponents = getNormalizedPathOrUrlComponents(relativeOrAbsolutePath, currentDirectory); var directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory); if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") { // If the directory path given was of type test/cases/ then we really need components of directory to be only till its name // that is ["test", "cases", ""] needs to be actually ["test", "cases"] directoryComponents.pop(); } // Find the component that differs var joinStartIndex; for (joinStartIndex = 0; joinStartIndex < pathComponents.length && joinStartIndex < directoryComponents.length; joinStartIndex++) { if (getCanonicalFileName(directoryComponents[joinStartIndex]) !== getCanonicalFileName(pathComponents[joinStartIndex])) { break; } } // Get the relative path if (joinStartIndex) { var relativePath = ""; var relativePathComponents = pathComponents.slice(joinStartIndex, pathComponents.length); for (; joinStartIndex < directoryComponents.length; joinStartIndex++) { if (directoryComponents[joinStartIndex] !== "") { relativePath = relativePath + ".." + ts.directorySeparator; } } return relativePath + relativePathComponents.join(ts.directorySeparator); } // Cant find the relative path, get the absolute path var absolutePath = getNormalizedPathFromPathComponents(pathComponents); if (isAbsolutePathAnUrl && isRootedDiskPath(absolutePath)) { absolutePath = "file:///" + absolutePath; } return absolutePath; } ts.getRelativePathToDirectoryOrUrl = getRelativePathToDirectoryOrUrl; function getBaseFileName(path) { if (path === undefined) { return undefined; } var i = path.lastIndexOf(ts.directorySeparator); return i < 0 ? path : path.substring(i + 1); } ts.getBaseFileName = getBaseFileName; function combinePaths(path1, path2) { if (!(path1 && path1.length)) return path2; if (!(path2 && path2.length)) return path1; if (getRootLength(path2) !== 0) return path2; if (path1.charAt(path1.length - 1) === ts.directorySeparator) return path1 + path2; return path1 + ts.directorySeparator + path2; } ts.combinePaths = combinePaths; function removeTrailingDirectorySeparator(path) { if (path.charAt(path.length - 1) === ts.directorySeparator) { return path.substr(0, path.length - 1); } return path; } ts.removeTrailingDirectorySeparator = removeTrailingDirectorySeparator; /** * Adds a trailing directory separator to a path, if it does not already have one. * @param path The path. */ function ensureTrailingDirectorySeparator(path) { if (path.charAt(path.length - 1) !== ts.directorySeparator) { return path + ts.directorySeparator; } return path; } ts.ensureTrailingDirectorySeparator = ensureTrailingDirectorySeparator; function comparePaths(a, b, currentDirectory, ignoreCase) { if (a === b) return 0 /* EqualTo */; if (a === undefined) return -1 /* LessThan */; if (b === undefined) return 1 /* GreaterThan */; a = removeTrailingDirectorySeparator(a); b = removeTrailingDirectorySeparator(b); var aComponents = getNormalizedPathComponents(a, currentDirectory); var bComponents = getNormalizedPathComponents(b, currentDirectory); var sharedLength = Math.min(aComponents.length, bComponents.length); var comparer = ignoreCase ? compareStringsCaseInsensitive : compareStringsCaseSensitive; for (var i = 0; i < sharedLength; i++) { var result = comparer(aComponents[i], bComponents[i]); 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; } var equalityComparer = ignoreCase ? equateStringsCaseInsensitive : equateStringsCaseSensitive; for (var i = 0; i < parentComponents.length; i++) { if (!equalityComparer(parentComponents[i], childComponents[i])) { return false; } } return true; } ts.containsPath = containsPath; function startsWith(str, prefix) { return str.lastIndexOf(prefix, 0) === 0; } ts.startsWith = startsWith; function removePrefix(str, prefix) { return startsWith(str, prefix) ? str.substr(prefix.length) : str; } ts.removePrefix = removePrefix; function endsWith(str, suffix) { var expectedPos = str.length - suffix.length; return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos; } ts.endsWith = endsWith; function removeSuffix(str, suffix) { return endsWith(str, suffix) ? str.slice(0, str.length - suffix.length) : str; } ts.removeSuffix = removeSuffix; function stringContains(str, substring) { return str.indexOf(substring) !== -1; } ts.stringContains = stringContains; function hasExtension(fileName) { return stringContains(getBaseFileName(fileName), "."); } ts.hasExtension = hasExtension; function fileExtensionIs(path, extension) { return path.length > extension.length && endsWith(path, extension); } ts.fileExtensionIs = fileExtensionIs; function fileExtensionIsOneOf(path, extensions) { for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) { var extension = extensions_1[_i]; if (fileExtensionIs(path, extension)) { return true; } } return false; } ts.fileExtensionIsOneOf = fileExtensionIsOneOf; // Reserved characters, forces escaping of any non-word (or digit), non-whitespace character. // It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future // proof. var reservedCharacterPattern = /[^\w\s\/]/g; var wildcardCharCodes = [42 /* asterisk */, 63 /* question */]; ts.commonPackageFolders = ["node_modules", "bower_components", "jspm_packages"]; var implicitExcludePathRegexPattern = "(?!(" + ts.commonPackageFolders.join("|") + ")(/|$))"; var filesMatcher = { /** * Matches any single directory segment unless it is the last segment and a .min.js file * Breakdown: * [^./] # matches everything up to the first . character (excluding directory seperators) * (\\.(?!min\\.js$))? # matches . characters but not if they are part of the .min.js file extension */ singleAsteriskRegexFragment: "([^./]|(\\.(?!min\\.js$))?)*", /** * Regex for the ** wildcard. Matches any number of subdirectories. When used for including * files or directories, does not match subdirectories that start with a . character */ doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, filesMatcher.singleAsteriskRegexFragment); } }; var directoriesMatcher = { singleAsteriskRegexFragment: "[^/]*", /** * Regex for the ** wildcard. Matches any number of subdirectories. When used for including * files or directories, does not match subdirectories that start with a . character */ doubleAsteriskRegexFragment: "(/" + implicitExcludePathRegexPattern + "[^/.][^/]*)*?", replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment); } }; var excludeMatcher = { singleAsteriskRegexFragment: "[^/]*", doubleAsteriskRegexFragment: "(/.+?)?", replaceWildcardCharacter: function (match) { return replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment); } }; var wildcardMatchers = { files: filesMatcher, directories: directoriesMatcher, exclude: excludeMatcher }; function getRegularExpressionForWildcard(specs, basePath, usage) { var patterns = getRegularExpressionsForWildcards(specs, basePath, usage); if (!patterns || !patterns.length) { return undefined; } var pattern = patterns.map(function (pattern) { return "(" + pattern + ")"; }).join("|"); // If excluding, match "foo/bar/baz...", but if including, only allow "foo". var terminator = usage === "exclude" ? "($|/)" : "$"; return "^(" + pattern + ")" + terminator; } ts.getRegularExpressionForWildcard = getRegularExpressionForWildcard; function getRegularExpressionsForWildcards(specs, basePath, usage) { if (specs === undefined || specs.length === 0) { return undefined; } return flatMap(specs, function (spec) { return spec && getSubPatternFromSpec(spec, basePath, usage, wildcardMatchers[usage]); }); } /** * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension, * and does not contain any glob characters itself. */ function isImplicitGlob(lastPathComponent) { return !/[.*?]/.test(lastPathComponent); } ts.isImplicitGlob = isImplicitGlob; function getSubPatternFromSpec(spec, basePath, usage, _a) { var singleAsteriskRegexFragment = _a.singleAsteriskRegexFragment, doubleAsteriskRegexFragment = _a.doubleAsteriskRegexFragment, replaceWildcardCharacter = _a.replaceWildcardCharacter; var subpattern = ""; var hasRecursiveDirectoryWildcard = false; var hasWrittenComponent = false; var components = getNormalizedPathComponents(spec, basePath); var lastComponent = lastOrUndefined(components); if (usage !== "exclude" && lastComponent === "**") { return undefined; } // getNormalizedPathComponents includes the separator for the root component. // We need to remove to create our regex correctly. components[0] = removeTrailingDirectorySeparator(components[0]); if (isImplicitGlob(lastComponent)) { components.push("**", "*"); } var optionalCount = 0; for (var _i = 0, components_1 = components; _i < components_1.length; _i++) { var component = components_1[_i]; if (component === "**") { if (hasRecursiveDirectoryWildcard) { return undefined; } subpattern += doubleAsteriskRegexFragment; hasRecursiveDirectoryWildcard = true; } else { if (usage === "directories") { subpattern += "("; optionalCount++; } if (hasWrittenComponent) { subpattern += ts.directorySeparator; } if (usage !== "exclude") { var componentPattern = ""; // The * and ? wildcards should not match directories or files that start with . if they // appear first in a component. Dotted directories and files can be included explicitly // like so: **/.*/.* if (component.charCodeAt(0) === 42 /* asterisk */) { componentPattern += "([^./]" + singleAsteriskRegexFragment + ")?"; component = component.substr(1); } else if (component.charCodeAt(0) === 63 /* question */) { componentPattern += "[^./]"; component = component.substr(1); } componentPattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); // Patterns should not include subfolders like node_modules unless they are // explicitly included as part of the path. // // As an optimization, if the component pattern is the same as the component, // then there definitely were no wildcard characters and we do not need to // add the exclusion pattern. if (componentPattern !== component) { subpattern += implicitExcludePathRegexPattern; } subpattern += componentPattern; } else { subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter); } } hasWrittenComponent = true; } while (optionalCount > 0) { subpattern += ")?"; optionalCount--; } return subpattern; } function replaceWildcardCharacter(match, singleAsteriskRegexFragment) { return match === "*" ? singleAsteriskRegexFragment : match === "?" ? "[^/]" : "\\" + match; } function getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory) { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); var absolutePath = combinePaths(currentDirectory, path); return { includeFilePatterns: map(getRegularExpressionsForWildcards(includes, absolutePath, "files"), function (pattern) { return "^" + pattern + "$"; }), includeFilePattern: getRegularExpressionForWildcard(includes, absolutePath, "files"), includeDirectoryPattern: getRegularExpressionForWildcard(includes, absolutePath, "directories"), excludePattern: getRegularExpressionForWildcard(excludes, absolutePath, "exclude"), basePaths: getBasePaths(path, includes, useCaseSensitiveFileNames) }; } ts.getFileMatcherPatterns = getFileMatcherPatterns; function matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory, depth, getFileSystemEntries) { path = normalizePath(path); currentDirectory = normalizePath(currentDirectory); var comparer = useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive; var patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory); var regexFlag = useCaseSensitiveFileNames ? "" : "i"; var includeFileRegexes = patterns.includeFilePatterns && patterns.includeFilePatterns.map(function (pattern) { return new RegExp(pattern, regexFlag); }); var includeDirectoryRegex = patterns.includeDirectoryPattern && new RegExp(patterns.includeDirectoryPattern, regexFlag); var excludeRegex = patterns.excludePattern && new RegExp(patterns.excludePattern, regexFlag); // Associate an array of results with each include regex. This keeps results in order of the "include" order. // If there are no "includes", then just put everything in results[0]. var results = includeFileRegexes ? includeFileRegexes.map(function () { return []; }) : [[]]; for (var _i = 0, _a = patterns.basePaths; _i < _a.length; _i++) { var basePath = _a[_i]; visitDirectory(basePath, combinePaths(currentDirectory, basePath), depth); } return flatten(results); function visitDirectory(path, absolutePath, depth) { var _a = getFileSystemEntries(path), files = _a.files, directories = _a.directories; var _loop_1 = function (current) { var name = combinePaths(path, current); var absoluteName = combinePaths(absolutePath, current); if (extensions && !fileExtensionIsOneOf(name, extensions)) return "continue"; if (excludeRegex && excludeRegex.test(absoluteName)) return "continue"; if (!includeFileRegexes) { results[0].push(name); } else { var includeIndex = findIndex(includeFileRegexes, function (re) { return re.test(absoluteName); }); if (includeIndex !== -1) { results[includeIndex].push(name); } } }; for (var _i = 0, _b = sort(files, comparer); _i < _b.length; _i++) { var current = _b[_i]; _loop_1(current); } if (depth !== undefined) { depth--; if (depth === 0) { return; } } for (var _c = 0, _d = sort(directories, comparer); _c < _d.length; _c++) { var current = _d[_c]; var name = combinePaths(path, current); var absoluteName = combinePaths(absolutePath, current); if ((!includeDirectoryRegex || includeDirectoryRegex.test(absoluteName)) && (!excludeRegex || !excludeRegex.test(absoluteName))) { visitDirectory(name, absoluteName, depth); } } } } ts.matchFiles = matchFiles; /** * Computes the unique non-wildcard base paths amongst the provided include patterns. */ function getBasePaths(path, includes, useCaseSensitiveFileNames) { // Storage for our results in the form of literal paths (e.g. the paths as written by the user). var basePaths = [path]; if (includes) { // Storage for literal base paths amongst the include patterns. var includeBasePaths = []; for (var _i = 0, includes_1 = includes; _i < includes_1.length; _i++) { var include = includes_1[_i]; // We also need to check the relative paths by converting them to absolute and normalizing // in case they escape the base path (e.g "..\somedirectory") var absolute = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include)); // Append the literal and canonical candidate base paths. includeBasePaths.push(getIncludeBasePath(absolute)); } // Sort the offsets array using either the literal or canonical path representations. includeBasePaths.sort(useCaseSensitiveFileNames ? compareStringsCaseSensitive : compareStringsCaseInsensitive); var _loop_2 = function (includeBasePath) { if (ts.every(basePaths, function (basePath) { return !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames); })) { basePaths.push(includeBasePath); } }; // Iterate over each include base path and include unique base paths that are not a // subpath of an existing base path for (var _a = 0, includeBasePaths_1 = includeBasePaths; _a < includeBasePaths_1.length; _a++) { var includeBasePath = includeBasePaths_1[_a]; _loop_2(includeBasePath); } } return basePaths; } function getIncludeBasePath(absolute) { var wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes); if (wildcardOffset < 0) { // No "*" or "?" in the path return !hasExtension(absolute) ? absolute : removeTrailingDirectorySeparator(getDirectoryPath(absolute)); } return absolute.substring(0, absolute.lastIndexOf(ts.directorySeparator, wildcardOffset)); } function ensureScriptKind(fileName, scriptKind) { // Using scriptKind as a condition handles both: // - 'scriptKind' is unspecified and thus it is `undefined` // - 'scriptKind' is set and it is `Unknown` (0) // If the 'scriptKind' is 'undefined' or 'Unknown' then we attempt // to get the ScriptKind from the file name. If it cannot be resolved // from the file name then the default 'TS' script kind is returned. return scriptKind || getScriptKindFromFileName(fileName) || 3 /* TS */; } ts.ensureScriptKind = ensureScriptKind; function getScriptKindFromFileName(fileName) { var ext = fileName.substr(fileName.lastIndexOf(".")); switch (ext.toLowerCase()) { case ".js" /* Js */: return 1 /* JS */; case ".jsx" /* Jsx */: return 2 /* JSX */; case ".ts" /* Ts */: return 3 /* TS */; case ".tsx" /* Tsx */: return 4 /* TSX */; case ".json" /* Json */: return 6 /* JSON */; default: return 0 /* Unknown */; } } ts.getScriptKindFromFileName = getScriptKindFromFileName; /** * List of supported extensions in order of file resolution precedence. */ ts.supportedTypeScriptExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".d.ts" /* Dts */]; /** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */ ts.supportedTypescriptExtensionsForExtractExtension = [".d.ts" /* Dts */, ".ts" /* Ts */, ".tsx" /* Tsx */]; ts.supportedJavascriptExtensions = [".js" /* Js */, ".jsx" /* Jsx */]; var allSupportedExtensions = ts.supportedTypeScriptExtensions.concat(ts.supportedJavascriptExtensions); function getSupportedExtensions(options, extraFileExtensions) { var needAllExtensions = options && options.allowJs; if (!extraFileExtensions || extraFileExtensions.length === 0 || !needAllExtensions) { return needAllExtensions ? allSupportedExtensions : ts.supportedTypeScriptExtensions; } return deduplicate(allSupportedExtensions.concat(extraFileExtensions.map(function (e) { return e.extension; })), equateStringsCaseSensitive, compareStringsCaseSensitive); } ts.getSupportedExtensions = getSupportedExtensions; function hasJavaScriptFileExtension(fileName) { return forEach(ts.supportedJavascriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); }); } ts.hasJavaScriptFileExtension = hasJavaScriptFileExtension; function hasTypeScriptFileExtension(fileName) { return forEach(ts.supportedTypeScriptExtensions, function (extension) { return fileExtensionIs(fileName, extension); }); } ts.hasTypeScriptFileExtension = hasTypeScriptFileExtension; function isSupportedSourceFileName(fileName, compilerOptions, extraFileExtensions) { if (!fileName) { return false; } for (var _i = 0, _a = getSupportedExtensions(compilerOptions, extraFileExtensions); _i < _a.length; _i++) { var extension = _a[_i]; if (fileExtensionIs(fileName, extension)) { return true; } } return false; } ts.isSupportedSourceFileName = isSupportedSourceFileName; /** * Extension boundaries by priority. Lower numbers indicate higher priorities, and are * aligned to the offset of the highest priority extension in the * allSupportedExtensions array. */ var ExtensionPriority; (function (ExtensionPriority) { ExtensionPriority[ExtensionPriority["TypeScriptFiles"] = 0] = "TypeScriptFiles"; ExtensionPriority[ExtensionPriority["DeclarationAndJavaScriptFiles"] = 2] = "DeclarationAndJavaScriptFiles"; ExtensionPriority[ExtensionPriority["Highest"] = 0] = "Highest"; ExtensionPriority[ExtensionPriority["Lowest"] = 2] = "Lowest"; })(ExtensionPriority = ts.ExtensionPriority || (ts.ExtensionPriority = {})); function getExtensionPriority(path, supportedExtensions) { for (var i = supportedExtensions.length - 1; i >= 0; i--) { if (fileExtensionIs(path, supportedExtensions[i])) { return adjustExtensionPriority(i, supportedExtensions); } } // If its not in the list of supported extensions, this is likely a // TypeScript file with a non-ts extension return 0 /* Highest */; } ts.getExtensionPriority = getExtensionPriority; /** * Adjusts an extension priority to be the highest priority within the same range. */ function adjustExtensionPriority(extensionPriority, supportedExtensions) { if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) { return 0 /* TypeScriptFiles */; } else if (extensionPriority < supportedExtensions.length) { return 2 /* DeclarationAndJavaScriptFiles */; } else { return supportedExtensions.length; } } ts.adjustExtensionPriority = adjustExtensionPriority; /** * Gets the next lowest extension priority for a given priority. */ function getNextLowestExtensionPriority(extensionPriority, supportedExtensions) { if (extensionPriority < 2 /* DeclarationAndJavaScriptFiles */) { return 2 /* DeclarationAndJavaScriptFiles */; } else { return supportedExtensions.length; } } ts.getNextLowestExtensionPriority = getNextLowestExtensionPriority; var extensionsToRemove = [".d.ts" /* Dts */, ".ts" /* Ts */, ".js" /* Js */, ".tsx" /* Tsx */, ".jsx" /* Jsx */]; function removeFileExtension(path) { for (var _i = 0, extensionsToRemove_1 = extensionsToRemove; _i < extensionsToRemove_1.length; _i++) { var ext = extensionsToRemove_1[_i]; var extensionless = tryRemoveExtension(path, ext); if (extensionless !== undefined) { return extensionless; } } return path; } ts.removeFileExtension = removeFileExtension; function tryRemoveExtension(path, extension) { return fileExtensionIs(path, extension) ? removeExtension(path, extension) : undefined; } ts.tryRemoveExtension = tryRemoveExtension; function removeExtension(path, extension) { return path.substring(0, path.length - extension.length); } ts.removeExtension = removeExtension; function changeExtension(path, newExtension) { return (removeFileExtension(path) + newExtension); } ts.changeExtension = changeExtension; /** * Takes a string like "jquery-min.4.2.3" and returns "jquery" */ function removeMinAndVersionNumbers(fileName) { // Match a "." or "-" followed by a version number or 'min' at the end of the name var trailingMinOrVersion = /[.-]((min)|(\d+(\.\d+)*))$/; // The "min" or version may both be present, in either order, so try applying the above twice. return fileName.replace(trailingMinOrVersion, "").replace(trailingMinOrVersion, ""); } ts.removeMinAndVersionNumbers = removeMinAndVersionNumbers; function Symbol(flags, name) { this.flags = flags; this.escapedName = name; this.declarations = undefined; } function Type(checker, flags) { this.flags = flags; if (Debug.isDebugging) { this.checker = checker; } } function Signature() { } // tslint:disable-line no-empty function Node(kind, pos, end) { this.id = 0; this.kind = kind; this.pos = pos; this.end = end; this.flags = 0 /* None */; this.modifierFlagsCache = 0 /* None */; this.transformFlags = 0 /* None */; this.parent = undefined; this.original = undefined; } function SourceMapSource(fileName, text, skipTrivia) { this.fileName = fileName; this.text = text; this.skipTrivia = skipTrivia || (function (pos) { return pos; }); } ts.objectAllocator = { getNodeConstructor: function () { return Node; }, getTokenConstructor: function () { return Node; }, getIdentifierConstructor: function () { return Node; }, getSourceFileConstructor: function () { return Node; }, getSymbolConstructor: function () { return Symbol; }, getTypeConstructor: function () { return Type; }, getSignatureConstructor: function () { return Signature; }, getSourceMapSourceConstructor: function () { return SourceMapSource; }, }; var AssertionLevel; (function (AssertionLevel) { AssertionLevel[AssertionLevel["None"] = 0] = "None"; AssertionLevel[AssertionLevel["Normal"] = 1] = "Normal"; AssertionLevel[AssertionLevel["Aggressive"] = 2] = "Aggressive"; AssertionLevel[AssertionLevel["VeryAggressive"] = 3] = "VeryAggressive"; })(AssertionLevel = ts.AssertionLevel || (ts.AssertionLevel = {})); var Debug; (function (Debug) { Debug.currentAssertionLevel = 0 /* None */; Debug.isDebugging = false; function shouldAssert(level) { return Debug.currentAssertionLevel >= level; } Debug.shouldAssert = shouldAssert; function assert(expression, message, verboseDebugInfo, stackCrawlMark) { if (!expression) { if (verboseDebugInfo) { message += "\r\nVerbose Debug Information: " + (typeof verboseDebugInfo === "string" ? verboseDebugInfo : verboseDebugInfo()); } fail(message ? "False expression: " + message : "False expression.", stackCrawlMark || assert); } } Debug.assert = assert; function assertEqual(a, b, msg, msg2) { if (a !== b) { var message = msg ? msg2 ? msg + " " + msg2 : msg : ""; fail("Expected " + a + " === " + b + ". " + message); } } Debug.assertEqual = assertEqual; function assertLessThan(a, b, msg) { if (a >= b) { fail("Expected " + a + " < " + b + ". " + (msg || "")); } } Debug.assertLessThan = assertLessThan; function assertLessThanOrEqual(a, b) { if (a > b) { fail("Expected " + a + " <= " + b); } } Debug.assertLessThanOrEqual = assertLessThanOrEqual; function assertGreaterThanOrEqual(a, b) { if (a < b) { fail("Expected " + a + " >= " + b); } } Debug.assertGreaterThanOrEqual = assertGreaterThanOrEqual; function fail(message, stackCrawlMark) { debugger; var e = new Error(message ? "Debug Failure. " + message : "Debug Failure."); if (Error.captureStackTrace) { Error.captureStackTrace(e, stackCrawlMark || fail); } throw e; } Debug.fail = fail; function assertNever(member, message, stackCrawlMark) { return fail(message || "Illegal value: " + member, stackCrawlMark || assertNever); } Debug.assertNever = assertNever; function getFunctionName(func) { if (typeof func !== "function") { return ""; } else if (func.hasOwnProperty("name")) { return func.name; } else { var text = Function.prototype.toString.call(func); var match = /^function\s+([\w\$]+)\s*\(/.exec(text); return match ? match[1] : ""; } } Debug.getFunctionName = getFunctionName; })(Debug = ts.Debug || (ts.Debug = {})); /** Remove an item from an array, moving everything to its right one space left. */ function orderedRemoveItem(array, item) { for (var i = 0; i < array.length; i++) { if (array[i] === item) { orderedRemoveItemAt(array, i); return true; } } return false; } ts.orderedRemoveItem = orderedRemoveItem; /** Remove an item by index from an array, moving everything to its right one space left. */ function orderedRemoveItemAt(array, index) { // This seems to be faster than either `array.splice(i, 1)` or `array.copyWithin(i, i+ 1)`. for (var i = index; i < array.length - 1; i++) { array[i] = array[i + 1]; } array.pop(); } ts.orderedRemoveItemAt = orderedRemoveItemAt; function unorderedRemoveItemAt(array, index) { // Fill in the "hole" left at `index`. array[index] = array[array.length - 1]; array.pop(); } ts.unorderedRemoveItemAt = unorderedRemoveItemAt; /** Remove the *first* occurrence of `item` from the array. */ function unorderedRemoveItem(array, item) { unorderedRemoveFirstItemWhere(array, function (element) { return element === item; }); } ts.unorderedRemoveItem = unorderedRemoveItem; /** Remove the *first* element satisfying `predicate`. */ function unorderedRemoveFirstItemWhere(array, predicate) { for (var i = 0; i < array.length; i++) { if (predicate(array[i])) { unorderedRemoveItemAt(array, i); break; } } } function createGetCanonicalFileName(useCaseSensitiveFileNames) { return useCaseSensitiveFileNames ? (function (fileName) { return fileName; }) : (function (fileName) { return fileName.toLowerCase(); }); } ts.createGetCanonicalFileName = createGetCanonicalFileName; /** * patternStrings contains both pattern strings (containing "*") and regular strings. * Return an exact match if possible, or a pattern match, or undefined. * (These are verified by verifyCompilerOptions to have 0 or 1 "*" characters.) */ function matchPatternOrExact(patternStrings, candidate) { var patterns = []; for (var _i = 0, patternStrings_1 = patternStrings; _i < patternStrings_1.length; _i++) { var patternString = patternStrings_1[_i]; var pattern = tryParsePattern(patternString); if (pattern) { patterns.push(pattern); } else if (patternString === candidate) { // pattern was matched as is - no need to search further return patternString; } } return findBestPatternMatch(patterns, function (_) { return _; }, candidate); } ts.matchPatternOrExact = matchPatternOrExact; function patternText(_a) { var prefix = _a.prefix, suffix = _a.suffix; return prefix + "*" + suffix; } ts.patternText = patternText; /** * Given that candidate matches pattern, returns the text matching the '*'. * E.g.: matchedText(tryParsePattern("foo*baz"), "foobarbaz") === "bar" */ function matchedText(pattern, candidate) { Debug.assert(isPatternMatch(pattern, candidate)); return candidate.substr(pattern.prefix.length, candidate.length - pattern.suffix.length); } ts.matchedText = matchedText; /** Return the object corresponding to the best pattern to match `candidate`. */ function findBestPatternMatch(values, getPattern, candidate) { var matchedValue = undefined; // use length of prefix as betterness criteria var longestMatchPrefixLength = -1; for (var _i = 0, values_1 = values; _i < values_1.length; _i++) { var v = values_1[_i]; var pattern = getPattern(v); if (isPatternMatch(pattern, candidate) && pattern.prefix.length > longestMatchPrefixLength) { longestMatchPrefixLength = pattern.prefix.length; matchedValue = v; } } return matchedValue; } ts.findBestPatternMatch = findBestPatternMatch; function isPatternMatch(_a, candidate) { var prefix = _a.prefix, suffix = _a.suffix; return candidate.length >= prefix.length + suffix.length && startsWith(candidate, prefix) && endsWith(candidate, suffix); } function tryParsePattern(pattern) { // This should be verified outside of here and a proper error thrown. Debug.assert(hasZeroOrOneAsteriskCharacter(pattern)); var indexOfStar = pattern.indexOf("*"); return indexOfStar === -1 ? undefined : { prefix: pattern.substr(0, indexOfStar), suffix: pattern.substr(indexOfStar + 1) }; } ts.tryParsePattern = tryParsePattern; function positionIsSynthesized(pos) { // This is a fast way of testing the following conditions: // pos === undefined || pos === null || isNaN(pos) || pos < 0; return !(pos >= 0); } ts.positionIsSynthesized = positionIsSynthesized; /** True if an extension is one of the supported TypeScript extensions. */ function extensionIsTypeScript(ext) { return ext === ".ts" /* Ts */ || ext === ".tsx" /* Tsx */ || ext === ".d.ts" /* Dts */; } ts.extensionIsTypeScript = extensionIsTypeScript; /** * Gets the extension from a path. * Path must have a valid extension. */ function extensionFromPath(path) { var ext = tryGetExtensionFromPath(path); if (ext !== undefined) { return ext; } Debug.fail("File " + path + " has unknown extension."); } ts.extensionFromPath = extensionFromPath; function isAnySupportedFileExtension(path) { return tryGetExtensionFromPath(path) !== undefined; } ts.isAnySupportedFileExtension = isAnySupportedFileExtension; function tryGetExtensionFromPath(path) { return find(ts.supportedTypescriptExtensionsForExtractExtension, function (e) { return fileExtensionIs(path, e); }) || find(ts.supportedJavascriptExtensions, function (e) { return fileExtensionIs(path, e); }); } ts.tryGetExtensionFromPath = tryGetExtensionFromPath; // Retrieves any string from the final "." onwards from a base file name. // Unlike extensionFromPath, which throws an exception on unrecognized extensions. function getAnyExtensionFromPath(path) { var baseFileName = getBaseFileName(path); var extensionIndex = baseFileName.lastIndexOf("."); if (extensionIndex >= 0) { return baseFileName.substring(extensionIndex); } } ts.getAnyExtensionFromPath = getAnyExtensionFromPath; function isCheckJsEnabledForFile(sourceFile, compilerOptions) { return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; } ts.isCheckJsEnabledForFile = isCheckJsEnabledForFile; function and(f, g) { return function (arg) { return f(arg) && g(arg); }; } ts.and = and; function assertTypeIsNever(_) { } // tslint:disable-line no-empty ts.assertTypeIsNever = assertTypeIsNever; function createCachedDirectoryStructureHost(host) { var cachedReadDirectoryResult = createMap(); var getCurrentDirectory = memoize(function () { return host.getCurrentDirectory(); }); var getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames); return { useCaseSensitiveFileNames: host.useCaseSensitiveFileNames, newLine: host.newLine, readFile: function (path, encoding) { return host.readFile(path, encoding); }, write: function (s) { return host.write(s); }, writeFile: writeFile, fileExists: fileExists, directoryExists: directoryExists, createDirectory: createDirectory, getCurrentDirectory: getCurrentDirectory, getDirectories: getDirectories, readDirectory: readDirectory, addOrDeleteFileOrDirectory: addOrDeleteFileOrDirectory, addOrDeleteFile: addOrDeleteFile, clearCache: clearCache, exit: function (code) { return host.exit(code); } }; function toPath(fileName) { return ts.toPath(fileName, getCurrentDirectory(), getCanonicalFileName); } function getCachedFileSystemEntries(rootDirPath) { return cachedReadDirectoryResult.get(rootDirPath); } function getCachedFileSystemEntriesForBaseDir(path) { return getCachedFileSystemEntries(getDirectoryPath(path)); } function getBaseNameOfFileName(fileName) { return getBaseFileName(normalizePath(fileName)); } function createCachedFileSystemEntries(rootDir, rootDirPath) { var resultFromHost = { files: map(host.readDirectory(rootDir, /*extensions*/ undefined, /*exclude*/ undefined, /*include*/ ["*.*"]), getBaseNameOfFileName) || [], directories: host.getDirectories(rootDir) || [] }; cachedReadDirectoryResult.set(rootDirPath, resultFromHost); return resultFromHost; } /** * If the readDirectory result was already cached, it returns that * Otherwise gets result from host and caches it. * The host request is done under try catch block to avoid caching incorrect result */ function tryReadDirectory(rootDir, rootDirPath) { var cachedResult = getCachedFileSystemEntries(rootDirPath); if (cachedResult) { return cachedResult; } try { return createCachedFileSystemEntries(rootDir, rootDirPath); } catch (_e) { // If there is exception to read directories, dont cache the result and direct the calls to host Debug.assert(!cachedReadDirectoryResult.has(rootDirPath)); return undefined; } } function fileNameEqual(name1, name2) { return getCanonicalFileName(name1) === getCanonicalFileName(name2); } function hasEntry(entries, name) { return some(entries, function (file) { return fileNameEqual(file, name); }); } function updateFileSystemEntry(entries, baseName, isValid) { if (hasEntry(entries, baseName)) { if (!isValid) { return filterMutate(entries, function (entry) { return !fileNameEqual(entry, baseName); }); } } else if (isValid) { return entries.push(baseName); } } function writeFile(fileName, data, writeByteOrderMark) { var path = toPath(fileName); var result = getCachedFileSystemEntriesForBaseDir(path); if (result) { updateFilesOfFileSystemEntry(result, getBaseNameOfFileName(fileName), /*fileExists*/ true); } return host.writeFile(fileName, data, writeByteOrderMark); } function fileExists(fileName) { var path = toPath(fileName); var result = getCachedFileSystemEntriesForBaseDir(path); return result && hasEntry(result.files, getBaseNameOfFileName(fileName)) || host.fileExists(fileName); } function directoryExists(dirPath) { var path = toPath(dirPath); return cachedReadDirectoryResult.has(path) || host.directoryExists(dirPath); } function createDirectory(dirPath) { var path = toPath(dirPath); var result = getCachedFileSystemEntriesForBaseDir(path); var baseFileName = getBaseNameOfFileName(dirPath); if (result) { updateFileSystemEntry(result.directories, baseFileName, /*isValid*/ true); } host.createDirectory(dirPath); } function getDirectories(rootDir) { var rootDirPath = toPath(rootDir); var result = tryReadDirectory(rootDir, rootDirPath); if (result) { return result.directories.slice(); } return host.getDirectories(rootDir); } function readDirectory(rootDir, extensions, excludes, includes, depth) { var rootDirPath = toPath(rootDir); var result = tryReadDirectory(rootDir, rootDirPath); if (result) { return matchFiles(rootDir, extensions, excludes, includes, host.useCaseSensitiveFileNames, getCurrentDirectory(), depth, getFileSystemEntries); } return host.readDirectory(rootDir, extensions, excludes, includes, depth); function getFileSystemEntries(dir) { var path = toPath(dir); if (path === rootDirPath) { return result; } return getCachedFileSystemEntries(path) || createCachedFileSystemEntries(dir, path); } } function addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath) { var existingResult = getCachedFileSystemEntries(fileOrDirectoryPath); if (existingResult) { // Just clear the cache for now // For now just clear the cache, since this could mean that multiple level entries might need to be re-evaluated clearCache(); } else { // This was earlier a file (hence not in cached directory contents) // or we never cached the directory containing it var parentResult = getCachedFileSystemEntriesForBaseDir(fileOrDirectoryPath); if (parentResult) { var baseName = getBaseNameOfFileName(fileOrDirectory); if (parentResult) { var fsQueryResult = { fileExists: host.fileExists(fileOrDirectoryPath), directoryExists: host.directoryExists(fileOrDirectoryPath) }; if (fsQueryResult.directoryExists || hasEntry(parentResult.directories, baseName)) { // Folder added or removed, clear the cache instead of updating the folder and its structure clearCache(); } else { // No need to update the directory structure, just files updateFilesOfFileSystemEntry(parentResult, baseName, fsQueryResult.fileExists); } return fsQueryResult; } } } } function addOrDeleteFile(fileName, filePath, eventKind) { if (eventKind === ts.FileWatcherEventKind.Changed) { return; } var parentResult = getCachedFileSystemEntriesForBaseDir(filePath); if (parentResult) { updateFilesOfFileSystemEntry(parentResult, getBaseNameOfFileName(fileName), eventKind === ts.FileWatcherEventKind.Created); } } function updateFilesOfFileSystemEntry(parentResult, baseName, fileExists) { updateFileSystemEntry(parentResult.files, baseName, fileExists); } function clearCache() { cachedReadDirectoryResult.clear(); } } ts.createCachedDirectoryStructureHost = createCachedDirectoryStructureHost; })(ts || (ts = {})); /// var ts; (function (ts) { /** * Set a high stack trace limit to provide more information in case of an error. * Called for command-line and server use cases. * Not called if TypeScript is used as a library. */ /* @internal */ function setStackTraceLimit() { if (Error.stackTraceLimit < 100) { Error.stackTraceLimit = 100; } } ts.setStackTraceLimit = setStackTraceLimit; var FileWatcherEventKind; (function (FileWatcherEventKind) { FileWatcherEventKind[FileWatcherEventKind["Created"] = 0] = "Created"; FileWatcherEventKind[FileWatcherEventKind["Changed"] = 1] = "Changed"; FileWatcherEventKind[FileWatcherEventKind["Deleted"] = 2] = "Deleted"; })(FileWatcherEventKind = ts.FileWatcherEventKind || (ts.FileWatcherEventKind = {})); function getNodeMajorVersion() { if (typeof process === "undefined") { return undefined; } var version = process.version; if (!version) { return undefined; } var dot = version.indexOf("."); if (dot === -1) { return undefined; } return parseInt(version.substring(1, dot)); } ts.getNodeMajorVersion = getNodeMajorVersion; ts.sys = (function () { var utf8ByteOrderMark = "\u00EF\u00BB\u00BF"; function getNodeSystem() { var _fs = require("fs"); var _path = require("path"); var _os = require("os"); var _crypto = require("crypto"); var useNonPollingWatchers = process.env.TSC_NONPOLLING_WATCHER; function createWatchedFileSet() { var dirWatchers = ts.createMap(); // One file can have multiple watchers var fileWatcherCallbacks = ts.createMultiMap(); return { addFile: addFile, removeFile: removeFile }; function reduceDirWatcherRefCountForFile(fileName) { var dirName = ts.getDirectoryPath(fileName); var watcher = dirWatchers.get(dirName); if (watcher) { watcher.referenceCount -= 1; if (watcher.referenceCount <= 0) { watcher.close(); dirWatchers.delete(dirName); } } } function addDirWatcher(dirPath) { var watcher = dirWatchers.get(dirPath); if (watcher) { watcher.referenceCount += 1; return; } watcher = fsWatchDirectory(dirPath || ".", function (eventName, relativeFileName) { return fileEventHandler(eventName, relativeFileName, dirPath); }); watcher.referenceCount = 1; dirWatchers.set(dirPath, watcher); return; } function addFileWatcherCallback(filePath, callback) { fileWatcherCallbacks.add(filePath, callback); } function addFile(fileName, callback) { addFileWatcherCallback(fileName, callback); addDirWatcher(ts.getDirectoryPath(fileName)); return { fileName: fileName, callback: callback }; } function removeFile(watchedFile) { removeFileWatcherCallback(watchedFile.fileName, watchedFile.callback); reduceDirWatcherRefCountForFile(watchedFile.fileName); } function removeFileWatcherCallback(filePath, callback) { fileWatcherCallbacks.remove(filePath, callback); } function fileEventHandler(eventName, relativeFileName, baseDirPath) { // When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined" var fileName = !ts.isString(relativeFileName) ? undefined : ts.getNormalizedAbsolutePath(relativeFileName, baseDirPath); // Some applications save a working file via rename operations if ((eventName === "change" || eventName === "rename")) { var callbacks = fileWatcherCallbacks.get(fileName); if (callbacks) { for (var _i = 0, callbacks_1 = callbacks; _i < callbacks_1.length; _i++) { var fileCallback = callbacks_1[_i]; fileCallback(fileName, FileWatcherEventKind.Changed); } } } } } var watchedFileSet = createWatchedFileSet(); var nodeVersion = getNodeMajorVersion(); var isNode4OrLater = nodeVersion >= 4; function isFileSystemCaseSensitive() { // win32\win64 are case insensitive platforms if (platform === "win32" || platform === "win64") { return false; } // If this file exists under a different case, we must be case-insensitve. return !fileExists(swapCase(__filename)); } /** Convert all lowercase chars to uppercase, and vice-versa */ function swapCase(s) { return s.replace(/\w/g, function (ch) { var up = ch.toUpperCase(); return ch === up ? ch.toLowerCase() : up; }); } var platform = _os.platform(); var useCaseSensitiveFileNames = isFileSystemCaseSensitive(); function fsWatchFile(fileName, callback, pollingInterval) { _fs.watchFile(fileName, { persistent: true, interval: pollingInterval || 250 }, fileChanged); return { close: function () { return _fs.unwatchFile(fileName, fileChanged); } }; function fileChanged(curr, prev) { var isCurrZero = +curr.mtime === 0; var isPrevZero = +prev.mtime === 0; var created = !isCurrZero && isPrevZero; var deleted = isCurrZero && !isPrevZero; var eventKind = created ? FileWatcherEventKind.Created : deleted ? FileWatcherEventKind.Deleted : FileWatcherEventKind.Changed; if (eventKind === FileWatcherEventKind.Changed && +curr.mtime <= +prev.mtime) { return; } callback(fileName, eventKind); } } function fsWatchDirectory(directoryName, callback, recursive) { var options; /** Watcher for the directory depending on whether it is missing or present */ var watcher = !directoryExists(directoryName) ? watchMissingDirectory() : watchPresentDirectory(); return { close: function () { // Close the watcher (either existing directory watcher or missing directory watcher) watcher.close(); } }; /** * Watch the directory that is currently present * and when the watched directory is deleted, switch to missing directory watcher */ function watchPresentDirectory() { // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643) if (options === undefined) { if (isNode4OrLater && (process.platform === "win32" || process.platform === "darwin")) { options = { persistent: true, recursive: !!recursive }; } else { options = { persistent: true }; } } var dirWatcher = _fs.watch(directoryName, options, callback); dirWatcher.on("error", function () { if (!directoryExists(directoryName)) { // Deleting directory watcher = watchMissingDirectory(); // Call the callback for current directory callback("rename", ""); } }); return dirWatcher; } /** * Watch the directory that is missing * and switch to existing directory when the directory is created */ function watchMissingDirectory() { return fsWatchFile(directoryName, function (_fileName, eventKind) { if (eventKind === FileWatcherEventKind.Created && directoryExists(directoryName)) { watcher.close(); watcher = watchPresentDirectory(); // Call the callback for current directory // For now it could be callback for the inner directory creation, // but just return current directory, better than current no-op callback("rename", ""); } }); } } function readFile(fileName, _encoding) { if (!fileExists(fileName)) { return undefined; } var buffer = _fs.readFileSync(fileName); var len = buffer.length; if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) { // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js, // flip all byte pairs and treat as little endian. len &= ~1; // Round down to a multiple of 2 for (var i = 0; i < len; i += 2) { var temp = buffer[i]; buffer[i] = buffer[i + 1]; buffer[i + 1] = temp; } return buffer.toString("utf16le", 2); } if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) { // Little endian UTF-16 byte order mark detected return buffer.toString("utf16le", 2); } if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) { // UTF-8 byte order mark detected return buffer.toString("utf8", 3); } // Default is UTF-8 with no byte order mark return buffer.toString("utf8"); } function writeFile(fileName, data, writeByteOrderMark) { // If a BOM is required, emit one if (writeByteOrderMark) { data = utf8ByteOrderMark + data; } var fd; try { fd = _fs.openSync(fileName, "w"); _fs.writeSync(fd, data, /*position*/ undefined, "utf8"); } finally { if (fd !== undefined) { _fs.closeSync(fd); } } } function getAccessibleFileSystemEntries(path) { try { var entries = _fs.readdirSync(path || ".").sort(); var files = []; var directories = []; for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { var entry = entries_1[_i]; // This is necessary because on some file system node fails to exclude // "." and "..". See https://github.com/nodejs/node/issues/4002 if (entry === "." || entry === "..") { continue; } var name = ts.combinePaths(path, entry); var stat = void 0; try { stat = _fs.statSync(name); } catch (e) { continue; } if (stat.isFile()) { files.push(entry); } else if (stat.isDirectory()) { directories.push(entry); } } return { files: files, directories: directories }; } catch (e) { return { files: [], directories: [] }; } } function readDirectory(path, extensions, excludes, includes, depth) { return ts.matchFiles(path, extensions, excludes, includes, useCaseSensitiveFileNames, process.cwd(), depth, getAccessibleFileSystemEntries); } var FileSystemEntryKind; (function (FileSystemEntryKind) { FileSystemEntryKind[FileSystemEntryKind["File"] = 0] = "File"; FileSystemEntryKind[FileSystemEntryKind["Directory"] = 1] = "Directory"; })(FileSystemEntryKind || (FileSystemEntryKind = {})); function fileSystemEntryExists(path, entryKind) { try { var stat = _fs.statSync(path); switch (entryKind) { case 0 /* File */: return stat.isFile(); case 1 /* Directory */: return stat.isDirectory(); } } catch (e) { return false; } } function fileExists(path) { return fileSystemEntryExists(path, 0 /* File */); } function directoryExists(path) { return fileSystemEntryExists(path, 1 /* Directory */); } function getDirectories(path) { return ts.filter(_fs.readdirSync(path), function (dir) { return fileSystemEntryExists(ts.combinePaths(path, dir), 1 /* Directory */); }); } var nodeSystem = { args: process.argv.slice(2), newLine: _os.EOL, useCaseSensitiveFileNames: useCaseSensitiveFileNames, write: function (s) { process.stdout.write(s); }, readFile: readFile, writeFile: writeFile, watchFile: function (fileName, callback, pollingInterval) { if (useNonPollingWatchers) { var watchedFile_1 = watchedFileSet.addFile(fileName, callback); return { close: function () { return watchedFileSet.removeFile(watchedFile_1); } }; } else { return fsWatchFile(fileName, callback, pollingInterval); } }, watchDirectory: function (directoryName, callback, recursive) { // Node 4.0 `fs.watch` function supports the "recursive" option on both OSX and Windows // (ref: https://github.com/nodejs/node/pull/2649 and https://github.com/Microsoft/TypeScript/issues/4643) return fsWatchDirectory(directoryName, function (eventName, relativeFileName) { // In watchDirectory we only care about adding and removing files (when event name is // "rename"); changes made within files are handled by corresponding fileWatchers (when // event name is "change") if (eventName === "rename") { // When deleting a file, the passed baseFileName is null callback(!relativeFileName ? relativeFileName : ts.normalizePath(ts.combinePaths(directoryName, relativeFileName))); } }, recursive); }, resolvePath: function (path) { return _path.resolve(path); }, fileExists: fileExists, directoryExists: directoryExists, createDirectory: function (directoryName) { if (!nodeSystem.directoryExists(directoryName)) { _fs.mkdirSync(directoryName); } }, getExecutingFilePath: function () { return __filename; }, getCurrentDirectory: function () { return process.cwd(); }, getDirectories: getDirectories, getEnvironmentVariable: function (name) { return process.env[name] || ""; }, readDirectory: readDirectory, getModifiedTime: function (path) { try { return _fs.statSync(path).mtime; } catch (e) { return undefined; } }, createHash: function (data) { var hash = _crypto.createHash("md5"); hash.update(data); return hash.digest("hex"); }, getMemoryUsage: function () { if (global.gc) { global.gc(); } return process.memoryUsage().heapUsed; }, getFileSize: function (path) { try { var stat = _fs.statSync(path); if (stat.isFile()) { return stat.size; } } catch (_a) { } return 0; }, exit: function (exitCode) { process.exit(exitCode); }, realpath: function (path) { return _fs.realpathSync(path); }, debugMode: ts.some(process.execArgv, function (arg) { return /^--(inspect|debug)(-brk)?(=\d+)?$/i.test(arg); }), tryEnableSourceMapsForHost: function () { try { require("source-map-support").install(); } catch (_a) { // Could not enable source maps. } }, setTimeout: setTimeout, clearTimeout: clearTimeout }; return nodeSystem; } function getChakraSystem() { var realpath = ChakraHost.realpath && (function (path) { return ChakraHost.realpath(path); }); return { newLine: ChakraHost.newLine || "\r\n", args: ChakraHost.args, useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames, write: ChakraHost.echo, readFile: function (path, _encoding) { // encoding is automatically handled by the implementation in ChakraHost return ChakraHost.readFile(path); }, writeFile: function (path, data, writeByteOrderMark) { // If a BOM is required, emit one if (writeByteOrderMark) { data = utf8ByteOrderMark + data; } ChakraHost.writeFile(path, data); }, resolvePath: ChakraHost.resolvePath, fileExists: ChakraHost.fileExists, directoryExists: ChakraHost.directoryExists, createDirectory: ChakraHost.createDirectory, getExecutingFilePath: function () { return ChakraHost.executingFile; }, getCurrentDirectory: function () { return ChakraHost.currentDirectory; }, getDirectories: ChakraHost.getDirectories, getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (function () { return ""; }), readDirectory: function (path, extensions, excludes, includes, _depth) { var pattern = ts.getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory); return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern); }, exit: ChakraHost.quit, realpath: realpath }; } function recursiveCreateDirectory(directoryPath, sys) { var basePath = ts.getDirectoryPath(directoryPath); var shouldCreateParent = basePath !== "" && directoryPath !== basePath && !sys.directoryExists(basePath); if (shouldCreateParent) { recursiveCreateDirectory(basePath, sys); } if (shouldCreateParent || !sys.directoryExists(directoryPath)) { sys.createDirectory(directoryPath); } } var sys; if (typeof ChakraHost !== "undefined") { sys = getChakraSystem(); } else if (typeof process !== "undefined" && process.nextTick && !process.browser && typeof require !== "undefined") { // process and process.nextTick checks if current environment is node-like // process.browser check excludes webpack and browserify sys = getNodeSystem(); } if (sys) { // patch writefile to create folder before writing the file var originalWriteFile_1 = sys.writeFile; sys.writeFile = function (path, data, writeBom) { var directoryPath = ts.getDirectoryPath(ts.normalizeSlashes(path)); if (directoryPath && !sys.directoryExists(directoryPath)) { recursiveCreateDirectory(directoryPath, sys); } originalWriteFile_1.call(sys, path, data, writeBom); }; } return sys; })(); if (ts.sys && ts.sys.getEnvironmentVariable) { ts.Debug.currentAssertionLevel = /^development$/i.test(ts.sys.getEnvironmentVariable("NODE_ENV")) ? 1 /* Normal */ : 0 /* None */; } if (ts.sys && ts.sys.debugMode) { ts.Debug.isDebugging = true; } })(ts || (ts = {})); // // generated from './diagnosticInformationMap.generated.ts' by '../../scripts/processDiagnosticMessages.js' /// /* @internal */ var ts; (function (ts) { function diag(code, category, key, message) { return { code: code, category: category, key: key, message: message }; } // tslint:disable-next-line variable-name ts.Diagnostics = { Unterminated_string_literal: diag(1002, ts.DiagnosticCategory.Error, "Unterminated_string_literal_1002", "Unterminated string literal."), Identifier_expected: diag(1003, ts.DiagnosticCategory.Error, "Identifier_expected_1003", "Identifier expected."), _0_expected: diag(1005, ts.DiagnosticCategory.Error, "_0_expected_1005", "'{0}' expected."), A_file_cannot_have_a_reference_to_itself: diag(1006, ts.DiagnosticCategory.Error, "A_file_cannot_have_a_reference_to_itself_1006", "A file cannot have a reference to itself."), Trailing_comma_not_allowed: diag(1009, ts.DiagnosticCategory.Error, "Trailing_comma_not_allowed_1009", "Trailing comma not allowed."), Asterisk_Slash_expected: diag(1010, ts.DiagnosticCategory.Error, "Asterisk_Slash_expected_1010", "'*/' expected."), Unexpected_token: diag(1012, ts.DiagnosticCategory.Error, "Unexpected_token_1012", "Unexpected token."), A_rest_parameter_must_be_last_in_a_parameter_list: diag(1014, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_last_in_a_parameter_list_1014", "A rest parameter must be last in a parameter list."), Parameter_cannot_have_question_mark_and_initializer: diag(1015, ts.DiagnosticCategory.Error, "Parameter_cannot_have_question_mark_and_initializer_1015", "Parameter cannot have question mark and initializer."), A_required_parameter_cannot_follow_an_optional_parameter: diag(1016, ts.DiagnosticCategory.Error, "A_required_parameter_cannot_follow_an_optional_parameter_1016", "A required parameter cannot follow an optional parameter."), An_index_signature_cannot_have_a_rest_parameter: diag(1017, ts.DiagnosticCategory.Error, "An_index_signature_cannot_have_a_rest_parameter_1017", "An index signature cannot have a rest parameter."), An_index_signature_parameter_cannot_have_an_accessibility_modifier: diag(1018, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_accessibility_modifier_1018", "An index signature parameter cannot have an accessibility modifier."), An_index_signature_parameter_cannot_have_a_question_mark: diag(1019, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_a_question_mark_1019", "An index signature parameter cannot have a question mark."), An_index_signature_parameter_cannot_have_an_initializer: diag(1020, ts.DiagnosticCategory.Error, "An_index_signature_parameter_cannot_have_an_initializer_1020", "An index signature parameter cannot have an initializer."), An_index_signature_must_have_a_type_annotation: diag(1021, ts.DiagnosticCategory.Error, "An_index_signature_must_have_a_type_annotation_1021", "An index signature must have a type annotation."), An_index_signature_parameter_must_have_a_type_annotation: diag(1022, ts.DiagnosticCategory.Error, "An_index_signature_parameter_must_have_a_type_annotation_1022", "An index signature parameter must have a type annotation."), An_index_signature_parameter_type_must_be_string_or_number: diag(1023, ts.DiagnosticCategory.Error, "An_index_signature_parameter_type_must_be_string_or_number_1023", "An index signature parameter type must be 'string' or 'number'."), readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature: diag(1024, ts.DiagnosticCategory.Error, "readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature_1024", "'readonly' modifier can only appear on a property declaration or index signature."), Accessibility_modifier_already_seen: diag(1028, ts.DiagnosticCategory.Error, "Accessibility_modifier_already_seen_1028", "Accessibility modifier already seen."), _0_modifier_must_precede_1_modifier: diag(1029, ts.DiagnosticCategory.Error, "_0_modifier_must_precede_1_modifier_1029", "'{0}' modifier must precede '{1}' modifier."), _0_modifier_already_seen: diag(1030, ts.DiagnosticCategory.Error, "_0_modifier_already_seen_1030", "'{0}' modifier already seen."), _0_modifier_cannot_appear_on_a_class_element: diag(1031, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_class_element_1031", "'{0}' modifier cannot appear on a class element."), super_must_be_followed_by_an_argument_list_or_member_access: diag(1034, ts.DiagnosticCategory.Error, "super_must_be_followed_by_an_argument_list_or_member_access_1034", "'super' must be followed by an argument list or member access."), Only_ambient_modules_can_use_quoted_names: diag(1035, ts.DiagnosticCategory.Error, "Only_ambient_modules_can_use_quoted_names_1035", "Only ambient modules can use quoted names."), Statements_are_not_allowed_in_ambient_contexts: diag(1036, ts.DiagnosticCategory.Error, "Statements_are_not_allowed_in_ambient_contexts_1036", "Statements are not allowed in ambient contexts."), A_declare_modifier_cannot_be_used_in_an_already_ambient_context: diag(1038, ts.DiagnosticCategory.Error, "A_declare_modifier_cannot_be_used_in_an_already_ambient_context_1038", "A 'declare' modifier cannot be used in an already ambient context."), Initializers_are_not_allowed_in_ambient_contexts: diag(1039, ts.DiagnosticCategory.Error, "Initializers_are_not_allowed_in_ambient_contexts_1039", "Initializers are not allowed in ambient contexts."), _0_modifier_cannot_be_used_in_an_ambient_context: diag(1040, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_in_an_ambient_context_1040", "'{0}' modifier cannot be used in an ambient context."), _0_modifier_cannot_be_used_with_a_class_declaration: diag(1041, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_a_class_declaration_1041", "'{0}' modifier cannot be used with a class declaration."), _0_modifier_cannot_be_used_here: diag(1042, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_here_1042", "'{0}' modifier cannot be used here."), _0_modifier_cannot_appear_on_a_data_property: diag(1043, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_data_property_1043", "'{0}' modifier cannot appear on a data property."), _0_modifier_cannot_appear_on_a_module_or_namespace_element: diag(1044, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_module_or_namespace_element_1044", "'{0}' modifier cannot appear on a module or namespace element."), A_0_modifier_cannot_be_used_with_an_interface_declaration: diag(1045, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_interface_declaration_1045", "A '{0}' modifier cannot be used with an interface declaration."), A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: diag(1046, ts.DiagnosticCategory.Error, "A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file_1046", "A 'declare' modifier is required for a top level declaration in a .d.ts file."), A_rest_parameter_cannot_be_optional: diag(1047, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_be_optional_1047", "A rest parameter cannot be optional."), A_rest_parameter_cannot_have_an_initializer: diag(1048, ts.DiagnosticCategory.Error, "A_rest_parameter_cannot_have_an_initializer_1048", "A rest parameter cannot have an initializer."), A_set_accessor_must_have_exactly_one_parameter: diag(1049, ts.DiagnosticCategory.Error, "A_set_accessor_must_have_exactly_one_parameter_1049", "A 'set' accessor must have exactly one parameter."), A_set_accessor_cannot_have_an_optional_parameter: diag(1051, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_an_optional_parameter_1051", "A 'set' accessor cannot have an optional parameter."), A_set_accessor_parameter_cannot_have_an_initializer: diag(1052, ts.DiagnosticCategory.Error, "A_set_accessor_parameter_cannot_have_an_initializer_1052", "A 'set' accessor parameter cannot have an initializer."), A_set_accessor_cannot_have_rest_parameter: diag(1053, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_rest_parameter_1053", "A 'set' accessor cannot have rest parameter."), A_get_accessor_cannot_have_parameters: diag(1054, ts.DiagnosticCategory.Error, "A_get_accessor_cannot_have_parameters_1054", "A 'get' accessor cannot have parameters."), Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value: diag(1055, ts.DiagnosticCategory.Error, "Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Prom_1055", "Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value."), Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: diag(1056, ts.DiagnosticCategory.Error, "Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher_1056", "Accessors are only available when targeting ECMAScript 5 and higher."), An_async_function_or_method_must_have_a_valid_awaitable_return_type: diag(1057, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_have_a_valid_awaitable_return_type_1057", "An async function or method must have a valid awaitable return type."), The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1058, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_t_1058", "The return type of an async function must either be a valid promise or must not contain a callable 'then' member."), A_promise_must_have_a_then_method: diag(1059, ts.DiagnosticCategory.Error, "A_promise_must_have_a_then_method_1059", "A promise must have a 'then' method."), The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback: diag(1060, ts.DiagnosticCategory.Error, "The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback_1060", "The first parameter of the 'then' method of a promise must be a callback."), Enum_member_must_have_initializer: diag(1061, ts.DiagnosticCategory.Error, "Enum_member_must_have_initializer_1061", "Enum member must have initializer."), Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: diag(1062, ts.DiagnosticCategory.Error, "Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method_1062", "Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method."), An_export_assignment_cannot_be_used_in_a_namespace: diag(1063, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_namespace_1063", "An export assignment cannot be used in a namespace."), The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type: diag(1064, ts.DiagnosticCategory.Error, "The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type_1064", "The return type of an async function or method must be the global Promise type."), In_ambient_enum_declarations_member_initializer_must_be_constant_expression: diag(1066, ts.DiagnosticCategory.Error, "In_ambient_enum_declarations_member_initializer_must_be_constant_expression_1066", "In ambient enum declarations member initializer must be constant expression."), Unexpected_token_A_constructor_method_accessor_or_property_was_expected: diag(1068, ts.DiagnosticCategory.Error, "Unexpected_token_A_constructor_method_accessor_or_property_was_expected_1068", "Unexpected token. A constructor, method, accessor, or property was expected."), _0_modifier_cannot_appear_on_a_type_member: diag(1070, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_type_member_1070", "'{0}' modifier cannot appear on a type member."), _0_modifier_cannot_appear_on_an_index_signature: diag(1071, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_an_index_signature_1071", "'{0}' modifier cannot appear on an index signature."), A_0_modifier_cannot_be_used_with_an_import_declaration: diag(1079, ts.DiagnosticCategory.Error, "A_0_modifier_cannot_be_used_with_an_import_declaration_1079", "A '{0}' modifier cannot be used with an import declaration."), Invalid_reference_directive_syntax: diag(1084, ts.DiagnosticCategory.Error, "Invalid_reference_directive_syntax_1084", "Invalid 'reference' directive syntax."), Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0: diag(1085, ts.DiagnosticCategory.Error, "Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0_1085", "Octal literals are not available when targeting ECMAScript 5 and higher. Use the syntax '{0}'."), An_accessor_cannot_be_declared_in_an_ambient_context: diag(1086, ts.DiagnosticCategory.Error, "An_accessor_cannot_be_declared_in_an_ambient_context_1086", "An accessor cannot be declared in an ambient context."), _0_modifier_cannot_appear_on_a_constructor_declaration: diag(1089, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_constructor_declaration_1089", "'{0}' modifier cannot appear on a constructor declaration."), _0_modifier_cannot_appear_on_a_parameter: diag(1090, ts.DiagnosticCategory.Error, "_0_modifier_cannot_appear_on_a_parameter_1090", "'{0}' modifier cannot appear on a parameter."), Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement: diag(1091, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_in_statement_1091", "Only a single variable declaration is allowed in a 'for...in' statement."), Type_parameters_cannot_appear_on_a_constructor_declaration: diag(1092, ts.DiagnosticCategory.Error, "Type_parameters_cannot_appear_on_a_constructor_declaration_1092", "Type parameters cannot appear on a constructor declaration."), Type_annotation_cannot_appear_on_a_constructor_declaration: diag(1093, ts.DiagnosticCategory.Error, "Type_annotation_cannot_appear_on_a_constructor_declaration_1093", "Type annotation cannot appear on a constructor declaration."), An_accessor_cannot_have_type_parameters: diag(1094, ts.DiagnosticCategory.Error, "An_accessor_cannot_have_type_parameters_1094", "An accessor cannot have type parameters."), A_set_accessor_cannot_have_a_return_type_annotation: diag(1095, ts.DiagnosticCategory.Error, "A_set_accessor_cannot_have_a_return_type_annotation_1095", "A 'set' accessor cannot have a return type annotation."), An_index_signature_must_have_exactly_one_parameter: diag(1096, ts.DiagnosticCategory.Error, "An_index_signature_must_have_exactly_one_parameter_1096", "An index signature must have exactly one parameter."), _0_list_cannot_be_empty: diag(1097, ts.DiagnosticCategory.Error, "_0_list_cannot_be_empty_1097", "'{0}' list cannot be empty."), Type_parameter_list_cannot_be_empty: diag(1098, ts.DiagnosticCategory.Error, "Type_parameter_list_cannot_be_empty_1098", "Type parameter list cannot be empty."), Type_argument_list_cannot_be_empty: diag(1099, ts.DiagnosticCategory.Error, "Type_argument_list_cannot_be_empty_1099", "Type argument list cannot be empty."), Invalid_use_of_0_in_strict_mode: diag(1100, ts.DiagnosticCategory.Error, "Invalid_use_of_0_in_strict_mode_1100", "Invalid use of '{0}' in strict mode."), with_statements_are_not_allowed_in_strict_mode: diag(1101, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_strict_mode_1101", "'with' statements are not allowed in strict mode."), delete_cannot_be_called_on_an_identifier_in_strict_mode: diag(1102, ts.DiagnosticCategory.Error, "delete_cannot_be_called_on_an_identifier_in_strict_mode_1102", "'delete' cannot be called on an identifier in strict mode."), A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator: diag(1103, ts.DiagnosticCategory.Error, "A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator_1103", "A 'for-await-of' statement is only allowed within an async function or async generator."), A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement: diag(1104, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement_1104", "A 'continue' statement can only be used within an enclosing iteration statement."), A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement: diag(1105, ts.DiagnosticCategory.Error, "A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement_1105", "A 'break' statement can only be used within an enclosing iteration or switch statement."), Jump_target_cannot_cross_function_boundary: diag(1107, ts.DiagnosticCategory.Error, "Jump_target_cannot_cross_function_boundary_1107", "Jump target cannot cross function boundary."), A_return_statement_can_only_be_used_within_a_function_body: diag(1108, ts.DiagnosticCategory.Error, "A_return_statement_can_only_be_used_within_a_function_body_1108", "A 'return' statement can only be used within a function body."), Expression_expected: diag(1109, ts.DiagnosticCategory.Error, "Expression_expected_1109", "Expression expected."), Type_expected: diag(1110, ts.DiagnosticCategory.Error, "Type_expected_1110", "Type expected."), A_default_clause_cannot_appear_more_than_once_in_a_switch_statement: diag(1113, ts.DiagnosticCategory.Error, "A_default_clause_cannot_appear_more_than_once_in_a_switch_statement_1113", "A 'default' clause cannot appear more than once in a 'switch' statement."), Duplicate_label_0: diag(1114, ts.DiagnosticCategory.Error, "Duplicate_label_0_1114", "Duplicate label '{0}'."), A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement: diag(1115, ts.DiagnosticCategory.Error, "A_continue_statement_can_only_jump_to_a_label_of_an_enclosing_iteration_statement_1115", "A 'continue' statement can only jump to a label of an enclosing iteration statement."), A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement: diag(1116, ts.DiagnosticCategory.Error, "A_break_statement_can_only_jump_to_a_label_of_an_enclosing_statement_1116", "A 'break' statement can only jump to a label of an enclosing statement."), An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode: diag(1117, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode_1117", "An object literal cannot have multiple properties with the same name in strict mode."), An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name: diag(1118, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name_1118", "An object literal cannot have multiple get/set accessors with the same name."), An_object_literal_cannot_have_property_and_accessor_with_the_same_name: diag(1119, ts.DiagnosticCategory.Error, "An_object_literal_cannot_have_property_and_accessor_with_the_same_name_1119", "An object literal cannot have property and accessor with the same name."), An_export_assignment_cannot_have_modifiers: diag(1120, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_have_modifiers_1120", "An export assignment cannot have modifiers."), Octal_literals_are_not_allowed_in_strict_mode: diag(1121, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_strict_mode_1121", "Octal literals are not allowed in strict mode."), A_tuple_type_element_list_cannot_be_empty: diag(1122, ts.DiagnosticCategory.Error, "A_tuple_type_element_list_cannot_be_empty_1122", "A tuple type element list cannot be empty."), Variable_declaration_list_cannot_be_empty: diag(1123, ts.DiagnosticCategory.Error, "Variable_declaration_list_cannot_be_empty_1123", "Variable declaration list cannot be empty."), Digit_expected: diag(1124, ts.DiagnosticCategory.Error, "Digit_expected_1124", "Digit expected."), Hexadecimal_digit_expected: diag(1125, ts.DiagnosticCategory.Error, "Hexadecimal_digit_expected_1125", "Hexadecimal digit expected."), Unexpected_end_of_text: diag(1126, ts.DiagnosticCategory.Error, "Unexpected_end_of_text_1126", "Unexpected end of text."), Invalid_character: diag(1127, ts.DiagnosticCategory.Error, "Invalid_character_1127", "Invalid character."), Declaration_or_statement_expected: diag(1128, ts.DiagnosticCategory.Error, "Declaration_or_statement_expected_1128", "Declaration or statement expected."), Statement_expected: diag(1129, ts.DiagnosticCategory.Error, "Statement_expected_1129", "Statement expected."), case_or_default_expected: diag(1130, ts.DiagnosticCategory.Error, "case_or_default_expected_1130", "'case' or 'default' expected."), Property_or_signature_expected: diag(1131, ts.DiagnosticCategory.Error, "Property_or_signature_expected_1131", "Property or signature expected."), Enum_member_expected: diag(1132, ts.DiagnosticCategory.Error, "Enum_member_expected_1132", "Enum member expected."), Variable_declaration_expected: diag(1134, ts.DiagnosticCategory.Error, "Variable_declaration_expected_1134", "Variable declaration expected."), Argument_expression_expected: diag(1135, ts.DiagnosticCategory.Error, "Argument_expression_expected_1135", "Argument expression expected."), Property_assignment_expected: diag(1136, ts.DiagnosticCategory.Error, "Property_assignment_expected_1136", "Property assignment expected."), Expression_or_comma_expected: diag(1137, ts.DiagnosticCategory.Error, "Expression_or_comma_expected_1137", "Expression or comma expected."), Parameter_declaration_expected: diag(1138, ts.DiagnosticCategory.Error, "Parameter_declaration_expected_1138", "Parameter declaration expected."), Type_parameter_declaration_expected: diag(1139, ts.DiagnosticCategory.Error, "Type_parameter_declaration_expected_1139", "Type parameter declaration expected."), Type_argument_expected: diag(1140, ts.DiagnosticCategory.Error, "Type_argument_expected_1140", "Type argument expected."), String_literal_expected: diag(1141, ts.DiagnosticCategory.Error, "String_literal_expected_1141", "String literal expected."), Line_break_not_permitted_here: diag(1142, ts.DiagnosticCategory.Error, "Line_break_not_permitted_here_1142", "Line break not permitted here."), or_expected: diag(1144, ts.DiagnosticCategory.Error, "or_expected_1144", "'{' or ';' expected."), Declaration_expected: diag(1146, ts.DiagnosticCategory.Error, "Declaration_expected_1146", "Declaration expected."), Import_declarations_in_a_namespace_cannot_reference_a_module: diag(1147, ts.DiagnosticCategory.Error, "Import_declarations_in_a_namespace_cannot_reference_a_module_1147", "Import declarations in a namespace cannot reference a module."), Cannot_use_imports_exports_or_module_augmentations_when_module_is_none: diag(1148, ts.DiagnosticCategory.Error, "Cannot_use_imports_exports_or_module_augmentations_when_module_is_none_1148", "Cannot use imports, exports, or module augmentations when '--module' is 'none'."), File_name_0_differs_from_already_included_file_name_1_only_in_casing: diag(1149, ts.DiagnosticCategory.Error, "File_name_0_differs_from_already_included_file_name_1_only_in_casing_1149", "File name '{0}' differs from already included file name '{1}' only in casing."), new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead: diag(1150, ts.DiagnosticCategory.Error, "new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead_1150", "'new T[]' cannot be used to create an array. Use 'new Array()' instead."), const_declarations_must_be_initialized: diag(1155, ts.DiagnosticCategory.Error, "const_declarations_must_be_initialized_1155", "'const' declarations must be initialized."), const_declarations_can_only_be_declared_inside_a_block: diag(1156, ts.DiagnosticCategory.Error, "const_declarations_can_only_be_declared_inside_a_block_1156", "'const' declarations can only be declared inside a block."), let_declarations_can_only_be_declared_inside_a_block: diag(1157, ts.DiagnosticCategory.Error, "let_declarations_can_only_be_declared_inside_a_block_1157", "'let' declarations can only be declared inside a block."), Unterminated_template_literal: diag(1160, ts.DiagnosticCategory.Error, "Unterminated_template_literal_1160", "Unterminated template literal."), Unterminated_regular_expression_literal: diag(1161, ts.DiagnosticCategory.Error, "Unterminated_regular_expression_literal_1161", "Unterminated regular expression literal."), An_object_member_cannot_be_declared_optional: diag(1162, ts.DiagnosticCategory.Error, "An_object_member_cannot_be_declared_optional_1162", "An object member cannot be declared optional."), A_yield_expression_is_only_allowed_in_a_generator_body: diag(1163, ts.DiagnosticCategory.Error, "A_yield_expression_is_only_allowed_in_a_generator_body_1163", "A 'yield' expression is only allowed in a generator body."), Computed_property_names_are_not_allowed_in_enums: diag(1164, ts.DiagnosticCategory.Error, "Computed_property_names_are_not_allowed_in_enums_1164", "Computed property names are not allowed in enums."), A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1165, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_t_1165", "A computed property name in an ambient context must refer to an expression whose type is a literal type or a 'unique symbol' type."), A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1166, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_1166", "A computed property name in a class property declaration must refer to an expression whose type is a literal type or a 'unique symbol' type."), A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1168, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_ty_1168", "A computed property name in a method overload must refer to an expression whose type is a literal type or a 'unique symbol' type."), A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1169, ts.DiagnosticCategory.Error, "A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_1169", "A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type."), A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type: diag(1170, ts.DiagnosticCategory.Error, "A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type__1170", "A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type."), A_comma_expression_is_not_allowed_in_a_computed_property_name: diag(1171, ts.DiagnosticCategory.Error, "A_comma_expression_is_not_allowed_in_a_computed_property_name_1171", "A comma expression is not allowed in a computed property name."), extends_clause_already_seen: diag(1172, ts.DiagnosticCategory.Error, "extends_clause_already_seen_1172", "'extends' clause already seen."), extends_clause_must_precede_implements_clause: diag(1173, ts.DiagnosticCategory.Error, "extends_clause_must_precede_implements_clause_1173", "'extends' clause must precede 'implements' clause."), Classes_can_only_extend_a_single_class: diag(1174, ts.DiagnosticCategory.Error, "Classes_can_only_extend_a_single_class_1174", "Classes can only extend a single class."), implements_clause_already_seen: diag(1175, ts.DiagnosticCategory.Error, "implements_clause_already_seen_1175", "'implements' clause already seen."), Interface_declaration_cannot_have_implements_clause: diag(1176, ts.DiagnosticCategory.Error, "Interface_declaration_cannot_have_implements_clause_1176", "Interface declaration cannot have 'implements' clause."), Binary_digit_expected: diag(1177, ts.DiagnosticCategory.Error, "Binary_digit_expected_1177", "Binary digit expected."), Octal_digit_expected: diag(1178, ts.DiagnosticCategory.Error, "Octal_digit_expected_1178", "Octal digit expected."), Unexpected_token_expected: diag(1179, ts.DiagnosticCategory.Error, "Unexpected_token_expected_1179", "Unexpected token. '{' expected."), Property_destructuring_pattern_expected: diag(1180, ts.DiagnosticCategory.Error, "Property_destructuring_pattern_expected_1180", "Property destructuring pattern expected."), Array_element_destructuring_pattern_expected: diag(1181, ts.DiagnosticCategory.Error, "Array_element_destructuring_pattern_expected_1181", "Array element destructuring pattern expected."), A_destructuring_declaration_must_have_an_initializer: diag(1182, ts.DiagnosticCategory.Error, "A_destructuring_declaration_must_have_an_initializer_1182", "A destructuring declaration must have an initializer."), An_implementation_cannot_be_declared_in_ambient_contexts: diag(1183, ts.DiagnosticCategory.Error, "An_implementation_cannot_be_declared_in_ambient_contexts_1183", "An implementation cannot be declared in ambient contexts."), Modifiers_cannot_appear_here: diag(1184, ts.DiagnosticCategory.Error, "Modifiers_cannot_appear_here_1184", "Modifiers cannot appear here."), Merge_conflict_marker_encountered: diag(1185, ts.DiagnosticCategory.Error, "Merge_conflict_marker_encountered_1185", "Merge conflict marker encountered."), A_rest_element_cannot_have_an_initializer: diag(1186, ts.DiagnosticCategory.Error, "A_rest_element_cannot_have_an_initializer_1186", "A rest element cannot have an initializer."), A_parameter_property_may_not_be_declared_using_a_binding_pattern: diag(1187, ts.DiagnosticCategory.Error, "A_parameter_property_may_not_be_declared_using_a_binding_pattern_1187", "A parameter property may not be declared using a binding pattern."), Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement: diag(1188, ts.DiagnosticCategory.Error, "Only_a_single_variable_declaration_is_allowed_in_a_for_of_statement_1188", "Only a single variable declaration is allowed in a 'for...of' statement."), The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer: diag(1189, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_in_statement_cannot_have_an_initializer_1189", "The variable declaration of a 'for...in' statement cannot have an initializer."), The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer: diag(1190, ts.DiagnosticCategory.Error, "The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer_1190", "The variable declaration of a 'for...of' statement cannot have an initializer."), An_import_declaration_cannot_have_modifiers: diag(1191, ts.DiagnosticCategory.Error, "An_import_declaration_cannot_have_modifiers_1191", "An import declaration cannot have modifiers."), Module_0_has_no_default_export: diag(1192, ts.DiagnosticCategory.Error, "Module_0_has_no_default_export_1192", "Module '{0}' has no default export."), An_export_declaration_cannot_have_modifiers: diag(1193, ts.DiagnosticCategory.Error, "An_export_declaration_cannot_have_modifiers_1193", "An export declaration cannot have modifiers."), Export_declarations_are_not_permitted_in_a_namespace: diag(1194, ts.DiagnosticCategory.Error, "Export_declarations_are_not_permitted_in_a_namespace_1194", "Export declarations are not permitted in a namespace."), Catch_clause_variable_cannot_have_a_type_annotation: diag(1196, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_a_type_annotation_1196", "Catch clause variable cannot have a type annotation."), Catch_clause_variable_cannot_have_an_initializer: diag(1197, ts.DiagnosticCategory.Error, "Catch_clause_variable_cannot_have_an_initializer_1197", "Catch clause variable cannot have an initializer."), An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive: diag(1198, ts.DiagnosticCategory.Error, "An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive_1198", "An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive."), Unterminated_Unicode_escape_sequence: diag(1199, ts.DiagnosticCategory.Error, "Unterminated_Unicode_escape_sequence_1199", "Unterminated Unicode escape sequence."), Line_terminator_not_permitted_before_arrow: diag(1200, ts.DiagnosticCategory.Error, "Line_terminator_not_permitted_before_arrow_1200", "Line terminator not permitted before arrow."), Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead: diag(1202, ts.DiagnosticCategory.Error, "Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_1202", "Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from \"mod\"', 'import {a} from \"mod\"', 'import d from \"mod\"', or another module format instead."), Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead: diag(1203, ts.DiagnosticCategory.Error, "Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or__1203", "Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead."), Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided: diag(1205, ts.DiagnosticCategory.Error, "Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205", "Cannot re-export a type when the '--isolatedModules' flag is provided."), Decorators_are_not_valid_here: diag(1206, ts.DiagnosticCategory.Error, "Decorators_are_not_valid_here_1206", "Decorators are not valid here."), Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name: diag(1207, ts.DiagnosticCategory.Error, "Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name_1207", "Decorators cannot be applied to multiple get/set accessors of the same name."), Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided: diag(1208, ts.DiagnosticCategory.Error, "Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided_1208", "Cannot compile namespaces when the '--isolatedModules' flag is provided."), Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided: diag(1209, ts.DiagnosticCategory.Error, "Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided_1209", "Ambient const enums are not allowed when the '--isolatedModules' flag is provided."), Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode: diag(1210, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode_1210", "Invalid use of '{0}'. Class definitions are automatically in strict mode."), A_class_declaration_without_the_default_modifier_must_have_a_name: diag(1211, ts.DiagnosticCategory.Error, "A_class_declaration_without_the_default_modifier_must_have_a_name_1211", "A class declaration without the 'default' modifier must have a name."), Identifier_expected_0_is_a_reserved_word_in_strict_mode: diag(1212, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_1212", "Identifier expected. '{0}' is a reserved word in strict mode."), Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: diag(1213, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_stric_1213", "Identifier expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode."), Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode: diag(1214, ts.DiagnosticCategory.Error, "Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode_1214", "Identifier expected. '{0}' is a reserved word in strict mode. Modules are automatically in strict mode."), Invalid_use_of_0_Modules_are_automatically_in_strict_mode: diag(1215, ts.DiagnosticCategory.Error, "Invalid_use_of_0_Modules_are_automatically_in_strict_mode_1215", "Invalid use of '{0}'. Modules are automatically in strict mode."), Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules: diag(1216, ts.DiagnosticCategory.Error, "Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules_1216", "Identifier expected. '__esModule' is reserved as an exported marker when transforming ECMAScript modules."), Export_assignment_is_not_supported_when_module_flag_is_system: diag(1218, ts.DiagnosticCategory.Error, "Export_assignment_is_not_supported_when_module_flag_is_system_1218", "Export assignment is not supported when '--module' flag is 'system'."), Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning: diag(1219, ts.DiagnosticCategory.Error, "Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_t_1219", "Experimental support for decorators is a feature that is subject to change in a future release. Set the 'experimentalDecorators' option to remove this warning."), Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher: diag(1220, ts.DiagnosticCategory.Error, "Generators_are_only_available_when_targeting_ECMAScript_2015_or_higher_1220", "Generators are only available when targeting ECMAScript 2015 or higher."), Generators_are_not_allowed_in_an_ambient_context: diag(1221, ts.DiagnosticCategory.Error, "Generators_are_not_allowed_in_an_ambient_context_1221", "Generators are not allowed in an ambient context."), An_overload_signature_cannot_be_declared_as_a_generator: diag(1222, ts.DiagnosticCategory.Error, "An_overload_signature_cannot_be_declared_as_a_generator_1222", "An overload signature cannot be declared as a generator."), _0_tag_already_specified: diag(1223, ts.DiagnosticCategory.Error, "_0_tag_already_specified_1223", "'{0}' tag already specified."), Signature_0_must_be_a_type_predicate: diag(1224, ts.DiagnosticCategory.Error, "Signature_0_must_be_a_type_predicate_1224", "Signature '{0}' must be a type predicate."), Cannot_find_parameter_0: diag(1225, ts.DiagnosticCategory.Error, "Cannot_find_parameter_0_1225", "Cannot find parameter '{0}'."), Type_predicate_0_is_not_assignable_to_1: diag(1226, ts.DiagnosticCategory.Error, "Type_predicate_0_is_not_assignable_to_1_1226", "Type predicate '{0}' is not assignable to '{1}'."), Parameter_0_is_not_in_the_same_position_as_parameter_1: diag(1227, ts.DiagnosticCategory.Error, "Parameter_0_is_not_in_the_same_position_as_parameter_1_1227", "Parameter '{0}' is not in the same position as parameter '{1}'."), A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods: diag(1228, ts.DiagnosticCategory.Error, "A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods_1228", "A type predicate is only allowed in return type position for functions and methods."), A_type_predicate_cannot_reference_a_rest_parameter: diag(1229, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_a_rest_parameter_1229", "A type predicate cannot reference a rest parameter."), A_type_predicate_cannot_reference_element_0_in_a_binding_pattern: diag(1230, ts.DiagnosticCategory.Error, "A_type_predicate_cannot_reference_element_0_in_a_binding_pattern_1230", "A type predicate cannot reference element '{0}' in a binding pattern."), An_export_assignment_can_only_be_used_in_a_module: diag(1231, ts.DiagnosticCategory.Error, "An_export_assignment_can_only_be_used_in_a_module_1231", "An export assignment can only be used in a module."), An_import_declaration_can_only_be_used_in_a_namespace_or_module: diag(1232, ts.DiagnosticCategory.Error, "An_import_declaration_can_only_be_used_in_a_namespace_or_module_1232", "An import declaration can only be used in a namespace or module."), An_export_declaration_can_only_be_used_in_a_module: diag(1233, ts.DiagnosticCategory.Error, "An_export_declaration_can_only_be_used_in_a_module_1233", "An export declaration can only be used in a module."), An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: diag(1234, ts.DiagnosticCategory.Error, "An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file_1234", "An ambient module declaration is only allowed at the top level in a file."), A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: diag(1235, ts.DiagnosticCategory.Error, "A_namespace_declaration_is_only_allowed_in_a_namespace_or_module_1235", "A namespace declaration is only allowed in a namespace or module."), The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: diag(1236, ts.DiagnosticCategory.Error, "The_return_type_of_a_property_decorator_function_must_be_either_void_or_any_1236", "The return type of a property decorator function must be either 'void' or 'any'."), The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: diag(1237, ts.DiagnosticCategory.Error, "The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any_1237", "The return type of a parameter decorator function must be either 'void' or 'any'."), Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: diag(1238, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression_1238", "Unable to resolve signature of class decorator when called as an expression."), Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: diag(1239, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression_1239", "Unable to resolve signature of parameter decorator when called as an expression."), Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: diag(1240, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression_1240", "Unable to resolve signature of property decorator when called as an expression."), Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: diag(1241, ts.DiagnosticCategory.Error, "Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression_1241", "Unable to resolve signature of method decorator when called as an expression."), abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration: diag(1242, ts.DiagnosticCategory.Error, "abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration_1242", "'abstract' modifier can only appear on a class, method, or property declaration."), _0_modifier_cannot_be_used_with_1_modifier: diag(1243, ts.DiagnosticCategory.Error, "_0_modifier_cannot_be_used_with_1_modifier_1243", "'{0}' modifier cannot be used with '{1}' modifier."), Abstract_methods_can_only_appear_within_an_abstract_class: diag(1244, ts.DiagnosticCategory.Error, "Abstract_methods_can_only_appear_within_an_abstract_class_1244", "Abstract methods can only appear within an abstract class."), Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: diag(1245, ts.DiagnosticCategory.Error, "Method_0_cannot_have_an_implementation_because_it_is_marked_abstract_1245", "Method '{0}' cannot have an implementation because it is marked abstract."), An_interface_property_cannot_have_an_initializer: diag(1246, ts.DiagnosticCategory.Error, "An_interface_property_cannot_have_an_initializer_1246", "An interface property cannot have an initializer."), A_type_literal_property_cannot_have_an_initializer: diag(1247, ts.DiagnosticCategory.Error, "A_type_literal_property_cannot_have_an_initializer_1247", "A type literal property cannot have an initializer."), A_class_member_cannot_have_the_0_keyword: diag(1248, ts.DiagnosticCategory.Error, "A_class_member_cannot_have_the_0_keyword_1248", "A class member cannot have the '{0}' keyword."), A_decorator_can_only_decorate_a_method_implementation_not_an_overload: diag(1249, ts.DiagnosticCategory.Error, "A_decorator_can_only_decorate_a_method_implementation_not_an_overload_1249", "A decorator can only decorate a method implementation, not an overload."), Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5: diag(1250, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_1250", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'."), Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode: diag(1251, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_d_1251", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Class definitions are automatically in strict mode."), Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode: diag(1252, ts.DiagnosticCategory.Error, "Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_1252", "Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode."), _0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag: diag(1253, ts.DiagnosticCategory.Error, "_0_tag_cannot_be_used_independently_as_a_top_level_JSDoc_tag_1253", "'{0}' tag cannot be used independently as a top level JSDoc tag."), A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal: diag(1254, ts.DiagnosticCategory.Error, "A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal_1254", "A 'const' initializer in an ambient context must be a string or numeric literal."), A_definite_assignment_assertion_is_not_permitted_in_this_context: diag(1255, ts.DiagnosticCategory.Error, "A_definite_assignment_assertion_is_not_permitted_in_this_context_1255", "A definite assignment assertion '!' is not permitted in this context."), with_statements_are_not_allowed_in_an_async_function_block: diag(1300, ts.DiagnosticCategory.Error, "with_statements_are_not_allowed_in_an_async_function_block_1300", "'with' statements are not allowed in an async function block."), await_expression_is_only_allowed_within_an_async_function: diag(1308, ts.DiagnosticCategory.Error, "await_expression_is_only_allowed_within_an_async_function_1308", "'await' expression is only allowed within an async function."), can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment: diag(1312, ts.DiagnosticCategory.Error, "can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment_1312", "'=' can only be used in an object literal property inside a destructuring assignment."), The_body_of_an_if_statement_cannot_be_the_empty_statement: diag(1313, ts.DiagnosticCategory.Error, "The_body_of_an_if_statement_cannot_be_the_empty_statement_1313", "The body of an 'if' statement cannot be the empty statement."), Global_module_exports_may_only_appear_in_module_files: diag(1314, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_module_files_1314", "Global module exports may only appear in module files."), Global_module_exports_may_only_appear_in_declaration_files: diag(1315, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_in_declaration_files_1315", "Global module exports may only appear in declaration files."), Global_module_exports_may_only_appear_at_top_level: diag(1316, ts.DiagnosticCategory.Error, "Global_module_exports_may_only_appear_at_top_level_1316", "Global module exports may only appear at top level."), A_parameter_property_cannot_be_declared_using_a_rest_parameter: diag(1317, ts.DiagnosticCategory.Error, "A_parameter_property_cannot_be_declared_using_a_rest_parameter_1317", "A parameter property cannot be declared using a rest parameter."), An_abstract_accessor_cannot_have_an_implementation: diag(1318, ts.DiagnosticCategory.Error, "An_abstract_accessor_cannot_have_an_implementation_1318", "An abstract accessor cannot have an implementation."), A_default_export_can_only_be_used_in_an_ECMAScript_style_module: diag(1319, ts.DiagnosticCategory.Error, "A_default_export_can_only_be_used_in_an_ECMAScript_style_module_1319", "A default export can only be used in an ECMAScript-style module."), Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1320, ts.DiagnosticCategory.Error, "Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member_1320", "Type of 'await' operand must either be a valid promise or must not contain a callable 'then' member."), Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1321, ts.DiagnosticCategory.Error, "Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321", "Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member."), Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member: diag(1322, ts.DiagnosticCategory.Error, "Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_con_1322", "Type of iterated elements of a 'yield*' operand must either be a valid promise or must not contain a callable 'then' member."), Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules: diag(1323, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules_1323", "Dynamic import cannot be used when targeting ECMAScript 2015 modules."), Dynamic_import_must_have_one_specifier_as_an_argument: diag(1324, ts.DiagnosticCategory.Error, "Dynamic_import_must_have_one_specifier_as_an_argument_1324", "Dynamic import must have one specifier as an argument."), Specifier_of_dynamic_import_cannot_be_spread_element: diag(1325, ts.DiagnosticCategory.Error, "Specifier_of_dynamic_import_cannot_be_spread_element_1325", "Specifier of dynamic import cannot be spread element."), Dynamic_import_cannot_have_type_arguments: diag(1326, ts.DiagnosticCategory.Error, "Dynamic_import_cannot_have_type_arguments_1326", "Dynamic import cannot have type arguments"), String_literal_with_double_quotes_expected: diag(1327, ts.DiagnosticCategory.Error, "String_literal_with_double_quotes_expected_1327", "String literal with double quotes expected."), Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal: diag(1328, ts.DiagnosticCategory.Error, "Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_li_1328", "Property value can only be string literal, numeric literal, 'true', 'false', 'null', object literal or array literal."), _0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0: diag(1329, ts.DiagnosticCategory.Error, "_0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write__1329", "'{0}' accepts too few arguments to be used as a decorator here. Did you mean to call it first and write '@{0}()'?"), A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly: diag(1330, ts.DiagnosticCategory.Error, "A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly_1330", "A property of an interface or type literal whose type is a 'unique symbol' type must be 'readonly'."), A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly: diag(1331, ts.DiagnosticCategory.Error, "A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly_1331", "A property of a class whose type is a 'unique symbol' type must be both 'static' and 'readonly'."), A_variable_whose_type_is_a_unique_symbol_type_must_be_const: diag(1332, ts.DiagnosticCategory.Error, "A_variable_whose_type_is_a_unique_symbol_type_must_be_const_1332", "A variable whose type is a 'unique symbol' type must be 'const'."), unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name: diag(1333, ts.DiagnosticCategory.Error, "unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name_1333", "'unique symbol' types may not be used on a variable declaration with a binding name."), unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement: diag(1334, ts.DiagnosticCategory.Error, "unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement_1334", "'unique symbol' types are only allowed on variables in a variable statement."), unique_symbol_types_are_not_allowed_here: diag(1335, ts.DiagnosticCategory.Error, "unique_symbol_types_are_not_allowed_here_1335", "'unique symbol' types are not allowed here."), Duplicate_identifier_0: diag(2300, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_2300", "Duplicate identifier '{0}'."), Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: diag(2301, ts.DiagnosticCategory.Error, "Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor_2301", "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor."), Static_members_cannot_reference_class_type_parameters: diag(2302, ts.DiagnosticCategory.Error, "Static_members_cannot_reference_class_type_parameters_2302", "Static members cannot reference class type parameters."), Circular_definition_of_import_alias_0: diag(2303, ts.DiagnosticCategory.Error, "Circular_definition_of_import_alias_0_2303", "Circular definition of import alias '{0}'."), Cannot_find_name_0: diag(2304, ts.DiagnosticCategory.Error, "Cannot_find_name_0_2304", "Cannot find name '{0}'."), Module_0_has_no_exported_member_1: diag(2305, ts.DiagnosticCategory.Error, "Module_0_has_no_exported_member_1_2305", "Module '{0}' has no exported member '{1}'."), File_0_is_not_a_module: diag(2306, ts.DiagnosticCategory.Error, "File_0_is_not_a_module_2306", "File '{0}' is not a module."), Cannot_find_module_0: diag(2307, ts.DiagnosticCategory.Error, "Cannot_find_module_0_2307", "Cannot find module '{0}'."), Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity: diag(2308, ts.DiagnosticCategory.Error, "Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambig_2308", "Module {0} has already exported a member named '{1}'. Consider explicitly re-exporting to resolve the ambiguity."), An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements: diag(2309, ts.DiagnosticCategory.Error, "An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements_2309", "An export assignment cannot be used in a module with other exported elements."), Type_0_recursively_references_itself_as_a_base_type: diag(2310, ts.DiagnosticCategory.Error, "Type_0_recursively_references_itself_as_a_base_type_2310", "Type '{0}' recursively references itself as a base type."), A_class_may_only_extend_another_class: diag(2311, ts.DiagnosticCategory.Error, "A_class_may_only_extend_another_class_2311", "A class may only extend another class."), An_interface_may_only_extend_a_class_or_another_interface: diag(2312, ts.DiagnosticCategory.Error, "An_interface_may_only_extend_a_class_or_another_interface_2312", "An interface may only extend a class or another interface."), Type_parameter_0_has_a_circular_constraint: diag(2313, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_constraint_2313", "Type parameter '{0}' has a circular constraint."), Generic_type_0_requires_1_type_argument_s: diag(2314, ts.DiagnosticCategory.Error, "Generic_type_0_requires_1_type_argument_s_2314", "Generic type '{0}' requires {1} type argument(s)."), Type_0_is_not_generic: diag(2315, ts.DiagnosticCategory.Error, "Type_0_is_not_generic_2315", "Type '{0}' is not generic."), Global_type_0_must_be_a_class_or_interface_type: diag(2316, ts.DiagnosticCategory.Error, "Global_type_0_must_be_a_class_or_interface_type_2316", "Global type '{0}' must be a class or interface type."), Global_type_0_must_have_1_type_parameter_s: diag(2317, ts.DiagnosticCategory.Error, "Global_type_0_must_have_1_type_parameter_s_2317", "Global type '{0}' must have {1} type parameter(s)."), Cannot_find_global_type_0: diag(2318, ts.DiagnosticCategory.Error, "Cannot_find_global_type_0_2318", "Cannot find global type '{0}'."), Named_property_0_of_types_1_and_2_are_not_identical: diag(2319, ts.DiagnosticCategory.Error, "Named_property_0_of_types_1_and_2_are_not_identical_2319", "Named property '{0}' of types '{1}' and '{2}' are not identical."), Interface_0_cannot_simultaneously_extend_types_1_and_2: diag(2320, ts.DiagnosticCategory.Error, "Interface_0_cannot_simultaneously_extend_types_1_and_2_2320", "Interface '{0}' cannot simultaneously extend types '{1}' and '{2}'."), Excessive_stack_depth_comparing_types_0_and_1: diag(2321, ts.DiagnosticCategory.Error, "Excessive_stack_depth_comparing_types_0_and_1_2321", "Excessive stack depth comparing types '{0}' and '{1}'."), Type_0_is_not_assignable_to_type_1: diag(2322, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_2322", "Type '{0}' is not assignable to type '{1}'."), Cannot_redeclare_exported_variable_0: diag(2323, ts.DiagnosticCategory.Error, "Cannot_redeclare_exported_variable_0_2323", "Cannot redeclare exported variable '{0}'."), Property_0_is_missing_in_type_1: diag(2324, ts.DiagnosticCategory.Error, "Property_0_is_missing_in_type_1_2324", "Property '{0}' is missing in type '{1}'."), Property_0_is_private_in_type_1_but_not_in_type_2: diag(2325, ts.DiagnosticCategory.Error, "Property_0_is_private_in_type_1_but_not_in_type_2_2325", "Property '{0}' is private in type '{1}' but not in type '{2}'."), Types_of_property_0_are_incompatible: diag(2326, ts.DiagnosticCategory.Error, "Types_of_property_0_are_incompatible_2326", "Types of property '{0}' are incompatible."), Property_0_is_optional_in_type_1_but_required_in_type_2: diag(2327, ts.DiagnosticCategory.Error, "Property_0_is_optional_in_type_1_but_required_in_type_2_2327", "Property '{0}' is optional in type '{1}' but required in type '{2}'."), Types_of_parameters_0_and_1_are_incompatible: diag(2328, ts.DiagnosticCategory.Error, "Types_of_parameters_0_and_1_are_incompatible_2328", "Types of parameters '{0}' and '{1}' are incompatible."), Index_signature_is_missing_in_type_0: diag(2329, ts.DiagnosticCategory.Error, "Index_signature_is_missing_in_type_0_2329", "Index signature is missing in type '{0}'."), Index_signatures_are_incompatible: diag(2330, ts.DiagnosticCategory.Error, "Index_signatures_are_incompatible_2330", "Index signatures are incompatible."), this_cannot_be_referenced_in_a_module_or_namespace_body: diag(2331, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_module_or_namespace_body_2331", "'this' cannot be referenced in a module or namespace body."), this_cannot_be_referenced_in_current_location: diag(2332, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_current_location_2332", "'this' cannot be referenced in current location."), this_cannot_be_referenced_in_constructor_arguments: diag(2333, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_constructor_arguments_2333", "'this' cannot be referenced in constructor arguments."), this_cannot_be_referenced_in_a_static_property_initializer: diag(2334, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_static_property_initializer_2334", "'this' cannot be referenced in a static property initializer."), super_can_only_be_referenced_in_a_derived_class: diag(2335, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_a_derived_class_2335", "'super' can only be referenced in a derived class."), super_cannot_be_referenced_in_constructor_arguments: diag(2336, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_constructor_arguments_2336", "'super' cannot be referenced in constructor arguments."), Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: diag(2337, ts.DiagnosticCategory.Error, "Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors_2337", "Super calls are not permitted outside constructors or in nested functions inside constructors."), super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: diag(2338, ts.DiagnosticCategory.Error, "super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_der_2338", "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class."), Property_0_does_not_exist_on_type_1: diag(2339, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_2339", "Property '{0}' does not exist on type '{1}'."), Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: diag(2340, ts.DiagnosticCategory.Error, "Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340", "Only public and protected methods of the base class are accessible via the 'super' keyword."), Property_0_is_private_and_only_accessible_within_class_1: diag(2341, ts.DiagnosticCategory.Error, "Property_0_is_private_and_only_accessible_within_class_1_2341", "Property '{0}' is private and only accessible within class '{1}'."), An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: diag(2342, ts.DiagnosticCategory.Error, "An_index_expression_argument_must_be_of_type_string_number_symbol_or_any_2342", "An index expression argument must be of type 'string', 'number', 'symbol', or 'any'."), This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1: diag(2343, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1_2343", "This syntax requires an imported helper named '{1}', but module '{0}' has no exported member '{1}'."), Type_0_does_not_satisfy_the_constraint_1: diag(2344, ts.DiagnosticCategory.Error, "Type_0_does_not_satisfy_the_constraint_1_2344", "Type '{0}' does not satisfy the constraint '{1}'."), Argument_of_type_0_is_not_assignable_to_parameter_of_type_1: diag(2345, ts.DiagnosticCategory.Error, "Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_2345", "Argument of type '{0}' is not assignable to parameter of type '{1}'."), Call_target_does_not_contain_any_signatures: diag(2346, ts.DiagnosticCategory.Error, "Call_target_does_not_contain_any_signatures_2346", "Call target does not contain any signatures."), Untyped_function_calls_may_not_accept_type_arguments: diag(2347, ts.DiagnosticCategory.Error, "Untyped_function_calls_may_not_accept_type_arguments_2347", "Untyped function calls may not accept type arguments."), Value_of_type_0_is_not_callable_Did_you_mean_to_include_new: diag(2348, ts.DiagnosticCategory.Error, "Value_of_type_0_is_not_callable_Did_you_mean_to_include_new_2348", "Value of type '{0}' is not callable. Did you mean to include 'new'?"), Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures: diag(2349, ts.DiagnosticCategory.Error, "Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatur_2349", "Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures."), Only_a_void_function_can_be_called_with_the_new_keyword: diag(2350, ts.DiagnosticCategory.Error, "Only_a_void_function_can_be_called_with_the_new_keyword_2350", "Only a void function can be called with the 'new' keyword."), Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature: diag(2351, ts.DiagnosticCategory.Error, "Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature_2351", "Cannot use 'new' with an expression whose type lacks a call or construct signature."), Type_0_cannot_be_converted_to_type_1: diag(2352, ts.DiagnosticCategory.Error, "Type_0_cannot_be_converted_to_type_1_2352", "Type '{0}' cannot be converted to type '{1}'."), Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1: diag(2353, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1_2353", "Object literal may only specify known properties, and '{0}' does not exist in type '{1}'."), This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found: diag(2354, ts.DiagnosticCategory.Error, "This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found_2354", "This syntax requires an imported helper but module '{0}' cannot be found."), A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value: diag(2355, ts.DiagnosticCategory.Error, "A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value_2355", "A function whose declared type is neither 'void' nor 'any' must return a value."), An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type: diag(2356, ts.DiagnosticCategory.Error, "An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type_2356", "An arithmetic operand must be of type 'any', 'number' or an enum type."), The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access: diag(2357, ts.DiagnosticCategory.Error, "The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access_2357", "The operand of an increment or decrement operator must be a variable or a property access."), The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2358, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_paramete_2358", "The left-hand side of an 'instanceof' expression must be of type 'any', an object type or a type parameter."), The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type: diag(2359, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_F_2359", "The right-hand side of an 'instanceof' expression must be of type 'any' or of a type assignable to the 'Function' interface type."), The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol: diag(2360, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol_2360", "The left-hand side of an 'in' expression must be of type 'any', 'string', 'number', or 'symbol'."), The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2361, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter_2361", "The right-hand side of an 'in' expression must be of type 'any', an object type or a type parameter."), The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2362, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2362", "The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."), The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: diag(2363, ts.DiagnosticCategory.Error, "The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type_2363", "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type."), The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access: diag(2364, ts.DiagnosticCategory.Error, "The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access_2364", "The left-hand side of an assignment expression must be a variable or a property access."), Operator_0_cannot_be_applied_to_types_1_and_2: diag(2365, ts.DiagnosticCategory.Error, "Operator_0_cannot_be_applied_to_types_1_and_2_2365", "Operator '{0}' cannot be applied to types '{1}' and '{2}'."), Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined: diag(2366, ts.DiagnosticCategory.Error, "Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined_2366", "Function lacks ending return statement and return type does not include 'undefined'."), Type_parameter_name_cannot_be_0: diag(2368, ts.DiagnosticCategory.Error, "Type_parameter_name_cannot_be_0_2368", "Type parameter name cannot be '{0}'."), A_parameter_property_is_only_allowed_in_a_constructor_implementation: diag(2369, ts.DiagnosticCategory.Error, "A_parameter_property_is_only_allowed_in_a_constructor_implementation_2369", "A parameter property is only allowed in a constructor implementation."), A_rest_parameter_must_be_of_an_array_type: diag(2370, ts.DiagnosticCategory.Error, "A_rest_parameter_must_be_of_an_array_type_2370", "A rest parameter must be of an array type."), A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation: diag(2371, ts.DiagnosticCategory.Error, "A_parameter_initializer_is_only_allowed_in_a_function_or_constructor_implementation_2371", "A parameter initializer is only allowed in a function or constructor implementation."), Parameter_0_cannot_be_referenced_in_its_initializer: diag(2372, ts.DiagnosticCategory.Error, "Parameter_0_cannot_be_referenced_in_its_initializer_2372", "Parameter '{0}' cannot be referenced in its initializer."), Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it: diag(2373, ts.DiagnosticCategory.Error, "Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it_2373", "Initializer of parameter '{0}' cannot reference identifier '{1}' declared after it."), Duplicate_string_index_signature: diag(2374, ts.DiagnosticCategory.Error, "Duplicate_string_index_signature_2374", "Duplicate string index signature."), Duplicate_number_index_signature: diag(2375, ts.DiagnosticCategory.Error, "Duplicate_number_index_signature_2375", "Duplicate number index signature."), A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties: diag(2376, ts.DiagnosticCategory.Error, "A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_proper_2376", "A 'super' call must be the first statement in the constructor when a class contains initialized properties or has parameter properties."), Constructors_for_derived_classes_must_contain_a_super_call: diag(2377, ts.DiagnosticCategory.Error, "Constructors_for_derived_classes_must_contain_a_super_call_2377", "Constructors for derived classes must contain a 'super' call."), A_get_accessor_must_return_a_value: diag(2378, ts.DiagnosticCategory.Error, "A_get_accessor_must_return_a_value_2378", "A 'get' accessor must return a value."), Getter_and_setter_accessors_do_not_agree_in_visibility: diag(2379, ts.DiagnosticCategory.Error, "Getter_and_setter_accessors_do_not_agree_in_visibility_2379", "Getter and setter accessors do not agree in visibility."), get_and_set_accessor_must_have_the_same_type: diag(2380, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_type_2380", "'get' and 'set' accessor must have the same type."), A_signature_with_an_implementation_cannot_use_a_string_literal_type: diag(2381, ts.DiagnosticCategory.Error, "A_signature_with_an_implementation_cannot_use_a_string_literal_type_2381", "A signature with an implementation cannot use a string literal type."), Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: diag(2382, ts.DiagnosticCategory.Error, "Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature_2382", "Specialized overload signature is not assignable to any non-specialized signature."), Overload_signatures_must_all_be_exported_or_non_exported: diag(2383, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_exported_or_non_exported_2383", "Overload signatures must all be exported or non-exported."), Overload_signatures_must_all_be_ambient_or_non_ambient: diag(2384, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_ambient_or_non_ambient_2384", "Overload signatures must all be ambient or non-ambient."), Overload_signatures_must_all_be_public_private_or_protected: diag(2385, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_public_private_or_protected_2385", "Overload signatures must all be public, private or protected."), Overload_signatures_must_all_be_optional_or_required: diag(2386, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_optional_or_required_2386", "Overload signatures must all be optional or required."), Function_overload_must_be_static: diag(2387, ts.DiagnosticCategory.Error, "Function_overload_must_be_static_2387", "Function overload must be static."), Function_overload_must_not_be_static: diag(2388, ts.DiagnosticCategory.Error, "Function_overload_must_not_be_static_2388", "Function overload must not be static."), Function_implementation_name_must_be_0: diag(2389, ts.DiagnosticCategory.Error, "Function_implementation_name_must_be_0_2389", "Function implementation name must be '{0}'."), Constructor_implementation_is_missing: diag(2390, ts.DiagnosticCategory.Error, "Constructor_implementation_is_missing_2390", "Constructor implementation is missing."), Function_implementation_is_missing_or_not_immediately_following_the_declaration: diag(2391, ts.DiagnosticCategory.Error, "Function_implementation_is_missing_or_not_immediately_following_the_declaration_2391", "Function implementation is missing or not immediately following the declaration."), Multiple_constructor_implementations_are_not_allowed: diag(2392, ts.DiagnosticCategory.Error, "Multiple_constructor_implementations_are_not_allowed_2392", "Multiple constructor implementations are not allowed."), Duplicate_function_implementation: diag(2393, ts.DiagnosticCategory.Error, "Duplicate_function_implementation_2393", "Duplicate function implementation."), Overload_signature_is_not_compatible_with_function_implementation: diag(2394, ts.DiagnosticCategory.Error, "Overload_signature_is_not_compatible_with_function_implementation_2394", "Overload signature is not compatible with function implementation."), Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local: diag(2395, ts.DiagnosticCategory.Error, "Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local_2395", "Individual declarations in merged declaration '{0}' must be all exported or all local."), Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters: diag(2396, ts.DiagnosticCategory.Error, "Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters_2396", "Duplicate identifier 'arguments'. Compiler uses 'arguments' to initialize rest parameters."), Declaration_name_conflicts_with_built_in_global_identifier_0: diag(2397, ts.DiagnosticCategory.Error, "Declaration_name_conflicts_with_built_in_global_identifier_0_2397", "Declaration name conflicts with built-in global identifier '{0}'."), Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference: diag(2399, ts.DiagnosticCategory.Error, "Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference_2399", "Duplicate identifier '_this'. Compiler uses variable declaration '_this' to capture 'this' reference."), Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference: diag(2400, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference_2400", "Expression resolves to variable declaration '_this' that compiler uses to capture 'this' reference."), Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference: diag(2401, ts.DiagnosticCategory.Error, "Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference_2401", "Duplicate identifier '_super'. Compiler uses '_super' to capture base class reference."), Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference: diag(2402, ts.DiagnosticCategory.Error, "Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference_2402", "Expression resolves to '_super' that compiler uses to capture base class reference."), Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2: diag(2403, ts.DiagnosticCategory.Error, "Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_t_2403", "Subsequent variable declarations must have the same type. Variable '{0}' must be of type '{1}', but here has type '{2}'."), The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation: diag(2404, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_use_a_type_annotation_2404", "The left-hand side of a 'for...in' statement cannot use a type annotation."), The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any: diag(2405, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any_2405", "The left-hand side of a 'for...in' statement must be of type 'string' or 'any'."), The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access: diag(2406, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access_2406", "The left-hand side of a 'for...in' statement must be a variable or a property access."), The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter: diag(2407, ts.DiagnosticCategory.Error, "The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter_2407", "The right-hand side of a 'for...in' statement must be of type 'any', an object type or a type parameter."), Setters_cannot_return_a_value: diag(2408, ts.DiagnosticCategory.Error, "Setters_cannot_return_a_value_2408", "Setters cannot return a value."), Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class: diag(2409, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class_2409", "Return type of constructor signature must be assignable to the instance type of the class."), The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any: diag(2410, ts.DiagnosticCategory.Error, "The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any_2410", "The 'with' statement is not supported. All symbols in a 'with' block will have type 'any'."), Property_0_of_type_1_is_not_assignable_to_string_index_type_2: diag(2411, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_string_index_type_2_2411", "Property '{0}' of type '{1}' is not assignable to string index type '{2}'."), Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2: diag(2412, ts.DiagnosticCategory.Error, "Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2_2412", "Property '{0}' of type '{1}' is not assignable to numeric index type '{2}'."), Numeric_index_type_0_is_not_assignable_to_string_index_type_1: diag(2413, ts.DiagnosticCategory.Error, "Numeric_index_type_0_is_not_assignable_to_string_index_type_1_2413", "Numeric index type '{0}' is not assignable to string index type '{1}'."), Class_name_cannot_be_0: diag(2414, ts.DiagnosticCategory.Error, "Class_name_cannot_be_0_2414", "Class name cannot be '{0}'."), Class_0_incorrectly_extends_base_class_1: diag(2415, ts.DiagnosticCategory.Error, "Class_0_incorrectly_extends_base_class_1_2415", "Class '{0}' incorrectly extends base class '{1}'."), Class_static_side_0_incorrectly_extends_base_class_static_side_1: diag(2417, ts.DiagnosticCategory.Error, "Class_static_side_0_incorrectly_extends_base_class_static_side_1_2417", "Class static side '{0}' incorrectly extends base class static side '{1}'."), Class_0_incorrectly_implements_interface_1: diag(2420, ts.DiagnosticCategory.Error, "Class_0_incorrectly_implements_interface_1_2420", "Class '{0}' incorrectly implements interface '{1}'."), A_class_may_only_implement_another_class_or_interface: diag(2422, ts.DiagnosticCategory.Error, "A_class_may_only_implement_another_class_or_interface_2422", "A class may only implement another class or interface."), Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor: diag(2423, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_access_2423", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member accessor."), Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property: diag(2424, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_proper_2424", "Class '{0}' defines instance member function '{1}', but extended class '{2}' defines it as instance member property."), Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2425, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_functi_2425", "Class '{0}' defines instance member property '{1}', but extended class '{2}' defines it as instance member function."), Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: diag(2426, ts.DiagnosticCategory.Error, "Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_functi_2426", "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function."), Interface_name_cannot_be_0: diag(2427, ts.DiagnosticCategory.Error, "Interface_name_cannot_be_0_2427", "Interface name cannot be '{0}'."), All_declarations_of_0_must_have_identical_type_parameters: diag(2428, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_type_parameters_2428", "All declarations of '{0}' must have identical type parameters."), Interface_0_incorrectly_extends_interface_1: diag(2430, ts.DiagnosticCategory.Error, "Interface_0_incorrectly_extends_interface_1_2430", "Interface '{0}' incorrectly extends interface '{1}'."), Enum_name_cannot_be_0: diag(2431, ts.DiagnosticCategory.Error, "Enum_name_cannot_be_0_2431", "Enum name cannot be '{0}'."), In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element: diag(2432, ts.DiagnosticCategory.Error, "In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enu_2432", "In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element."), A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged: diag(2433, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merg_2433", "A namespace declaration cannot be in a different file from a class or function with which it is merged."), A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged: diag(2434, ts.DiagnosticCategory.Error, "A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged_2434", "A namespace declaration cannot be located prior to a class or function with which it is merged."), Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces: diag(2435, ts.DiagnosticCategory.Error, "Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces_2435", "Ambient modules cannot be nested in other modules or namespaces."), Ambient_module_declaration_cannot_specify_relative_module_name: diag(2436, ts.DiagnosticCategory.Error, "Ambient_module_declaration_cannot_specify_relative_module_name_2436", "Ambient module declaration cannot specify relative module name."), Module_0_is_hidden_by_a_local_declaration_with_the_same_name: diag(2437, ts.DiagnosticCategory.Error, "Module_0_is_hidden_by_a_local_declaration_with_the_same_name_2437", "Module '{0}' is hidden by a local declaration with the same name."), Import_name_cannot_be_0: diag(2438, ts.DiagnosticCategory.Error, "Import_name_cannot_be_0_2438", "Import name cannot be '{0}'."), Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name: diag(2439, ts.DiagnosticCategory.Error, "Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relati_2439", "Import or export declaration in an ambient module declaration cannot reference module through relative module name."), Import_declaration_conflicts_with_local_declaration_of_0: diag(2440, ts.DiagnosticCategory.Error, "Import_declaration_conflicts_with_local_declaration_of_0_2440", "Import declaration conflicts with local declaration of '{0}'."), Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module: diag(2441, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_2441", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module."), Types_have_separate_declarations_of_a_private_property_0: diag(2442, ts.DiagnosticCategory.Error, "Types_have_separate_declarations_of_a_private_property_0_2442", "Types have separate declarations of a private property '{0}'."), Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2: diag(2443, ts.DiagnosticCategory.Error, "Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2_2443", "Property '{0}' is protected but type '{1}' is not a class derived from '{2}'."), Property_0_is_protected_in_type_1_but_public_in_type_2: diag(2444, ts.DiagnosticCategory.Error, "Property_0_is_protected_in_type_1_but_public_in_type_2_2444", "Property '{0}' is protected in type '{1}' but public in type '{2}'."), Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: diag(2445, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses_2445", "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."), Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: diag(2446, ts.DiagnosticCategory.Error, "Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1_2446", "Property '{0}' is protected and only accessible through an instance of class '{1}'."), The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: diag(2447, ts.DiagnosticCategory.Error, "The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead_2447", "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead."), Block_scoped_variable_0_used_before_its_declaration: diag(2448, ts.DiagnosticCategory.Error, "Block_scoped_variable_0_used_before_its_declaration_2448", "Block-scoped variable '{0}' used before its declaration."), Class_0_used_before_its_declaration: diag(2449, ts.DiagnosticCategory.Error, "Class_0_used_before_its_declaration_2449", "Class '{0}' used before its declaration."), Enum_0_used_before_its_declaration: diag(2450, ts.DiagnosticCategory.Error, "Enum_0_used_before_its_declaration_2450", "Enum '{0}' used before its declaration."), Cannot_redeclare_block_scoped_variable_0: diag(2451, ts.DiagnosticCategory.Error, "Cannot_redeclare_block_scoped_variable_0_2451", "Cannot redeclare block-scoped variable '{0}'."), An_enum_member_cannot_have_a_numeric_name: diag(2452, ts.DiagnosticCategory.Error, "An_enum_member_cannot_have_a_numeric_name_2452", "An enum member cannot have a numeric name."), The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly: diag(2453, ts.DiagnosticCategory.Error, "The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_typ_2453", "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."), Variable_0_is_used_before_being_assigned: diag(2454, ts.DiagnosticCategory.Error, "Variable_0_is_used_before_being_assigned_2454", "Variable '{0}' is used before being assigned."), Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0: diag(2455, ts.DiagnosticCategory.Error, "Type_argument_candidate_1_is_not_a_valid_type_argument_because_it_is_not_a_supertype_of_candidate_0_2455", "Type argument candidate '{1}' is not a valid type argument because it is not a supertype of candidate '{0}'."), Type_alias_0_circularly_references_itself: diag(2456, ts.DiagnosticCategory.Error, "Type_alias_0_circularly_references_itself_2456", "Type alias '{0}' circularly references itself."), Type_alias_name_cannot_be_0: diag(2457, ts.DiagnosticCategory.Error, "Type_alias_name_cannot_be_0_2457", "Type alias name cannot be '{0}'."), An_AMD_module_cannot_have_multiple_name_assignments: diag(2458, ts.DiagnosticCategory.Error, "An_AMD_module_cannot_have_multiple_name_assignments_2458", "An AMD module cannot have multiple name assignments."), Type_0_has_no_property_1_and_no_string_index_signature: diag(2459, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_and_no_string_index_signature_2459", "Type '{0}' has no property '{1}' and no string index signature."), Type_0_has_no_property_1: diag(2460, ts.DiagnosticCategory.Error, "Type_0_has_no_property_1_2460", "Type '{0}' has no property '{1}'."), Type_0_is_not_an_array_type: diag(2461, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_2461", "Type '{0}' is not an array type."), A_rest_element_must_be_last_in_a_destructuring_pattern: diag(2462, ts.DiagnosticCategory.Error, "A_rest_element_must_be_last_in_a_destructuring_pattern_2462", "A rest element must be last in a destructuring pattern."), A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature: diag(2463, ts.DiagnosticCategory.Error, "A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature_2463", "A binding pattern parameter cannot be optional in an implementation signature."), A_computed_property_name_must_be_of_type_string_number_symbol_or_any: diag(2464, ts.DiagnosticCategory.Error, "A_computed_property_name_must_be_of_type_string_number_symbol_or_any_2464", "A computed property name must be of type 'string', 'number', 'symbol', or 'any'."), this_cannot_be_referenced_in_a_computed_property_name: diag(2465, ts.DiagnosticCategory.Error, "this_cannot_be_referenced_in_a_computed_property_name_2465", "'this' cannot be referenced in a computed property name."), super_cannot_be_referenced_in_a_computed_property_name: diag(2466, ts.DiagnosticCategory.Error, "super_cannot_be_referenced_in_a_computed_property_name_2466", "'super' cannot be referenced in a computed property name."), A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type: diag(2467, ts.DiagnosticCategory.Error, "A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type_2467", "A computed property name cannot reference a type parameter from its containing type."), Cannot_find_global_value_0: diag(2468, ts.DiagnosticCategory.Error, "Cannot_find_global_value_0_2468", "Cannot find global value '{0}'."), The_0_operator_cannot_be_applied_to_type_symbol: diag(2469, ts.DiagnosticCategory.Error, "The_0_operator_cannot_be_applied_to_type_symbol_2469", "The '{0}' operator cannot be applied to type 'symbol'."), Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object: diag(2470, ts.DiagnosticCategory.Error, "Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object_2470", "'Symbol' reference does not refer to the global Symbol constructor object."), A_computed_property_name_of_the_form_0_must_be_of_type_symbol: diag(2471, ts.DiagnosticCategory.Error, "A_computed_property_name_of_the_form_0_must_be_of_type_symbol_2471", "A computed property name of the form '{0}' must be of type 'symbol'."), Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher: diag(2472, ts.DiagnosticCategory.Error, "Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher_2472", "Spread operator in 'new' expressions is only available when targeting ECMAScript 5 and higher."), Enum_declarations_must_all_be_const_or_non_const: diag(2473, ts.DiagnosticCategory.Error, "Enum_declarations_must_all_be_const_or_non_const_2473", "Enum declarations must all be const or non-const."), In_const_enum_declarations_member_initializer_must_be_constant_expression: diag(2474, ts.DiagnosticCategory.Error, "In_const_enum_declarations_member_initializer_must_be_constant_expression_2474", "In 'const' enum declarations member initializer must be constant expression."), const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment: diag(2475, ts.DiagnosticCategory.Error, "const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_im_2475", "'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment."), A_const_enum_member_can_only_be_accessed_using_a_string_literal: diag(2476, ts.DiagnosticCategory.Error, "A_const_enum_member_can_only_be_accessed_using_a_string_literal_2476", "A const enum member can only be accessed using a string literal."), const_enum_member_initializer_was_evaluated_to_a_non_finite_value: diag(2477, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_a_non_finite_value_2477", "'const' enum member initializer was evaluated to a non-finite value."), const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: diag(2478, ts.DiagnosticCategory.Error, "const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN_2478", "'const' enum member initializer was evaluated to disallowed value 'NaN'."), Property_0_does_not_exist_on_const_enum_1: diag(2479, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_const_enum_1_2479", "Property '{0}' does not exist on 'const' enum '{1}'."), let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: diag(2480, ts.DiagnosticCategory.Error, "let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations_2480", "'let' is not allowed to be used as a name in 'let' or 'const' declarations."), Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: diag(2481, ts.DiagnosticCategory.Error, "Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1_2481", "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'."), The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation: diag(2483, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_cannot_use_a_type_annotation_2483", "The left-hand side of a 'for...of' statement cannot use a type annotation."), Export_declaration_conflicts_with_exported_declaration_of_0: diag(2484, ts.DiagnosticCategory.Error, "Export_declaration_conflicts_with_exported_declaration_of_0_2484", "Export declaration conflicts with exported declaration of '{0}'."), The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access: diag(2487, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access_2487", "The left-hand side of a 'for...of' statement must be a variable or a property access."), Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2488, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator_2488", "Type must have a '[Symbol.iterator]()' method that returns an iterator."), An_iterator_must_have_a_next_method: diag(2489, ts.DiagnosticCategory.Error, "An_iterator_must_have_a_next_method_2489", "An iterator must have a 'next()' method."), The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property: diag(2490, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property_2490", "The type returned by the 'next()' method of an iterator must have a 'value' property."), The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern: diag(2491, ts.DiagnosticCategory.Error, "The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern_2491", "The left-hand side of a 'for...in' statement cannot be a destructuring pattern."), Cannot_redeclare_identifier_0_in_catch_clause: diag(2492, ts.DiagnosticCategory.Error, "Cannot_redeclare_identifier_0_in_catch_clause_2492", "Cannot redeclare identifier '{0}' in catch clause."), Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2: diag(2493, ts.DiagnosticCategory.Error, "Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2_2493", "Tuple type '{0}' with length '{1}' cannot be assigned to tuple with length '{2}'."), Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher: diag(2494, ts.DiagnosticCategory.Error, "Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher_2494", "Using a string in a 'for...of' statement is only supported in ECMAScript 5 and higher."), Type_0_is_not_an_array_type_or_a_string_type: diag(2495, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_2495", "Type '{0}' is not an array type or a string type."), The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression: diag(2496, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_stand_2496", "The 'arguments' object cannot be referenced in an arrow function in ES3 and ES5. Consider using a standard function expression."), Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct: diag(2497, ts.DiagnosticCategory.Error, "Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct_2497", "Module '{0}' resolves to a non-module entity and cannot be imported using this construct."), Module_0_uses_export_and_cannot_be_used_with_export_Asterisk: diag(2498, ts.DiagnosticCategory.Error, "Module_0_uses_export_and_cannot_be_used_with_export_Asterisk_2498", "Module '{0}' uses 'export =' and cannot be used with 'export *'."), An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2499, ts.DiagnosticCategory.Error, "An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments_2499", "An interface can only extend an identifier/qualified-name with optional type arguments."), A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments: diag(2500, ts.DiagnosticCategory.Error, "A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments_2500", "A class can only implement an identifier/qualified-name with optional type arguments."), A_rest_element_cannot_contain_a_binding_pattern: diag(2501, ts.DiagnosticCategory.Error, "A_rest_element_cannot_contain_a_binding_pattern_2501", "A rest element cannot contain a binding pattern."), _0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: diag(2502, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation_2502", "'{0}' is referenced directly or indirectly in its own type annotation."), Cannot_find_namespace_0: diag(2503, ts.DiagnosticCategory.Error, "Cannot_find_namespace_0_2503", "Cannot find namespace '{0}'."), Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator: diag(2504, ts.DiagnosticCategory.Error, "Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator_2504", "Type must have a '[Symbol.asyncIterator]()' method that returns an async iterator."), A_generator_cannot_have_a_void_type_annotation: diag(2505, ts.DiagnosticCategory.Error, "A_generator_cannot_have_a_void_type_annotation_2505", "A generator cannot have a 'void' type annotation."), _0_is_referenced_directly_or_indirectly_in_its_own_base_expression: diag(2506, ts.DiagnosticCategory.Error, "_0_is_referenced_directly_or_indirectly_in_its_own_base_expression_2506", "'{0}' is referenced directly or indirectly in its own base expression."), Type_0_is_not_a_constructor_function_type: diag(2507, ts.DiagnosticCategory.Error, "Type_0_is_not_a_constructor_function_type_2507", "Type '{0}' is not a constructor function type."), No_base_constructor_has_the_specified_number_of_type_arguments: diag(2508, ts.DiagnosticCategory.Error, "No_base_constructor_has_the_specified_number_of_type_arguments_2508", "No base constructor has the specified number of type arguments."), Base_constructor_return_type_0_is_not_a_class_or_interface_type: diag(2509, ts.DiagnosticCategory.Error, "Base_constructor_return_type_0_is_not_a_class_or_interface_type_2509", "Base constructor return type '{0}' is not a class or interface type."), Base_constructors_must_all_have_the_same_return_type: diag(2510, ts.DiagnosticCategory.Error, "Base_constructors_must_all_have_the_same_return_type_2510", "Base constructors must all have the same return type."), Cannot_create_an_instance_of_an_abstract_class: diag(2511, ts.DiagnosticCategory.Error, "Cannot_create_an_instance_of_an_abstract_class_2511", "Cannot create an instance of an abstract class."), Overload_signatures_must_all_be_abstract_or_non_abstract: diag(2512, ts.DiagnosticCategory.Error, "Overload_signatures_must_all_be_abstract_or_non_abstract_2512", "Overload signatures must all be abstract or non-abstract."), Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: diag(2513, ts.DiagnosticCategory.Error, "Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression_2513", "Abstract method '{0}' in class '{1}' cannot be accessed via super expression."), Classes_containing_abstract_methods_must_be_marked_abstract: diag(2514, ts.DiagnosticCategory.Error, "Classes_containing_abstract_methods_must_be_marked_abstract_2514", "Classes containing abstract methods must be marked abstract."), Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: diag(2515, ts.DiagnosticCategory.Error, "Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2_2515", "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'."), All_declarations_of_an_abstract_method_must_be_consecutive: diag(2516, ts.DiagnosticCategory.Error, "All_declarations_of_an_abstract_method_must_be_consecutive_2516", "All declarations of an abstract method must be consecutive."), Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type: diag(2517, ts.DiagnosticCategory.Error, "Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type_2517", "Cannot assign an abstract constructor type to a non-abstract constructor type."), A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard: diag(2518, ts.DiagnosticCategory.Error, "A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard_2518", "A 'this'-based type guard is not compatible with a parameter-based type guard."), An_async_iterator_must_have_a_next_method: diag(2519, ts.DiagnosticCategory.Error, "An_async_iterator_must_have_a_next_method_2519", "An async iterator must have a 'next()' method."), Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: diag(2520, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions_2520", "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions."), Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: diag(2521, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions_2521", "Expression resolves to variable declaration '{0}' that compiler uses to support async functions."), The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method: diag(2522, ts.DiagnosticCategory.Error, "The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_usi_2522", "The 'arguments' object cannot be referenced in an async function or method in ES3 and ES5. Consider using a standard function or method."), yield_expressions_cannot_be_used_in_a_parameter_initializer: diag(2523, ts.DiagnosticCategory.Error, "yield_expressions_cannot_be_used_in_a_parameter_initializer_2523", "'yield' expressions cannot be used in a parameter initializer."), await_expressions_cannot_be_used_in_a_parameter_initializer: diag(2524, ts.DiagnosticCategory.Error, "await_expressions_cannot_be_used_in_a_parameter_initializer_2524", "'await' expressions cannot be used in a parameter initializer."), Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value: diag(2525, ts.DiagnosticCategory.Error, "Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value_2525", "Initializer provides no value for this binding element and the binding element has no default value."), A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface: diag(2526, ts.DiagnosticCategory.Error, "A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface_2526", "A 'this' type is available only in a non-static member of a class or interface."), The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary: diag(2527, ts.DiagnosticCategory.Error, "The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527", "The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary."), A_module_cannot_have_multiple_default_exports: diag(2528, ts.DiagnosticCategory.Error, "A_module_cannot_have_multiple_default_exports_2528", "A module cannot have multiple default exports."), Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions: diag(2529, ts.DiagnosticCategory.Error, "Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_func_2529", "Duplicate identifier '{0}'. Compiler reserves name '{1}' in top level scope of a module containing async functions."), Property_0_is_incompatible_with_index_signature: diag(2530, ts.DiagnosticCategory.Error, "Property_0_is_incompatible_with_index_signature_2530", "Property '{0}' is incompatible with index signature."), Object_is_possibly_null: diag(2531, ts.DiagnosticCategory.Error, "Object_is_possibly_null_2531", "Object is possibly 'null'."), Object_is_possibly_undefined: diag(2532, ts.DiagnosticCategory.Error, "Object_is_possibly_undefined_2532", "Object is possibly 'undefined'."), Object_is_possibly_null_or_undefined: diag(2533, ts.DiagnosticCategory.Error, "Object_is_possibly_null_or_undefined_2533", "Object is possibly 'null' or 'undefined'."), A_function_returning_never_cannot_have_a_reachable_end_point: diag(2534, ts.DiagnosticCategory.Error, "A_function_returning_never_cannot_have_a_reachable_end_point_2534", "A function returning 'never' cannot have a reachable end point."), Enum_type_0_has_members_with_initializers_that_are_not_literals: diag(2535, ts.DiagnosticCategory.Error, "Enum_type_0_has_members_with_initializers_that_are_not_literals_2535", "Enum type '{0}' has members with initializers that are not literals."), Type_0_cannot_be_used_to_index_type_1: diag(2536, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_to_index_type_1_2536", "Type '{0}' cannot be used to index type '{1}'."), Type_0_has_no_matching_index_signature_for_type_1: diag(2537, ts.DiagnosticCategory.Error, "Type_0_has_no_matching_index_signature_for_type_1_2537", "Type '{0}' has no matching index signature for type '{1}'."), Type_0_cannot_be_used_as_an_index_type: diag(2538, ts.DiagnosticCategory.Error, "Type_0_cannot_be_used_as_an_index_type_2538", "Type '{0}' cannot be used as an index type."), Cannot_assign_to_0_because_it_is_not_a_variable: diag(2539, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_not_a_variable_2539", "Cannot assign to '{0}' because it is not a variable."), Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property: diag(2540, ts.DiagnosticCategory.Error, "Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property_2540", "Cannot assign to '{0}' because it is a constant or a read-only property."), The_target_of_an_assignment_must_be_a_variable_or_a_property_access: diag(2541, ts.DiagnosticCategory.Error, "The_target_of_an_assignment_must_be_a_variable_or_a_property_access_2541", "The target of an assignment must be a variable or a property access."), Index_signature_in_type_0_only_permits_reading: diag(2542, ts.DiagnosticCategory.Error, "Index_signature_in_type_0_only_permits_reading_2542", "Index signature in type '{0}' only permits reading."), Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference: diag(2543, ts.DiagnosticCategory.Error, "Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_me_2543", "Duplicate identifier '_newTarget'. Compiler uses variable declaration '_newTarget' to capture 'new.target' meta-property reference."), Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference: diag(2544, ts.DiagnosticCategory.Error, "Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta__2544", "Expression resolves to variable declaration '_newTarget' that compiler uses to capture 'new.target' meta-property reference."), A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any: diag(2545, ts.DiagnosticCategory.Error, "A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any_2545", "A mixin class must have a constructor with a single rest parameter of type 'any[]'."), Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1: diag(2546, ts.DiagnosticCategory.Error, "Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1_2546", "Property '{0}' has conflicting declarations and is inaccessible in type '{1}'."), The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property: diag(2547, ts.DiagnosticCategory.Error, "The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value__2547", "The type returned by the 'next()' method of an async iterator must be a promise for a type with a 'value' property."), Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2548, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator_2548", "Type '{0}' is not an array type or does not have a '[Symbol.iterator]()' method that returns an iterator."), Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator: diag(2549, ts.DiagnosticCategory.Error, "Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns__2549", "Type '{0}' is not an array type or a string type or does not have a '[Symbol.iterator]()' method that returns an iterator."), Generic_type_instantiation_is_excessively_deep_and_possibly_infinite: diag(2550, ts.DiagnosticCategory.Error, "Generic_type_instantiation_is_excessively_deep_and_possibly_infinite_2550", "Generic type instantiation is excessively deep and possibly infinite."), Property_0_does_not_exist_on_type_1_Did_you_mean_2: diag(2551, ts.DiagnosticCategory.Error, "Property_0_does_not_exist_on_type_1_Did_you_mean_2_2551", "Property '{0}' does not exist on type '{1}'. Did you mean '{2}'?"), Cannot_find_name_0_Did_you_mean_1: diag(2552, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_1_2552", "Cannot find name '{0}'. Did you mean '{1}'?"), Computed_values_are_not_permitted_in_an_enum_with_string_valued_members: diag(2553, ts.DiagnosticCategory.Error, "Computed_values_are_not_permitted_in_an_enum_with_string_valued_members_2553", "Computed values are not permitted in an enum with string valued members."), Expected_0_arguments_but_got_1: diag(2554, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_2554", "Expected {0} arguments, but got {1}."), Expected_at_least_0_arguments_but_got_1: diag(2555, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_2555", "Expected at least {0} arguments, but got {1}."), Expected_0_arguments_but_got_1_or_more: diag(2556, ts.DiagnosticCategory.Error, "Expected_0_arguments_but_got_1_or_more_2556", "Expected {0} arguments, but got {1} or more."), Expected_at_least_0_arguments_but_got_1_or_more: diag(2557, ts.DiagnosticCategory.Error, "Expected_at_least_0_arguments_but_got_1_or_more_2557", "Expected at least {0} arguments, but got {1} or more."), Expected_0_type_arguments_but_got_1: diag(2558, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_but_got_1_2558", "Expected {0} type arguments, but got {1}."), Type_0_has_no_properties_in_common_with_type_1: diag(2559, ts.DiagnosticCategory.Error, "Type_0_has_no_properties_in_common_with_type_1_2559", "Type '{0}' has no properties in common with type '{1}'."), Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it: diag(2560, ts.DiagnosticCategory.Error, "Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it_2560", "Value of type '{0}' has no properties in common with type '{1}'. Did you mean to call it?"), Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2: diag(2561, ts.DiagnosticCategory.Error, "Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_writ_2561", "Object literal may only specify known properties, but '{0}' does not exist in type '{1}'. Did you mean to write '{2}'?"), Base_class_expressions_cannot_reference_class_type_parameters: diag(2562, ts.DiagnosticCategory.Error, "Base_class_expressions_cannot_reference_class_type_parameters_2562", "Base class expressions cannot reference class type parameters."), The_containing_function_or_module_body_is_too_large_for_control_flow_analysis: diag(2563, ts.DiagnosticCategory.Error, "The_containing_function_or_module_body_is_too_large_for_control_flow_analysis_2563", "The containing function or module body is too large for control flow analysis."), Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor: diag(2564, ts.DiagnosticCategory.Error, "Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor_2564", "Property '{0}' has no initializer and is not definitely assigned in the constructor."), Property_0_is_used_before_being_assigned: diag(2565, ts.DiagnosticCategory.Error, "Property_0_is_used_before_being_assigned_2565", "Property '{0}' is used before being assigned."), JSX_element_attributes_type_0_may_not_be_a_union_type: diag(2600, ts.DiagnosticCategory.Error, "JSX_element_attributes_type_0_may_not_be_a_union_type_2600", "JSX element attributes type '{0}' may not be a union type."), The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: diag(2601, ts.DiagnosticCategory.Error, "The_return_type_of_a_JSX_element_constructor_must_return_an_object_type_2601", "The return type of a JSX element constructor must return an object type."), JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: diag(2602, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist_2602", "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist."), Property_0_in_type_1_is_not_assignable_to_type_2: diag(2603, ts.DiagnosticCategory.Error, "Property_0_in_type_1_is_not_assignable_to_type_2_2603", "Property '{0}' in type '{1}' is not assignable to type '{2}'."), JSX_element_type_0_does_not_have_any_construct_or_call_signatures: diag(2604, ts.DiagnosticCategory.Error, "JSX_element_type_0_does_not_have_any_construct_or_call_signatures_2604", "JSX element type '{0}' does not have any construct or call signatures."), JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements: diag(2605, ts.DiagnosticCategory.Error, "JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements_2605", "JSX element type '{0}' is not a constructor function for JSX elements."), Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property: diag(2606, ts.DiagnosticCategory.Error, "Property_0_of_JSX_spread_attribute_is_not_assignable_to_target_property_2606", "Property '{0}' of JSX spread attribute is not assignable to target property."), JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property: diag(2607, ts.DiagnosticCategory.Error, "JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property_2607", "JSX element class does not support attributes because it does not have a '{0}' property."), The_global_type_JSX_0_may_not_have_more_than_one_property: diag(2608, ts.DiagnosticCategory.Error, "The_global_type_JSX_0_may_not_have_more_than_one_property_2608", "The global type 'JSX.{0}' may not have more than one property."), JSX_spread_child_must_be_an_array_type: diag(2609, ts.DiagnosticCategory.Error, "JSX_spread_child_must_be_an_array_type_2609", "JSX spread child must be an array type."), Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity: diag(2649, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity_2649", "Cannot augment module '{0}' with value exports because it resolves to a non-module entity."), A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums: diag(2651, ts.DiagnosticCategory.Error, "A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_memb_2651", "A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums."), Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead: diag(2652, ts.DiagnosticCategory.Error, "Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_d_2652", "Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead."), Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1: diag(2653, ts.DiagnosticCategory.Error, "Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1_2653", "Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'."), Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_package_author_to_update_the_package_definition: diag(2654, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_cannot_contain_tripleslash_references_Please_contact_the_pack_2654", "Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition."), Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_the_package_definition: diag(2656, ts.DiagnosticCategory.Error, "Exported_external_package_typings_file_0_is_not_a_module_Please_contact_the_package_author_to_update_2656", "Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition."), JSX_expressions_must_have_one_parent_element: diag(2657, ts.DiagnosticCategory.Error, "JSX_expressions_must_have_one_parent_element_2657", "JSX expressions must have one parent element."), Type_0_provides_no_match_for_the_signature_1: diag(2658, ts.DiagnosticCategory.Error, "Type_0_provides_no_match_for_the_signature_1_2658", "Type '{0}' provides no match for the signature '{1}'."), super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher: diag(2659, ts.DiagnosticCategory.Error, "super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_highe_2659", "'super' is only allowed in members of object literal expressions when option 'target' is 'ES2015' or higher."), super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions: diag(2660, ts.DiagnosticCategory.Error, "super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions_2660", "'super' can only be referenced in members of derived classes or object literal expressions."), Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module: diag(2661, ts.DiagnosticCategory.Error, "Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module_2661", "Cannot export '{0}'. Only local declarations can be exported from a module."), Cannot_find_name_0_Did_you_mean_the_static_member_1_0: diag(2662, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_static_member_1_0_2662", "Cannot find name '{0}'. Did you mean the static member '{1}.{0}'?"), Cannot_find_name_0_Did_you_mean_the_instance_member_this_0: diag(2663, ts.DiagnosticCategory.Error, "Cannot_find_name_0_Did_you_mean_the_instance_member_this_0_2663", "Cannot find name '{0}'. Did you mean the instance member 'this.{0}'?"), Invalid_module_name_in_augmentation_module_0_cannot_be_found: diag(2664, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_module_0_cannot_be_found_2664", "Invalid module name in augmentation, module '{0}' cannot be found."), Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented: diag(2665, ts.DiagnosticCategory.Error, "Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augm_2665", "Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented."), Exports_and_export_assignments_are_not_permitted_in_module_augmentations: diag(2666, ts.DiagnosticCategory.Error, "Exports_and_export_assignments_are_not_permitted_in_module_augmentations_2666", "Exports and export assignments are not permitted in module augmentations."), Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module: diag(2667, ts.DiagnosticCategory.Error, "Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_mod_2667", "Imports are not permitted in module augmentations. Consider moving them to the enclosing external module."), export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible: diag(2668, ts.DiagnosticCategory.Error, "export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always__2668", "'export' modifier cannot be applied to ambient modules and module augmentations since they are always visible."), Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations: diag(2669, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_2669", "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."), Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambient_context: diag(2670, ts.DiagnosticCategory.Error, "Augmentations_for_the_global_scope_should_have_declare_modifier_unless_they_appear_in_already_ambien_2670", "Augmentations for the global scope should have 'declare' modifier unless they appear in already ambient context."), Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity: diag(2671, ts.DiagnosticCategory.Error, "Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity_2671", "Cannot augment module '{0}' because it resolves to a non-module entity."), Cannot_assign_a_0_constructor_type_to_a_1_constructor_type: diag(2672, ts.DiagnosticCategory.Error, "Cannot_assign_a_0_constructor_type_to_a_1_constructor_type_2672", "Cannot assign a '{0}' constructor type to a '{1}' constructor type."), Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration: diag(2673, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration_2673", "Constructor of class '{0}' is private and only accessible within the class declaration."), Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration: diag(2674, ts.DiagnosticCategory.Error, "Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration_2674", "Constructor of class '{0}' is protected and only accessible within the class declaration."), Cannot_extend_a_class_0_Class_constructor_is_marked_as_private: diag(2675, ts.DiagnosticCategory.Error, "Cannot_extend_a_class_0_Class_constructor_is_marked_as_private_2675", "Cannot extend a class '{0}'. Class constructor is marked as private."), Accessors_must_both_be_abstract_or_non_abstract: diag(2676, ts.DiagnosticCategory.Error, "Accessors_must_both_be_abstract_or_non_abstract_2676", "Accessors must both be abstract or non-abstract."), A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type: diag(2677, ts.DiagnosticCategory.Error, "A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type_2677", "A type predicate's type must be assignable to its parameter's type."), Type_0_is_not_comparable_to_type_1: diag(2678, ts.DiagnosticCategory.Error, "Type_0_is_not_comparable_to_type_1_2678", "Type '{0}' is not comparable to type '{1}'."), A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void: diag(2679, ts.DiagnosticCategory.Error, "A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void_2679", "A function that is called with the 'new' keyword cannot have a 'this' type that is 'void'."), A_0_parameter_must_be_the_first_parameter: diag(2680, ts.DiagnosticCategory.Error, "A_0_parameter_must_be_the_first_parameter_2680", "A '{0}' parameter must be the first parameter."), A_constructor_cannot_have_a_this_parameter: diag(2681, ts.DiagnosticCategory.Error, "A_constructor_cannot_have_a_this_parameter_2681", "A constructor cannot have a 'this' parameter."), get_and_set_accessor_must_have_the_same_this_type: diag(2682, ts.DiagnosticCategory.Error, "get_and_set_accessor_must_have_the_same_this_type_2682", "'get' and 'set' accessor must have the same 'this' type."), this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation: diag(2683, ts.DiagnosticCategory.Error, "this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_2683", "'this' implicitly has type 'any' because it does not have a type annotation."), The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1: diag(2684, ts.DiagnosticCategory.Error, "The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1_2684", "The 'this' context of type '{0}' is not assignable to method's 'this' of type '{1}'."), The_this_types_of_each_signature_are_incompatible: diag(2685, ts.DiagnosticCategory.Error, "The_this_types_of_each_signature_are_incompatible_2685", "The 'this' types of each signature are incompatible."), _0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead: diag(2686, ts.DiagnosticCategory.Error, "_0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead_2686", "'{0}' refers to a UMD global, but the current file is a module. Consider adding an import instead."), All_declarations_of_0_must_have_identical_modifiers: diag(2687, ts.DiagnosticCategory.Error, "All_declarations_of_0_must_have_identical_modifiers_2687", "All declarations of '{0}' must have identical modifiers."), Cannot_find_type_definition_file_for_0: diag(2688, ts.DiagnosticCategory.Error, "Cannot_find_type_definition_file_for_0_2688", "Cannot find type definition file for '{0}'."), Cannot_extend_an_interface_0_Did_you_mean_implements: diag(2689, ts.DiagnosticCategory.Error, "Cannot_extend_an_interface_0_Did_you_mean_implements_2689", "Cannot extend an interface '{0}'. Did you mean 'implements'?"), An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead: diag(2691, ts.DiagnosticCategory.Error, "An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead_2691", "An import path cannot end with a '{0}' extension. Consider importing '{1}' instead."), _0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible: diag(2692, ts.DiagnosticCategory.Error, "_0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible_2692", "'{0}' is a primitive, but '{1}' is a wrapper object. Prefer using '{0}' when possible."), _0_only_refers_to_a_type_but_is_being_used_as_a_value_here: diag(2693, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_value_here_2693", "'{0}' only refers to a type, but is being used as a value here."), Namespace_0_has_no_exported_member_1: diag(2694, ts.DiagnosticCategory.Error, "Namespace_0_has_no_exported_member_1_2694", "Namespace '{0}' has no exported member '{1}'."), Left_side_of_comma_operator_is_unused_and_has_no_side_effects: diag(2695, ts.DiagnosticCategory.Error, "Left_side_of_comma_operator_is_unused_and_has_no_side_effects_2695", "Left side of comma operator is unused and has no side effects."), The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead: diag(2696, ts.DiagnosticCategory.Error, "The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead_2696", "The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?"), An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2697, ts.DiagnosticCategory.Error, "An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_in_2697", "An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."), Spread_types_may_only_be_created_from_object_types: diag(2698, ts.DiagnosticCategory.Error, "Spread_types_may_only_be_created_from_object_types_2698", "Spread types may only be created from object types."), Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1: diag(2699, ts.DiagnosticCategory.Error, "Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1_2699", "Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'."), Rest_types_may_only_be_created_from_object_types: diag(2700, ts.DiagnosticCategory.Error, "Rest_types_may_only_be_created_from_object_types_2700", "Rest types may only be created from object types."), The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access: diag(2701, ts.DiagnosticCategory.Error, "The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access_2701", "The target of an object rest assignment must be a variable or a property access."), _0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here: diag(2702, ts.DiagnosticCategory.Error, "_0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here_2702", "'{0}' only refers to a type, but is being used as a namespace here."), The_operand_of_a_delete_operator_must_be_a_property_reference: diag(2703, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_must_be_a_property_reference_2703", "The operand of a delete operator must be a property reference."), The_operand_of_a_delete_operator_cannot_be_a_read_only_property: diag(2704, ts.DiagnosticCategory.Error, "The_operand_of_a_delete_operator_cannot_be_a_read_only_property_2704", "The operand of a delete operator cannot be a read-only property."), An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2705, ts.DiagnosticCategory.Error, "An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_de_2705", "An async function or method in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."), Required_type_parameters_may_not_follow_optional_type_parameters: diag(2706, ts.DiagnosticCategory.Error, "Required_type_parameters_may_not_follow_optional_type_parameters_2706", "Required type parameters may not follow optional type parameters."), Generic_type_0_requires_between_1_and_2_type_arguments: diag(2707, ts.DiagnosticCategory.Error, "Generic_type_0_requires_between_1_and_2_type_arguments_2707", "Generic type '{0}' requires between {1} and {2} type arguments."), Cannot_use_namespace_0_as_a_value: diag(2708, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_value_2708", "Cannot use namespace '{0}' as a value."), Cannot_use_namespace_0_as_a_type: diag(2709, ts.DiagnosticCategory.Error, "Cannot_use_namespace_0_as_a_type_2709", "Cannot use namespace '{0}' as a type."), _0_are_specified_twice_The_attribute_named_0_will_be_overwritten: diag(2710, ts.DiagnosticCategory.Error, "_0_are_specified_twice_The_attribute_named_0_will_be_overwritten_2710", "'{0}' are specified twice. The attribute named '{0}' will be overwritten."), A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option: diag(2711, ts.DiagnosticCategory.Error, "A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES20_2711", "A dynamic import call returns a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option."), A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option: diag(2712, ts.DiagnosticCategory.Error, "A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declarat_2712", "A dynamic import call in ES5/ES3 requires the 'Promise' constructor. Make sure you have a declaration for the 'Promise' constructor or include 'ES2015' in your `--lib` option."), Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1: diag(2713, ts.DiagnosticCategory.Error, "Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_p_2713", "Cannot access '{0}.{1}' because '{0}' is a type, but not a namespace. Did you mean to retrieve the type of the property '{1}' in '{0}' with '{0}[\"{1}\"]'?"), The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context: diag(2714, ts.DiagnosticCategory.Error, "The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context_2714", "The expression of an export assignment must be an identifier or qualified name in an ambient context."), Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor: diag(2715, ts.DiagnosticCategory.Error, "Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor_2715", "Abstract property '{0}' in class '{1}' cannot be accessed in the constructor."), Type_parameter_0_has_a_circular_default: diag(2716, ts.DiagnosticCategory.Error, "Type_parameter_0_has_a_circular_default_2716", "Type parameter '{0}' has a circular default."), Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2: diag(2717, ts.DiagnosticCategory.Error, "Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_t_2717", "Subsequent property declarations must have the same type. Property '{0}' must be of type '{1}', but here has type '{2}'."), Duplicate_declaration_0: diag(2718, ts.DiagnosticCategory.Error, "Duplicate_declaration_0_2718", "Duplicate declaration '{0}'."), Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated: diag(2719, ts.DiagnosticCategory.Error, "Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated_2719", "Type '{0}' is not assignable to type '{1}'. Two different types with this name exist, but they are unrelated."), Import_declaration_0_is_using_private_name_1: diag(4000, ts.DiagnosticCategory.Error, "Import_declaration_0_is_using_private_name_1_4000", "Import declaration '{0}' is using private name '{1}'."), Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: diag(4002, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_class_has_or_is_using_private_name_1_4002", "Type parameter '{0}' of exported class has or is using private name '{1}'."), Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: diag(4004, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1_4004", "Type parameter '{0}' of exported interface has or is using private name '{1}'."), Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4006, ts.DiagnosticCategory.Error, "Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4006", "Type parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."), Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4008, ts.DiagnosticCategory.Error, "Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4008", "Type parameter '{0}' of call signature from exported interface has or is using private name '{1}'."), Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4010, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4010", "Type parameter '{0}' of public static method from exported class has or is using private name '{1}'."), Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4012, ts.DiagnosticCategory.Error, "Type_parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4012", "Type parameter '{0}' of public method from exported class has or is using private name '{1}'."), Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4014, ts.DiagnosticCategory.Error, "Type_parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4014", "Type parameter '{0}' of method from exported interface has or is using private name '{1}'."), Type_parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4016, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_function_has_or_is_using_private_name_1_4016", "Type parameter '{0}' of exported function has or is using private name '{1}'."), Implements_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4019, ts.DiagnosticCategory.Error, "Implements_clause_of_exported_class_0_has_or_is_using_private_name_1_4019", "Implements clause of exported class '{0}' has or is using private name '{1}'."), extends_clause_of_exported_class_0_has_or_is_using_private_name_1: diag(4020, ts.DiagnosticCategory.Error, "extends_clause_of_exported_class_0_has_or_is_using_private_name_1_4020", "'extends' clause of exported class '{0}' has or is using private name '{1}'."), extends_clause_of_exported_interface_0_has_or_is_using_private_name_1: diag(4022, ts.DiagnosticCategory.Error, "extends_clause_of_exported_interface_0_has_or_is_using_private_name_1_4022", "'extends' clause of exported interface '{0}' has or is using private name '{1}'."), Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4023, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4023", "Exported variable '{0}' has or is using name '{1}' from external module {2} but cannot be named."), Exported_variable_0_has_or_is_using_name_1_from_private_module_2: diag(4024, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_name_1_from_private_module_2_4024", "Exported variable '{0}' has or is using name '{1}' from private module '{2}'."), Exported_variable_0_has_or_is_using_private_name_1: diag(4025, ts.DiagnosticCategory.Error, "Exported_variable_0_has_or_is_using_private_name_1_4025", "Exported variable '{0}' has or is using private name '{1}'."), Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4026, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot__4026", "Public static property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."), Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4027, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4027", "Public static property '{0}' of exported class has or is using name '{1}' from private module '{2}'."), Public_static_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4028, ts.DiagnosticCategory.Error, "Public_static_property_0_of_exported_class_has_or_is_using_private_name_1_4028", "Public static property '{0}' of exported class has or is using private name '{1}'."), Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4029, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_name_4029", "Public property '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."), Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4030, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4030", "Public property '{0}' of exported class has or is using name '{1}' from private module '{2}'."), Public_property_0_of_exported_class_has_or_is_using_private_name_1: diag(4031, ts.DiagnosticCategory.Error, "Public_property_0_of_exported_class_has_or_is_using_private_name_1_4031", "Public property '{0}' of exported class has or is using private name '{1}'."), Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4032, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4032", "Property '{0}' of exported interface has or is using name '{1}' from private module '{2}'."), Property_0_of_exported_interface_has_or_is_using_private_name_1: diag(4033, ts.DiagnosticCategory.Error, "Property_0_of_exported_interface_has_or_is_using_private_name_1_4033", "Property '{0}' of exported interface has or is using private name '{1}'."), Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4034, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_mod_4034", "Parameter type of public static setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."), Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4035, ts.DiagnosticCategory.Error, "Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1_4035", "Parameter type of public static setter '{0}' from exported class has or is using private name '{1}'."), Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4036, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4036", "Parameter type of public setter '{0}' from exported class has or is using name '{1}' from private module '{2}'."), Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1: diag(4037, ts.DiagnosticCategory.Error, "Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1_4037", "Parameter type of public setter '{0}' from exported class has or is using private name '{1}'."), Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4038, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_modul_4038", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."), Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4039, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_4039", "Return type of public static getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."), Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4040, ts.DiagnosticCategory.Error, "Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1_4040", "Return type of public static getter '{0}' from exported class has or is using private name '{1}'."), Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4041, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_4041", "Return type of public getter '{0}' from exported class has or is using name '{1}' from external module {2} but cannot be named."), Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4042, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2_4042", "Return type of public getter '{0}' from exported class has or is using name '{1}' from private module '{2}'."), Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1: diag(4043, ts.DiagnosticCategory.Error, "Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1_4043", "Return type of public getter '{0}' from exported class has or is using private name '{1}'."), Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4044, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_name_0_from_private_mod_4044", "Return type of constructor signature from exported interface has or is using name '{0}' from private module '{1}'."), Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4045, ts.DiagnosticCategory.Error, "Return_type_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_0_4045", "Return type of constructor signature from exported interface has or is using private name '{0}'."), Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4046, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4046", "Return type of call signature from exported interface has or is using name '{0}' from private module '{1}'."), Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4047, ts.DiagnosticCategory.Error, "Return_type_of_call_signature_from_exported_interface_has_or_is_using_private_name_0_4047", "Return type of call signature from exported interface has or is using private name '{0}'."), Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4048, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4048", "Return type of index signature from exported interface has or is using name '{0}' from private module '{1}'."), Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0: diag(4049, ts.DiagnosticCategory.Error, "Return_type_of_index_signature_from_exported_interface_has_or_is_using_private_name_0_4049", "Return type of index signature from exported interface has or is using private name '{0}'."), Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4050, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module__4050", "Return type of public static method from exported class has or is using name '{0}' from external module {1} but cannot be named."), Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4051, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4051", "Return type of public static method from exported class has or is using name '{0}' from private module '{1}'."), Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0: diag(4052, ts.DiagnosticCategory.Error, "Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0_4052", "Return type of public static method from exported class has or is using private name '{0}'."), Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4053, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_c_4053", "Return type of public method from exported class has or is using name '{0}' from external module {1} but cannot be named."), Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1: diag(4054, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_name_0_from_private_module_1_4054", "Return type of public method from exported class has or is using name '{0}' from private module '{1}'."), Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0: diag(4055, ts.DiagnosticCategory.Error, "Return_type_of_public_method_from_exported_class_has_or_is_using_private_name_0_4055", "Return type of public method from exported class has or is using private name '{0}'."), Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1: diag(4056, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_name_0_from_private_module_1_4056", "Return type of method from exported interface has or is using name '{0}' from private module '{1}'."), Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0: diag(4057, ts.DiagnosticCategory.Error, "Return_type_of_method_from_exported_interface_has_or_is_using_private_name_0_4057", "Return type of method from exported interface has or is using private name '{0}'."), Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named: diag(4058, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named_4058", "Return type of exported function has or is using name '{0}' from external module {1} but cannot be named."), Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1: diag(4059, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_name_0_from_private_module_1_4059", "Return type of exported function has or is using name '{0}' from private module '{1}'."), Return_type_of_exported_function_has_or_is_using_private_name_0: diag(4060, ts.DiagnosticCategory.Error, "Return_type_of_exported_function_has_or_is_using_private_name_0_4060", "Return type of exported function has or is using private name '{0}'."), Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4061, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_can_4061", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from external module {2} but cannot be named."), Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4062, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_name_1_from_private_module_2_4062", "Parameter '{0}' of constructor from exported class has or is using name '{1}' from private module '{2}'."), Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1: diag(4063, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_from_exported_class_has_or_is_using_private_name_1_4063", "Parameter '{0}' of constructor from exported class has or is using private name '{1}'."), Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4064, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_name_1_from_private_mod_4064", "Parameter '{0}' of constructor signature from exported interface has or is using name '{1}' from private module '{2}'."), Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4065, ts.DiagnosticCategory.Error, "Parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1_4065", "Parameter '{0}' of constructor signature from exported interface has or is using private name '{1}'."), Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4066, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4066", "Parameter '{0}' of call signature from exported interface has or is using name '{1}' from private module '{2}'."), Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4067, ts.DiagnosticCategory.Error, "Parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1_4067", "Parameter '{0}' of call signature from exported interface has or is using private name '{1}'."), Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4068, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module__4068", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from external module {2} but cannot be named."), Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4069, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4069", "Parameter '{0}' of public static method from exported class has or is using name '{1}' from private module '{2}'."), Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1: diag(4070, ts.DiagnosticCategory.Error, "Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1_4070", "Parameter '{0}' of public static method from exported class has or is using private name '{1}'."), Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4071, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_c_4071", "Parameter '{0}' of public method from exported class has or is using name '{1}' from external module {2} but cannot be named."), Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4072, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_name_1_from_private_module_2_4072", "Parameter '{0}' of public method from exported class has or is using name '{1}' from private module '{2}'."), Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1: diag(4073, ts.DiagnosticCategory.Error, "Parameter_0_of_public_method_from_exported_class_has_or_is_using_private_name_1_4073", "Parameter '{0}' of public method from exported class has or is using private name '{1}'."), Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4074, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4074", "Parameter '{0}' of method from exported interface has or is using name '{1}' from private module '{2}'."), Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1: diag(4075, ts.DiagnosticCategory.Error, "Parameter_0_of_method_from_exported_interface_has_or_is_using_private_name_1_4075", "Parameter '{0}' of method from exported interface has or is using private name '{1}'."), Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4076, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4076", "Parameter '{0}' of exported function has or is using name '{1}' from external module {2} but cannot be named."), Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2: diag(4077, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_name_1_from_private_module_2_4077", "Parameter '{0}' of exported function has or is using name '{1}' from private module '{2}'."), Parameter_0_of_exported_function_has_or_is_using_private_name_1: diag(4078, ts.DiagnosticCategory.Error, "Parameter_0_of_exported_function_has_or_is_using_private_name_1_4078", "Parameter '{0}' of exported function has or is using private name '{1}'."), Exported_type_alias_0_has_or_is_using_private_name_1: diag(4081, ts.DiagnosticCategory.Error, "Exported_type_alias_0_has_or_is_using_private_name_1_4081", "Exported type alias '{0}' has or is using private name '{1}'."), Default_export_of_the_module_has_or_is_using_private_name_0: diag(4082, ts.DiagnosticCategory.Error, "Default_export_of_the_module_has_or_is_using_private_name_0_4082", "Default export of the module has or is using private name '{0}'."), Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1: diag(4083, ts.DiagnosticCategory.Error, "Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1_4083", "Type parameter '{0}' of exported type alias has or is using private name '{1}'."), Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict: diag(4090, ts.DiagnosticCategory.Message, "Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_librar_4090", "Conflicting definitions for '{0}' found at '{1}' and '{2}'. Consider installing a specific version of this library to resolve the conflict."), Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4091, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2_4091", "Parameter '{0}' of index signature from exported interface has or is using name '{1}' from private module '{2}'."), Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1: diag(4092, ts.DiagnosticCategory.Error, "Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1_4092", "Parameter '{0}' of index signature from exported interface has or is using private name '{1}'."), Property_0_of_exported_class_expression_may_not_be_private_or_protected: diag(4094, ts.DiagnosticCategory.Error, "Property_0_of_exported_class_expression_may_not_be_private_or_protected_4094", "Property '{0}' of exported class expression may not be private or protected."), Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4095, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_4095", "Public static method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."), Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4096, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4096", "Public static method '{0}' of exported class has or is using name '{1}' from private module '{2}'."), Public_static_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4097, ts.DiagnosticCategory.Error, "Public_static_method_0_of_exported_class_has_or_is_using_private_name_1_4097", "Public static method '{0}' of exported class has or is using private name '{1}'."), Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named: diag(4098, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named_4098", "Public method '{0}' of exported class has or is using name '{1}' from external module {2} but cannot be named."), Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: diag(4099, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2_4099", "Public method '{0}' of exported class has or is using name '{1}' from private module '{2}'."), Public_method_0_of_exported_class_has_or_is_using_private_name_1: diag(4100, ts.DiagnosticCategory.Error, "Public_method_0_of_exported_class_has_or_is_using_private_name_1_4100", "Public method '{0}' of exported class has or is using private name '{1}'."), Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2: diag(4101, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2_4101", "Method '{0}' of exported interface has or is using name '{1}' from private module '{2}'."), Method_0_of_exported_interface_has_or_is_using_private_name_1: diag(4102, ts.DiagnosticCategory.Error, "Method_0_of_exported_interface_has_or_is_using_private_name_1_4102", "Method '{0}' of exported interface has or is using private name '{1}'."), The_current_host_does_not_support_the_0_option: diag(5001, ts.DiagnosticCategory.Error, "The_current_host_does_not_support_the_0_option_5001", "The current host does not support the '{0}' option."), Cannot_find_the_common_subdirectory_path_for_the_input_files: diag(5009, ts.DiagnosticCategory.Error, "Cannot_find_the_common_subdirectory_path_for_the_input_files_5009", "Cannot find the common subdirectory path for the input files."), File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5010, ts.DiagnosticCategory.Error, "File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0_5010", "File specification cannot end in a recursive directory wildcard ('**'): '{0}'."), File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0: diag(5011, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0_5011", "File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'."), Cannot_read_file_0_Colon_1: diag(5012, ts.DiagnosticCategory.Error, "Cannot_read_file_0_Colon_1_5012", "Cannot read file '{0}': {1}."), Failed_to_parse_file_0_Colon_1: diag(5014, ts.DiagnosticCategory.Error, "Failed_to_parse_file_0_Colon_1_5014", "Failed to parse file '{0}': {1}."), Unknown_compiler_option_0: diag(5023, ts.DiagnosticCategory.Error, "Unknown_compiler_option_0_5023", "Unknown compiler option '{0}'."), Compiler_option_0_requires_a_value_of_type_1: diag(5024, ts.DiagnosticCategory.Error, "Compiler_option_0_requires_a_value_of_type_1_5024", "Compiler option '{0}' requires a value of type {1}."), Could_not_write_file_0_Colon_1: diag(5033, ts.DiagnosticCategory.Error, "Could_not_write_file_0_Colon_1_5033", "Could not write file '{0}': {1}."), Option_project_cannot_be_mixed_with_source_files_on_a_command_line: diag(5042, ts.DiagnosticCategory.Error, "Option_project_cannot_be_mixed_with_source_files_on_a_command_line_5042", "Option 'project' cannot be mixed with source files on a command line."), Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher: diag(5047, ts.DiagnosticCategory.Error, "Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES_5047", "Option 'isolatedModules' can only be used when either option '--module' is provided or option 'target' is 'ES2015' or higher."), Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: diag(5051, ts.DiagnosticCategory.Error, "Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided_5051", "Option '{0} can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided."), Option_0_cannot_be_specified_without_specifying_option_1: diag(5052, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_without_specifying_option_1_5052", "Option '{0}' cannot be specified without specifying option '{1}'."), Option_0_cannot_be_specified_with_option_1: diag(5053, ts.DiagnosticCategory.Error, "Option_0_cannot_be_specified_with_option_1_5053", "Option '{0}' cannot be specified with option '{1}'."), A_tsconfig_json_file_is_already_defined_at_Colon_0: diag(5054, ts.DiagnosticCategory.Error, "A_tsconfig_json_file_is_already_defined_at_Colon_0_5054", "A 'tsconfig.json' file is already defined at: '{0}'."), Cannot_write_file_0_because_it_would_overwrite_input_file: diag(5055, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_overwrite_input_file_5055", "Cannot write file '{0}' because it would overwrite input file."), Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files: diag(5056, ts.DiagnosticCategory.Error, "Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files_5056", "Cannot write file '{0}' because it would be overwritten by multiple input files."), Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0: diag(5057, ts.DiagnosticCategory.Error, "Cannot_find_a_tsconfig_json_file_at_the_specified_directory_Colon_0_5057", "Cannot find a tsconfig.json file at the specified directory: '{0}'."), The_specified_path_does_not_exist_Colon_0: diag(5058, ts.DiagnosticCategory.Error, "The_specified_path_does_not_exist_Colon_0_5058", "The specified path does not exist: '{0}'."), Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier: diag(5059, ts.DiagnosticCategory.Error, "Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier_5059", "Invalid value for '--reactNamespace'. '{0}' is not a valid identifier."), Option_paths_cannot_be_used_without_specifying_baseUrl_option: diag(5060, ts.DiagnosticCategory.Error, "Option_paths_cannot_be_used_without_specifying_baseUrl_option_5060", "Option 'paths' cannot be used without specifying '--baseUrl' option."), Pattern_0_can_have_at_most_one_Asterisk_character: diag(5061, ts.DiagnosticCategory.Error, "Pattern_0_can_have_at_most_one_Asterisk_character_5061", "Pattern '{0}' can have at most one '*' character."), Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character: diag(5062, ts.DiagnosticCategory.Error, "Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character_5062", "Substitution '{0}' in pattern '{1}' in can have at most one '*' character."), Substitutions_for_pattern_0_should_be_an_array: diag(5063, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_should_be_an_array_5063", "Substitutions for pattern '{0}' should be an array."), Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2: diag(5064, ts.DiagnosticCategory.Error, "Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2_5064", "Substitution '{0}' for pattern '{1}' has incorrect type, expected 'string', got '{2}'."), File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0: diag(5065, ts.DiagnosticCategory.Error, "File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildca_5065", "File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'."), Substitutions_for_pattern_0_shouldn_t_be_an_empty_array: diag(5066, ts.DiagnosticCategory.Error, "Substitutions_for_pattern_0_shouldn_t_be_an_empty_array_5066", "Substitutions for pattern '{0}' shouldn't be an empty array."), Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name: diag(5067, ts.DiagnosticCategory.Error, "Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name_5067", "Invalid value for 'jsxFactory'. '{0}' is not a valid identifier or qualified-name."), Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig: diag(5068, ts.DiagnosticCategory.Error, "Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript__5068", "Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig."), Concatenate_and_emit_output_to_single_file: diag(6001, ts.DiagnosticCategory.Message, "Concatenate_and_emit_output_to_single_file_6001", "Concatenate and emit output to single file."), Generates_corresponding_d_ts_file: diag(6002, ts.DiagnosticCategory.Message, "Generates_corresponding_d_ts_file_6002", "Generates corresponding '.d.ts' file."), Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: diag(6003, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations_6003", "Specify the location where debugger should locate map files instead of generated locations."), Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: diag(6004, ts.DiagnosticCategory.Message, "Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations_6004", "Specify the location where debugger should locate TypeScript files instead of source locations."), Watch_input_files: diag(6005, ts.DiagnosticCategory.Message, "Watch_input_files_6005", "Watch input files."), Redirect_output_structure_to_the_directory: diag(6006, ts.DiagnosticCategory.Message, "Redirect_output_structure_to_the_directory_6006", "Redirect output structure to the directory."), Do_not_erase_const_enum_declarations_in_generated_code: diag(6007, ts.DiagnosticCategory.Message, "Do_not_erase_const_enum_declarations_in_generated_code_6007", "Do not erase const enum declarations in generated code."), Do_not_emit_outputs_if_any_errors_were_reported: diag(6008, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_if_any_errors_were_reported_6008", "Do not emit outputs if any errors were reported."), Do_not_emit_comments_to_output: diag(6009, ts.DiagnosticCategory.Message, "Do_not_emit_comments_to_output_6009", "Do not emit comments to output."), Do_not_emit_outputs: diag(6010, ts.DiagnosticCategory.Message, "Do_not_emit_outputs_6010", "Do not emit outputs."), Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking: diag(6011, ts.DiagnosticCategory.Message, "Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typech_6011", "Allow default imports from modules with no default export. This does not affect code emit, just typechecking."), Skip_type_checking_of_declaration_files: diag(6012, ts.DiagnosticCategory.Message, "Skip_type_checking_of_declaration_files_6012", "Skip type checking of declaration files."), Do_not_resolve_the_real_path_of_symlinks: diag(6013, ts.DiagnosticCategory.Message, "Do_not_resolve_the_real_path_of_symlinks_6013", "Do not resolve the real path of symlinks."), Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_or_ESNEXT: diag(6015, ts.DiagnosticCategory.Message, "Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_or_ESNEXT_6015", "Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'."), Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext: diag(6016, ts.DiagnosticCategory.Message, "Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext_6016", "Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'."), Print_this_message: diag(6017, ts.DiagnosticCategory.Message, "Print_this_message_6017", "Print this message."), Print_the_compiler_s_version: diag(6019, ts.DiagnosticCategory.Message, "Print_the_compiler_s_version_6019", "Print the compiler's version."), Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json: diag(6020, ts.DiagnosticCategory.Message, "Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json_6020", "Compile the project given the path to its configuration file, or to a folder with a 'tsconfig.json'."), Syntax_Colon_0: diag(6023, ts.DiagnosticCategory.Message, "Syntax_Colon_0_6023", "Syntax: {0}"), options: diag(6024, ts.DiagnosticCategory.Message, "options_6024", "options"), file: diag(6025, ts.DiagnosticCategory.Message, "file_6025", "file"), Examples_Colon_0: diag(6026, ts.DiagnosticCategory.Message, "Examples_Colon_0_6026", "Examples: {0}"), Options_Colon: diag(6027, ts.DiagnosticCategory.Message, "Options_Colon_6027", "Options:"), Version_0: diag(6029, ts.DiagnosticCategory.Message, "Version_0_6029", "Version {0}"), Insert_command_line_options_and_files_from_a_file: diag(6030, ts.DiagnosticCategory.Message, "Insert_command_line_options_and_files_from_a_file_6030", "Insert command line options and files from a file."), File_change_detected_Starting_incremental_compilation: diag(6032, ts.DiagnosticCategory.Message, "File_change_detected_Starting_incremental_compilation_6032", "File change detected. Starting incremental compilation..."), KIND: diag(6034, ts.DiagnosticCategory.Message, "KIND_6034", "KIND"), FILE: diag(6035, ts.DiagnosticCategory.Message, "FILE_6035", "FILE"), VERSION: diag(6036, ts.DiagnosticCategory.Message, "VERSION_6036", "VERSION"), LOCATION: diag(6037, ts.DiagnosticCategory.Message, "LOCATION_6037", "LOCATION"), DIRECTORY: diag(6038, ts.DiagnosticCategory.Message, "DIRECTORY_6038", "DIRECTORY"), STRATEGY: diag(6039, ts.DiagnosticCategory.Message, "STRATEGY_6039", "STRATEGY"), FILE_OR_DIRECTORY: diag(6040, ts.DiagnosticCategory.Message, "FILE_OR_DIRECTORY_6040", "FILE OR DIRECTORY"), Compilation_complete_Watching_for_file_changes: diag(6042, ts.DiagnosticCategory.Message, "Compilation_complete_Watching_for_file_changes_6042", "Compilation complete. Watching for file changes."), Generates_corresponding_map_file: diag(6043, ts.DiagnosticCategory.Message, "Generates_corresponding_map_file_6043", "Generates corresponding '.map' file."), Compiler_option_0_expects_an_argument: diag(6044, ts.DiagnosticCategory.Error, "Compiler_option_0_expects_an_argument_6044", "Compiler option '{0}' expects an argument."), Unterminated_quoted_string_in_response_file_0: diag(6045, ts.DiagnosticCategory.Error, "Unterminated_quoted_string_in_response_file_0_6045", "Unterminated quoted string in response file '{0}'."), Argument_for_0_option_must_be_Colon_1: diag(6046, ts.DiagnosticCategory.Error, "Argument_for_0_option_must_be_Colon_1_6046", "Argument for '{0}' option must be: {1}."), Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1: diag(6048, ts.DiagnosticCategory.Error, "Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1_6048", "Locale must be of the form or -. For example '{0}' or '{1}'."), Unsupported_locale_0: diag(6049, ts.DiagnosticCategory.Error, "Unsupported_locale_0_6049", "Unsupported locale '{0}'."), Unable_to_open_file_0: diag(6050, ts.DiagnosticCategory.Error, "Unable_to_open_file_0_6050", "Unable to open file '{0}'."), Corrupted_locale_file_0: diag(6051, ts.DiagnosticCategory.Error, "Corrupted_locale_file_0_6051", "Corrupted locale file {0}."), Raise_error_on_expressions_and_declarations_with_an_implied_any_type: diag(6052, ts.DiagnosticCategory.Message, "Raise_error_on_expressions_and_declarations_with_an_implied_any_type_6052", "Raise error on expressions and declarations with an implied 'any' type."), File_0_not_found: diag(6053, ts.DiagnosticCategory.Error, "File_0_not_found_6053", "File '{0}' not found."), File_0_has_unsupported_extension_The_only_supported_extensions_are_1: diag(6054, ts.DiagnosticCategory.Error, "File_0_has_unsupported_extension_The_only_supported_extensions_are_1_6054", "File '{0}' has unsupported extension. The only supported extensions are {1}."), Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures: diag(6055, ts.DiagnosticCategory.Message, "Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures_6055", "Suppress noImplicitAny errors for indexing objects lacking index signatures."), Do_not_emit_declarations_for_code_that_has_an_internal_annotation: diag(6056, ts.DiagnosticCategory.Message, "Do_not_emit_declarations_for_code_that_has_an_internal_annotation_6056", "Do not emit declarations for code that has an '@internal' annotation."), Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir: diag(6058, ts.DiagnosticCategory.Message, "Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir_6058", "Specify the root directory of input files. Use to control the output directory structure with --outDir."), File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files: diag(6059, ts.DiagnosticCategory.Error, "File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059", "File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files."), Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix: diag(6060, ts.DiagnosticCategory.Message, "Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix_6060", "Specify the end of line sequence to be used when emitting files: 'CRLF' (dos) or 'LF' (unix)."), NEWLINE: diag(6061, ts.DiagnosticCategory.Message, "NEWLINE_6061", "NEWLINE"), Option_0_can_only_be_specified_in_tsconfig_json_file: diag(6064, ts.DiagnosticCategory.Error, "Option_0_can_only_be_specified_in_tsconfig_json_file_6064", "Option '{0}' can only be specified in 'tsconfig.json' file."), Enables_experimental_support_for_ES7_decorators: diag(6065, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_decorators_6065", "Enables experimental support for ES7 decorators."), Enables_experimental_support_for_emitting_type_metadata_for_decorators: diag(6066, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_emitting_type_metadata_for_decorators_6066", "Enables experimental support for emitting type metadata for decorators."), Enables_experimental_support_for_ES7_async_functions: diag(6068, ts.DiagnosticCategory.Message, "Enables_experimental_support_for_ES7_async_functions_6068", "Enables experimental support for ES7 async functions."), Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6: diag(6069, ts.DiagnosticCategory.Message, "Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6_6069", "Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6)."), Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file: diag(6070, ts.DiagnosticCategory.Message, "Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file_6070", "Initializes a TypeScript project and creates a tsconfig.json file."), Successfully_created_a_tsconfig_json_file: diag(6071, ts.DiagnosticCategory.Message, "Successfully_created_a_tsconfig_json_file_6071", "Successfully created a tsconfig.json file."), Suppress_excess_property_checks_for_object_literals: diag(6072, ts.DiagnosticCategory.Message, "Suppress_excess_property_checks_for_object_literals_6072", "Suppress excess property checks for object literals."), Stylize_errors_and_messages_using_color_and_context_experimental: diag(6073, ts.DiagnosticCategory.Message, "Stylize_errors_and_messages_using_color_and_context_experimental_6073", "Stylize errors and messages using color and context (experimental)."), Do_not_report_errors_on_unused_labels: diag(6074, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unused_labels_6074", "Do not report errors on unused labels."), Report_error_when_not_all_code_paths_in_function_return_a_value: diag(6075, ts.DiagnosticCategory.Message, "Report_error_when_not_all_code_paths_in_function_return_a_value_6075", "Report error when not all code paths in function return a value."), Report_errors_for_fallthrough_cases_in_switch_statement: diag(6076, ts.DiagnosticCategory.Message, "Report_errors_for_fallthrough_cases_in_switch_statement_6076", "Report errors for fallthrough cases in switch statement."), Do_not_report_errors_on_unreachable_code: diag(6077, ts.DiagnosticCategory.Message, "Do_not_report_errors_on_unreachable_code_6077", "Do not report errors on unreachable code."), Disallow_inconsistently_cased_references_to_the_same_file: diag(6078, ts.DiagnosticCategory.Message, "Disallow_inconsistently_cased_references_to_the_same_file_6078", "Disallow inconsistently-cased references to the same file."), Specify_library_files_to_be_included_in_the_compilation_Colon: diag(6079, ts.DiagnosticCategory.Message, "Specify_library_files_to_be_included_in_the_compilation_Colon_6079", "Specify library files to be included in the compilation: "), Specify_JSX_code_generation_Colon_preserve_react_native_or_react: diag(6080, ts.DiagnosticCategory.Message, "Specify_JSX_code_generation_Colon_preserve_react_native_or_react_6080", "Specify JSX code generation: 'preserve', 'react-native', or 'react'."), File_0_has_an_unsupported_extension_so_skipping_it: diag(6081, ts.DiagnosticCategory.Message, "File_0_has_an_unsupported_extension_so_skipping_it_6081", "File '{0}' has an unsupported extension, so skipping it."), Only_amd_and_system_modules_are_supported_alongside_0: diag(6082, ts.DiagnosticCategory.Error, "Only_amd_and_system_modules_are_supported_alongside_0_6082", "Only 'amd' and 'system' modules are supported alongside --{0}."), Base_directory_to_resolve_non_absolute_module_names: diag(6083, ts.DiagnosticCategory.Message, "Base_directory_to_resolve_non_absolute_module_names_6083", "Base directory to resolve non-absolute module names."), Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit: diag(6084, ts.DiagnosticCategory.Message, "Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react__6084", "[Deprecated] Use '--jsxFactory' instead. Specify the object invoked for createElement when targeting 'react' JSX emit"), Enable_tracing_of_the_name_resolution_process: diag(6085, ts.DiagnosticCategory.Message, "Enable_tracing_of_the_name_resolution_process_6085", "Enable tracing of the name resolution process."), Resolving_module_0_from_1: diag(6086, ts.DiagnosticCategory.Message, "Resolving_module_0_from_1_6086", "======== Resolving module '{0}' from '{1}'. ========"), Explicitly_specified_module_resolution_kind_Colon_0: diag(6087, ts.DiagnosticCategory.Message, "Explicitly_specified_module_resolution_kind_Colon_0_6087", "Explicitly specified module resolution kind: '{0}'."), Module_resolution_kind_is_not_specified_using_0: diag(6088, ts.DiagnosticCategory.Message, "Module_resolution_kind_is_not_specified_using_0_6088", "Module resolution kind is not specified, using '{0}'."), Module_name_0_was_successfully_resolved_to_1: diag(6089, ts.DiagnosticCategory.Message, "Module_name_0_was_successfully_resolved_to_1_6089", "======== Module name '{0}' was successfully resolved to '{1}'. ========"), Module_name_0_was_not_resolved: diag(6090, ts.DiagnosticCategory.Message, "Module_name_0_was_not_resolved_6090", "======== Module name '{0}' was not resolved. ========"), paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0: diag(6091, ts.DiagnosticCategory.Message, "paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0_6091", "'paths' option is specified, looking for a pattern to match module name '{0}'."), Module_name_0_matched_pattern_1: diag(6092, ts.DiagnosticCategory.Message, "Module_name_0_matched_pattern_1_6092", "Module name '{0}', matched pattern '{1}'."), Trying_substitution_0_candidate_module_location_Colon_1: diag(6093, ts.DiagnosticCategory.Message, "Trying_substitution_0_candidate_module_location_Colon_1_6093", "Trying substitution '{0}', candidate module location: '{1}'."), Resolving_module_name_0_relative_to_base_url_1_2: diag(6094, ts.DiagnosticCategory.Message, "Resolving_module_name_0_relative_to_base_url_1_2_6094", "Resolving module name '{0}' relative to base url '{1}' - '{2}'."), Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1: diag(6095, ts.DiagnosticCategory.Message, "Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1_6095", "Loading module as file / folder, candidate module location '{0}', target file type '{1}'."), File_0_does_not_exist: diag(6096, ts.DiagnosticCategory.Message, "File_0_does_not_exist_6096", "File '{0}' does not exist."), File_0_exist_use_it_as_a_name_resolution_result: diag(6097, ts.DiagnosticCategory.Message, "File_0_exist_use_it_as_a_name_resolution_result_6097", "File '{0}' exist - use it as a name resolution result."), Loading_module_0_from_node_modules_folder_target_file_type_1: diag(6098, ts.DiagnosticCategory.Message, "Loading_module_0_from_node_modules_folder_target_file_type_1_6098", "Loading module '{0}' from 'node_modules' folder, target file type '{1}'."), Found_package_json_at_0: diag(6099, ts.DiagnosticCategory.Message, "Found_package_json_at_0_6099", "Found 'package.json' at '{0}'."), package_json_does_not_have_a_0_field: diag(6100, ts.DiagnosticCategory.Message, "package_json_does_not_have_a_0_field_6100", "'package.json' does not have a '{0}' field."), package_json_has_0_field_1_that_references_2: diag(6101, ts.DiagnosticCategory.Message, "package_json_has_0_field_1_that_references_2_6101", "'package.json' has '{0}' field '{1}' that references '{2}'."), Allow_javascript_files_to_be_compiled: diag(6102, ts.DiagnosticCategory.Message, "Allow_javascript_files_to_be_compiled_6102", "Allow javascript files to be compiled."), Option_0_should_have_array_of_strings_as_a_value: diag(6103, ts.DiagnosticCategory.Error, "Option_0_should_have_array_of_strings_as_a_value_6103", "Option '{0}' should have array of strings as a value."), Checking_if_0_is_the_longest_matching_prefix_for_1_2: diag(6104, ts.DiagnosticCategory.Message, "Checking_if_0_is_the_longest_matching_prefix_for_1_2_6104", "Checking if '{0}' is the longest matching prefix for '{1}' - '{2}'."), Expected_type_of_0_field_in_package_json_to_be_string_got_1: diag(6105, ts.DiagnosticCategory.Message, "Expected_type_of_0_field_in_package_json_to_be_string_got_1_6105", "Expected type of '{0}' field in 'package.json' to be 'string', got '{1}'."), baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1: diag(6106, ts.DiagnosticCategory.Message, "baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1_6106", "'baseUrl' option is set to '{0}', using this value to resolve non-relative module name '{1}'."), rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0: diag(6107, ts.DiagnosticCategory.Message, "rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107", "'rootDirs' option is set, using it to resolve relative module name '{0}'."), Longest_matching_prefix_for_0_is_1: diag(6108, ts.DiagnosticCategory.Message, "Longest_matching_prefix_for_0_is_1_6108", "Longest matching prefix for '{0}' is '{1}'."), Loading_0_from_the_root_dir_1_candidate_location_2: diag(6109, ts.DiagnosticCategory.Message, "Loading_0_from_the_root_dir_1_candidate_location_2_6109", "Loading '{0}' from the root dir '{1}', candidate location '{2}'."), Trying_other_entries_in_rootDirs: diag(6110, ts.DiagnosticCategory.Message, "Trying_other_entries_in_rootDirs_6110", "Trying other entries in 'rootDirs'."), Module_resolution_using_rootDirs_has_failed: diag(6111, ts.DiagnosticCategory.Message, "Module_resolution_using_rootDirs_has_failed_6111", "Module resolution using 'rootDirs' has failed."), Do_not_emit_use_strict_directives_in_module_output: diag(6112, ts.DiagnosticCategory.Message, "Do_not_emit_use_strict_directives_in_module_output_6112", "Do not emit 'use strict' directives in module output."), Enable_strict_null_checks: diag(6113, ts.DiagnosticCategory.Message, "Enable_strict_null_checks_6113", "Enable strict null checks."), Unknown_option_excludes_Did_you_mean_exclude: diag(6114, ts.DiagnosticCategory.Error, "Unknown_option_excludes_Did_you_mean_exclude_6114", "Unknown option 'excludes'. Did you mean 'exclude'?"), Raise_error_on_this_expressions_with_an_implied_any_type: diag(6115, ts.DiagnosticCategory.Message, "Raise_error_on_this_expressions_with_an_implied_any_type_6115", "Raise error on 'this' expressions with an implied 'any' type."), Resolving_type_reference_directive_0_containing_file_1_root_directory_2: diag(6116, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_2_6116", "======== Resolving type reference directive '{0}', containing file '{1}', root directory '{2}'. ========"), Resolving_using_primary_search_paths: diag(6117, ts.DiagnosticCategory.Message, "Resolving_using_primary_search_paths_6117", "Resolving using primary search paths..."), Resolving_from_node_modules_folder: diag(6118, ts.DiagnosticCategory.Message, "Resolving_from_node_modules_folder_6118", "Resolving from node_modules folder..."), Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2: diag(6119, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2_6119", "======== Type reference directive '{0}' was successfully resolved to '{1}', primary: {2}. ========"), Type_reference_directive_0_was_not_resolved: diag(6120, ts.DiagnosticCategory.Message, "Type_reference_directive_0_was_not_resolved_6120", "======== Type reference directive '{0}' was not resolved. ========"), Resolving_with_primary_search_path_0: diag(6121, ts.DiagnosticCategory.Message, "Resolving_with_primary_search_path_0_6121", "Resolving with primary search path '{0}'."), Root_directory_cannot_be_determined_skipping_primary_search_paths: diag(6122, ts.DiagnosticCategory.Message, "Root_directory_cannot_be_determined_skipping_primary_search_paths_6122", "Root directory cannot be determined, skipping primary search paths."), Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set: diag(6123, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set_6123", "======== Resolving type reference directive '{0}', containing file '{1}', root directory not set. ========"), Type_declaration_files_to_be_included_in_compilation: diag(6124, ts.DiagnosticCategory.Message, "Type_declaration_files_to_be_included_in_compilation_6124", "Type declaration files to be included in compilation."), Looking_up_in_node_modules_folder_initial_location_0: diag(6125, ts.DiagnosticCategory.Message, "Looking_up_in_node_modules_folder_initial_location_0_6125", "Looking up in 'node_modules' folder, initial location '{0}'."), Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder: diag(6126, ts.DiagnosticCategory.Message, "Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_mod_6126", "Containing file is not specified and root directory cannot be determined, skipping lookup in 'node_modules' folder."), Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1: diag(6127, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1_6127", "======== Resolving type reference directive '{0}', containing file not set, root directory '{1}'. ========"), Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set: diag(6128, ts.DiagnosticCategory.Message, "Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set_6128", "======== Resolving type reference directive '{0}', containing file not set, root directory not set. ========"), Resolving_real_path_for_0_result_1: diag(6130, ts.DiagnosticCategory.Message, "Resolving_real_path_for_0_result_1_6130", "Resolving real path for '{0}', result '{1}'."), Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system: diag(6131, ts.DiagnosticCategory.Error, "Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system_6131", "Cannot compile modules using option '{0}' unless the '--module' flag is 'amd' or 'system'."), File_name_0_has_a_1_extension_stripping_it: diag(6132, ts.DiagnosticCategory.Message, "File_name_0_has_a_1_extension_stripping_it_6132", "File name '{0}' has a '{1}' extension - stripping it."), _0_is_declared_but_its_value_is_never_read: diag(6133, ts.DiagnosticCategory.Error, "_0_is_declared_but_its_value_is_never_read_6133", "'{0}' is declared but its value is never read."), Report_errors_on_unused_locals: diag(6134, ts.DiagnosticCategory.Message, "Report_errors_on_unused_locals_6134", "Report errors on unused locals."), Report_errors_on_unused_parameters: diag(6135, ts.DiagnosticCategory.Message, "Report_errors_on_unused_parameters_6135", "Report errors on unused parameters."), The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files: diag(6136, ts.DiagnosticCategory.Message, "The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files_6136", "The maximum dependency depth to search under node_modules and load JavaScript files."), Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1: diag(6137, ts.DiagnosticCategory.Error, "Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1_6137", "Cannot import type declaration files. Consider importing '{0}' instead of '{1}'."), Property_0_is_declared_but_its_value_is_never_read: diag(6138, ts.DiagnosticCategory.Error, "Property_0_is_declared_but_its_value_is_never_read_6138", "Property '{0}' is declared but its value is never read."), Import_emit_helpers_from_tslib: diag(6139, ts.DiagnosticCategory.Message, "Import_emit_helpers_from_tslib_6139", "Import emit helpers from 'tslib'."), Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2: diag(6140, ts.DiagnosticCategory.Error, "Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using__6140", "Auto discovery for typings is enabled in project '{0}'. Running extra resolution pass for module '{1}' using cache location '{2}'."), Parse_in_strict_mode_and_emit_use_strict_for_each_source_file: diag(6141, ts.DiagnosticCategory.Message, "Parse_in_strict_mode_and_emit_use_strict_for_each_source_file_6141", "Parse in strict mode and emit \"use strict\" for each source file."), Module_0_was_resolved_to_1_but_jsx_is_not_set: diag(6142, ts.DiagnosticCategory.Error, "Module_0_was_resolved_to_1_but_jsx_is_not_set_6142", "Module '{0}' was resolved to '{1}', but '--jsx' is not set."), Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1: diag(6144, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1_6144", "Module '{0}' was resolved as locally declared ambient module in file '{1}'."), Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified: diag(6145, ts.DiagnosticCategory.Message, "Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified_6145", "Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified."), Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h: diag(6146, ts.DiagnosticCategory.Message, "Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h_6146", "Specify the JSX factory function to use when targeting 'react' JSX emit, e.g. 'React.createElement' or 'h'."), Resolution_for_module_0_was_found_in_cache: diag(6147, ts.DiagnosticCategory.Message, "Resolution_for_module_0_was_found_in_cache_6147", "Resolution for module '{0}' was found in cache."), Directory_0_does_not_exist_skipping_all_lookups_in_it: diag(6148, ts.DiagnosticCategory.Message, "Directory_0_does_not_exist_skipping_all_lookups_in_it_6148", "Directory '{0}' does not exist, skipping all lookups in it."), Show_diagnostic_information: diag(6149, ts.DiagnosticCategory.Message, "Show_diagnostic_information_6149", "Show diagnostic information."), Show_verbose_diagnostic_information: diag(6150, ts.DiagnosticCategory.Message, "Show_verbose_diagnostic_information_6150", "Show verbose diagnostic information."), Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file: diag(6151, ts.DiagnosticCategory.Message, "Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file_6151", "Emit a single file with source maps instead of having a separate file."), Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set: diag(6152, ts.DiagnosticCategory.Message, "Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap__6152", "Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set."), Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule: diag(6153, ts.DiagnosticCategory.Message, "Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule_6153", "Transpile each file as a separate module (similar to 'ts.transpileModule')."), Print_names_of_generated_files_part_of_the_compilation: diag(6154, ts.DiagnosticCategory.Message, "Print_names_of_generated_files_part_of_the_compilation_6154", "Print names of generated files part of the compilation."), Print_names_of_files_part_of_the_compilation: diag(6155, ts.DiagnosticCategory.Message, "Print_names_of_files_part_of_the_compilation_6155", "Print names of files part of the compilation."), The_locale_used_when_displaying_messages_to_the_user_e_g_en_us: diag(6156, ts.DiagnosticCategory.Message, "The_locale_used_when_displaying_messages_to_the_user_e_g_en_us_6156", "The locale used when displaying messages to the user (e.g. 'en-us')"), Do_not_generate_custom_helper_functions_like_extends_in_compiled_output: diag(6157, ts.DiagnosticCategory.Message, "Do_not_generate_custom_helper_functions_like_extends_in_compiled_output_6157", "Do not generate custom helper functions like '__extends' in compiled output."), Do_not_include_the_default_library_file_lib_d_ts: diag(6158, ts.DiagnosticCategory.Message, "Do_not_include_the_default_library_file_lib_d_ts_6158", "Do not include the default library file (lib.d.ts)."), Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files: diag(6159, ts.DiagnosticCategory.Message, "Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files_6159", "Do not add triple-slash references or imported modules to the list of compiled files."), Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files: diag(6160, ts.DiagnosticCategory.Message, "Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files_6160", "[Deprecated] Use '--skipLibCheck' instead. Skip type checking of default library declaration files."), List_of_folders_to_include_type_definitions_from: diag(6161, ts.DiagnosticCategory.Message, "List_of_folders_to_include_type_definitions_from_6161", "List of folders to include type definitions from."), Disable_size_limitations_on_JavaScript_projects: diag(6162, ts.DiagnosticCategory.Message, "Disable_size_limitations_on_JavaScript_projects_6162", "Disable size limitations on JavaScript projects."), The_character_set_of_the_input_files: diag(6163, ts.DiagnosticCategory.Message, "The_character_set_of_the_input_files_6163", "The character set of the input files."), Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files: diag(6164, ts.DiagnosticCategory.Message, "Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files_6164", "Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files."), Do_not_truncate_error_messages: diag(6165, ts.DiagnosticCategory.Message, "Do_not_truncate_error_messages_6165", "Do not truncate error messages."), Output_directory_for_generated_declaration_files: diag(6166, ts.DiagnosticCategory.Message, "Output_directory_for_generated_declaration_files_6166", "Output directory for generated declaration files."), A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl: diag(6167, ts.DiagnosticCategory.Message, "A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl_6167", "A series of entries which re-map imports to lookup locations relative to the 'baseUrl'."), List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime: diag(6168, ts.DiagnosticCategory.Message, "List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime_6168", "List of root folders whose combined content represents the structure of the project at runtime."), Show_all_compiler_options: diag(6169, ts.DiagnosticCategory.Message, "Show_all_compiler_options_6169", "Show all compiler options."), Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file: diag(6170, ts.DiagnosticCategory.Message, "Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file_6170", "[Deprecated] Use '--outFile' instead. Concatenate and emit output to single file"), Command_line_Options: diag(6171, ts.DiagnosticCategory.Message, "Command_line_Options_6171", "Command-line Options"), Basic_Options: diag(6172, ts.DiagnosticCategory.Message, "Basic_Options_6172", "Basic Options"), Strict_Type_Checking_Options: diag(6173, ts.DiagnosticCategory.Message, "Strict_Type_Checking_Options_6173", "Strict Type-Checking Options"), Module_Resolution_Options: diag(6174, ts.DiagnosticCategory.Message, "Module_Resolution_Options_6174", "Module Resolution Options"), Source_Map_Options: diag(6175, ts.DiagnosticCategory.Message, "Source_Map_Options_6175", "Source Map Options"), Additional_Checks: diag(6176, ts.DiagnosticCategory.Message, "Additional_Checks_6176", "Additional Checks"), Experimental_Options: diag(6177, ts.DiagnosticCategory.Message, "Experimental_Options_6177", "Experimental Options"), Advanced_Options: diag(6178, ts.DiagnosticCategory.Message, "Advanced_Options_6178", "Advanced Options"), Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3: diag(6179, ts.DiagnosticCategory.Message, "Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3_6179", "Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'."), Enable_all_strict_type_checking_options: diag(6180, ts.DiagnosticCategory.Message, "Enable_all_strict_type_checking_options_6180", "Enable all strict type-checking options."), List_of_language_service_plugins: diag(6181, ts.DiagnosticCategory.Message, "List_of_language_service_plugins_6181", "List of language service plugins."), Scoped_package_detected_looking_in_0: diag(6182, ts.DiagnosticCategory.Message, "Scoped_package_detected_looking_in_0_6182", "Scoped package detected, looking in '{0}'"), Reusing_resolution_of_module_0_to_file_1_from_old_program: diag(6183, ts.DiagnosticCategory.Message, "Reusing_resolution_of_module_0_to_file_1_from_old_program_6183", "Reusing resolution of module '{0}' to file '{1}' from old program."), Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program: diag(6184, ts.DiagnosticCategory.Message, "Reusing_module_resolutions_originating_in_0_since_resolutions_are_unchanged_from_old_program_6184", "Reusing module resolutions originating in '{0}' since resolutions are unchanged from old program."), Disable_strict_checking_of_generic_signatures_in_function_types: diag(6185, ts.DiagnosticCategory.Message, "Disable_strict_checking_of_generic_signatures_in_function_types_6185", "Disable strict checking of generic signatures in function types."), Enable_strict_checking_of_function_types: diag(6186, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_function_types_6186", "Enable strict checking of function types."), Enable_strict_checking_of_property_initialization_in_classes: diag(6187, ts.DiagnosticCategory.Message, "Enable_strict_checking_of_property_initialization_in_classes_6187", "Enable strict checking of property initialization in classes."), Variable_0_implicitly_has_an_1_type: diag(7005, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_an_1_type_7005", "Variable '{0}' implicitly has an '{1}' type."), Parameter_0_implicitly_has_an_1_type: diag(7006, ts.DiagnosticCategory.Error, "Parameter_0_implicitly_has_an_1_type_7006", "Parameter '{0}' implicitly has an '{1}' type."), Member_0_implicitly_has_an_1_type: diag(7008, ts.DiagnosticCategory.Error, "Member_0_implicitly_has_an_1_type_7008", "Member '{0}' implicitly has an '{1}' type."), new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type: diag(7009, ts.DiagnosticCategory.Error, "new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type_7009", "'new' expression, whose target lacks a construct signature, implicitly has an 'any' type."), _0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type: diag(7010, ts.DiagnosticCategory.Error, "_0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type_7010", "'{0}', which lacks return-type annotation, implicitly has an '{1}' return type."), Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type: diag(7011, ts.DiagnosticCategory.Error, "Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type_7011", "Function expression, which lacks return-type annotation, implicitly has an '{0}' return type."), Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7013, ts.DiagnosticCategory.Error, "Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7013", "Construct signature, which lacks return-type annotation, implicitly has an 'any' return type."), Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number: diag(7015, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number_7015", "Element implicitly has an 'any' type because index expression is not of type 'number'."), Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type: diag(7016, ts.DiagnosticCategory.Error, "Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type_7016", "Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type."), Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature: diag(7017, ts.DiagnosticCategory.Error, "Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature_7017", "Element implicitly has an 'any' type because type '{0}' has no index signature."), Object_literal_s_property_0_implicitly_has_an_1_type: diag(7018, ts.DiagnosticCategory.Error, "Object_literal_s_property_0_implicitly_has_an_1_type_7018", "Object literal's property '{0}' implicitly has an '{1}' type."), Rest_parameter_0_implicitly_has_an_any_type: diag(7019, ts.DiagnosticCategory.Error, "Rest_parameter_0_implicitly_has_an_any_type_7019", "Rest parameter '{0}' implicitly has an 'any[]' type."), Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type: diag(7020, ts.DiagnosticCategory.Error, "Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type_7020", "Call signature, which lacks return-type annotation, implicitly has an 'any' return type."), _0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: diag(7022, ts.DiagnosticCategory.Error, "_0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or__7022", "'{0}' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer."), _0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7023, ts.DiagnosticCategory.Error, "_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_reference_7023", "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."), Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: diag(7024, ts.DiagnosticCategory.Error, "Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_ref_7024", "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions."), Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: diag(7025, ts.DiagnosticCategory.Error, "Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_typ_7025", "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type."), JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists: diag(7026, ts.DiagnosticCategory.Error, "JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists_7026", "JSX element implicitly has type 'any' because no interface 'JSX.{0}' exists."), Unreachable_code_detected: diag(7027, ts.DiagnosticCategory.Error, "Unreachable_code_detected_7027", "Unreachable code detected."), Unused_label: diag(7028, ts.DiagnosticCategory.Error, "Unused_label_7028", "Unused label."), Fallthrough_case_in_switch: diag(7029, ts.DiagnosticCategory.Error, "Fallthrough_case_in_switch_7029", "Fallthrough case in switch."), Not_all_code_paths_return_a_value: diag(7030, ts.DiagnosticCategory.Error, "Not_all_code_paths_return_a_value_7030", "Not all code paths return a value."), Binding_element_0_implicitly_has_an_1_type: diag(7031, ts.DiagnosticCategory.Error, "Binding_element_0_implicitly_has_an_1_type_7031", "Binding element '{0}' implicitly has an '{1}' type."), Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation: diag(7032, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation_7032", "Property '{0}' implicitly has type 'any', because its set accessor lacks a parameter type annotation."), Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation: diag(7033, ts.DiagnosticCategory.Error, "Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation_7033", "Property '{0}' implicitly has type 'any', because its get accessor lacks a return type annotation."), Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined: diag(7034, ts.DiagnosticCategory.Error, "Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined_7034", "Variable '{0}' implicitly has type '{1}' in some locations where its type cannot be determined."), Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0: diag(7035, ts.DiagnosticCategory.Error, "Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_mod_7035", "Try `npm install @types/{0}` if it exists or add a new declaration (.d.ts) file containing `declare module '{0}';`"), Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0: diag(7036, ts.DiagnosticCategory.Error, "Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0_7036", "Dynamic import's specifier must be of type 'string', but here has type '{0}'."), You_cannot_rename_this_element: diag(8000, ts.DiagnosticCategory.Error, "You_cannot_rename_this_element_8000", "You cannot rename this element."), You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: diag(8001, ts.DiagnosticCategory.Error, "You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library_8001", "You cannot rename elements that are defined in the standard TypeScript library."), import_can_only_be_used_in_a_ts_file: diag(8002, ts.DiagnosticCategory.Error, "import_can_only_be_used_in_a_ts_file_8002", "'import ... =' can only be used in a .ts file."), export_can_only_be_used_in_a_ts_file: diag(8003, ts.DiagnosticCategory.Error, "export_can_only_be_used_in_a_ts_file_8003", "'export=' can only be used in a .ts file."), type_parameter_declarations_can_only_be_used_in_a_ts_file: diag(8004, ts.DiagnosticCategory.Error, "type_parameter_declarations_can_only_be_used_in_a_ts_file_8004", "'type parameter declarations' can only be used in a .ts file."), implements_clauses_can_only_be_used_in_a_ts_file: diag(8005, ts.DiagnosticCategory.Error, "implements_clauses_can_only_be_used_in_a_ts_file_8005", "'implements clauses' can only be used in a .ts file."), interface_declarations_can_only_be_used_in_a_ts_file: diag(8006, ts.DiagnosticCategory.Error, "interface_declarations_can_only_be_used_in_a_ts_file_8006", "'interface declarations' can only be used in a .ts file."), module_declarations_can_only_be_used_in_a_ts_file: diag(8007, ts.DiagnosticCategory.Error, "module_declarations_can_only_be_used_in_a_ts_file_8007", "'module declarations' can only be used in a .ts file."), type_aliases_can_only_be_used_in_a_ts_file: diag(8008, ts.DiagnosticCategory.Error, "type_aliases_can_only_be_used_in_a_ts_file_8008", "'type aliases' can only be used in a .ts file."), _0_can_only_be_used_in_a_ts_file: diag(8009, ts.DiagnosticCategory.Error, "_0_can_only_be_used_in_a_ts_file_8009", "'{0}' can only be used in a .ts file."), types_can_only_be_used_in_a_ts_file: diag(8010, ts.DiagnosticCategory.Error, "types_can_only_be_used_in_a_ts_file_8010", "'types' can only be used in a .ts file."), type_arguments_can_only_be_used_in_a_ts_file: diag(8011, ts.DiagnosticCategory.Error, "type_arguments_can_only_be_used_in_a_ts_file_8011", "'type arguments' can only be used in a .ts file."), parameter_modifiers_can_only_be_used_in_a_ts_file: diag(8012, ts.DiagnosticCategory.Error, "parameter_modifiers_can_only_be_used_in_a_ts_file_8012", "'parameter modifiers' can only be used in a .ts file."), non_null_assertions_can_only_be_used_in_a_ts_file: diag(8013, ts.DiagnosticCategory.Error, "non_null_assertions_can_only_be_used_in_a_ts_file_8013", "'non-null assertions' can only be used in a .ts file."), enum_declarations_can_only_be_used_in_a_ts_file: diag(8015, ts.DiagnosticCategory.Error, "enum_declarations_can_only_be_used_in_a_ts_file_8015", "'enum declarations' can only be used in a .ts file."), type_assertion_expressions_can_only_be_used_in_a_ts_file: diag(8016, ts.DiagnosticCategory.Error, "type_assertion_expressions_can_only_be_used_in_a_ts_file_8016", "'type assertion expressions' can only be used in a .ts file."), Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0: diag(8017, ts.DiagnosticCategory.Error, "Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0_8017", "Octal literal types must use ES2015 syntax. Use the syntax '{0}'."), Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0: diag(8018, ts.DiagnosticCategory.Error, "Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0_8018", "Octal literals are not allowed in enums members initializer. Use the syntax '{0}'."), Report_errors_in_js_files: diag(8019, ts.DiagnosticCategory.Message, "Report_errors_in_js_files_8019", "Report errors in .js files."), JSDoc_types_can_only_be_used_inside_documentation_comments: diag(8020, ts.DiagnosticCategory.Error, "JSDoc_types_can_only_be_used_inside_documentation_comments_8020", "JSDoc types can only be used inside documentation comments."), JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags: diag(8021, ts.DiagnosticCategory.Error, "JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags_8021", "JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags."), JSDoc_0_is_not_attached_to_a_class: diag(8022, ts.DiagnosticCategory.Error, "JSDoc_0_is_not_attached_to_a_class_8022", "JSDoc '@{0}' is not attached to a class."), JSDoc_0_1_does_not_match_the_extends_2_clause: diag(8023, ts.DiagnosticCategory.Error, "JSDoc_0_1_does_not_match_the_extends_2_clause_8023", "JSDoc '@{0} {1}' does not match the 'extends {2}' clause."), JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name: diag(8024, ts.DiagnosticCategory.Error, "JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_8024", "JSDoc '@param' tag has name '{0}', but there is no parameter with that name."), Class_declarations_cannot_have_more_than_one_augments_or_extends_tag: diag(8025, ts.DiagnosticCategory.Error, "Class_declarations_cannot_have_more_than_one_augments_or_extends_tag_8025", "Class declarations cannot have more than one `@augments` or `@extends` tag."), Expected_0_type_arguments_provide_these_with_an_extends_tag: diag(8026, ts.DiagnosticCategory.Error, "Expected_0_type_arguments_provide_these_with_an_extends_tag_8026", "Expected {0} type arguments; provide these with an '@extends' tag."), Expected_0_1_type_arguments_provide_these_with_an_extends_tag: diag(8027, ts.DiagnosticCategory.Error, "Expected_0_1_type_arguments_provide_these_with_an_extends_tag_8027", "Expected {0}-{1} type arguments; provide these with an '@extends' tag."), JSDoc_may_only_appear_in_the_last_parameter_of_a_signature: diag(8028, ts.DiagnosticCategory.Error, "JSDoc_may_only_appear_in_the_last_parameter_of_a_signature_8028", "JSDoc '...' may only appear in the last parameter of a signature."), Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clause: diag(9002, ts.DiagnosticCategory.Error, "Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_clas_9002", "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clause."), class_expressions_are_not_currently_supported: diag(9003, ts.DiagnosticCategory.Error, "class_expressions_are_not_currently_supported_9003", "'class' expressions are not currently supported."), Language_service_is_disabled: diag(9004, ts.DiagnosticCategory.Error, "Language_service_is_disabled_9004", "Language service is disabled."), JSX_attributes_must_only_be_assigned_a_non_empty_expression: diag(17000, ts.DiagnosticCategory.Error, "JSX_attributes_must_only_be_assigned_a_non_empty_expression_17000", "JSX attributes must only be assigned a non-empty 'expression'."), JSX_elements_cannot_have_multiple_attributes_with_the_same_name: diag(17001, ts.DiagnosticCategory.Error, "JSX_elements_cannot_have_multiple_attributes_with_the_same_name_17001", "JSX elements cannot have multiple attributes with the same name."), Expected_corresponding_JSX_closing_tag_for_0: diag(17002, ts.DiagnosticCategory.Error, "Expected_corresponding_JSX_closing_tag_for_0_17002", "Expected corresponding JSX closing tag for '{0}'."), JSX_attribute_expected: diag(17003, ts.DiagnosticCategory.Error, "JSX_attribute_expected_17003", "JSX attribute expected."), Cannot_use_JSX_unless_the_jsx_flag_is_provided: diag(17004, ts.DiagnosticCategory.Error, "Cannot_use_JSX_unless_the_jsx_flag_is_provided_17004", "Cannot use JSX unless the '--jsx' flag is provided."), A_constructor_cannot_contain_a_super_call_when_its_class_extends_null: diag(17005, ts.DiagnosticCategory.Error, "A_constructor_cannot_contain_a_super_call_when_its_class_extends_null_17005", "A constructor cannot contain a 'super' call when its class extends 'null'."), An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17006, ts.DiagnosticCategory.Error, "An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_ex_17006", "An unary expression with the '{0}' operator is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."), A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses: diag(17007, ts.DiagnosticCategory.Error, "A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Con_17007", "A type assertion expression is not allowed in the left-hand side of an exponentiation expression. Consider enclosing the expression in parentheses."), JSX_element_0_has_no_corresponding_closing_tag: diag(17008, ts.DiagnosticCategory.Error, "JSX_element_0_has_no_corresponding_closing_tag_17008", "JSX element '{0}' has no corresponding closing tag."), super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class: diag(17009, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class_17009", "'super' must be called before accessing 'this' in the constructor of a derived class."), Unknown_type_acquisition_option_0: diag(17010, ts.DiagnosticCategory.Error, "Unknown_type_acquisition_option_0_17010", "Unknown type acquisition option '{0}'."), super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class: diag(17011, ts.DiagnosticCategory.Error, "super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class_17011", "'super' must be called before accessing a property of 'super' in the constructor of a derived class."), _0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2: diag(17012, ts.DiagnosticCategory.Error, "_0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2_17012", "'{0}' is not a valid meta-property for keyword '{1}'. Did you mean '{2}'?"), Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor: diag(17013, ts.DiagnosticCategory.Error, "Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constru_17013", "Meta-property '{0}' is only allowed in the body of a function declaration, function expression, or constructor."), JSX_fragment_has_no_corresponding_closing_tag: diag(17014, ts.DiagnosticCategory.Error, "JSX_fragment_has_no_corresponding_closing_tag_17014", "JSX fragment has no corresponding closing tag."), Expected_corresponding_closing_tag_for_JSX_fragment: diag(17015, ts.DiagnosticCategory.Error, "Expected_corresponding_closing_tag_for_JSX_fragment_17015", "Expected corresponding closing tag for JSX fragment."), JSX_fragment_is_not_supported_when_using_jsxFactory: diag(17016, ts.DiagnosticCategory.Error, "JSX_fragment_is_not_supported_when_using_jsxFactory_17016", "JSX fragment is not supported when using --jsxFactory"), Circularity_detected_while_resolving_configuration_Colon_0: diag(18000, ts.DiagnosticCategory.Error, "Circularity_detected_while_resolving_configuration_Colon_0_18000", "Circularity detected while resolving configuration: {0}"), A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not: diag(18001, ts.DiagnosticCategory.Error, "A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not_18001", "A path in an 'extends' option must be relative or rooted, but '{0}' is not."), The_files_list_in_config_file_0_is_empty: diag(18002, ts.DiagnosticCategory.Error, "The_files_list_in_config_file_0_is_empty_18002", "The 'files' list in config file '{0}' is empty."), No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2: diag(18003, ts.DiagnosticCategory.Error, "No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2_18003", "No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'."), Add_missing_super_call: diag(90001, ts.DiagnosticCategory.Message, "Add_missing_super_call_90001", "Add missing 'super()' call"), Make_super_call_the_first_statement_in_the_constructor: diag(90002, ts.DiagnosticCategory.Message, "Make_super_call_the_first_statement_in_the_constructor_90002", "Make 'super()' call the first statement in the constructor"), Change_extends_to_implements: diag(90003, ts.DiagnosticCategory.Message, "Change_extends_to_implements_90003", "Change 'extends' to 'implements'"), Remove_declaration_for_Colon_0: diag(90004, ts.DiagnosticCategory.Message, "Remove_declaration_for_Colon_0_90004", "Remove declaration for: '{0}'"), Implement_interface_0: diag(90006, ts.DiagnosticCategory.Message, "Implement_interface_0_90006", "Implement interface '{0}'"), Implement_inherited_abstract_class: diag(90007, ts.DiagnosticCategory.Message, "Implement_inherited_abstract_class_90007", "Implement inherited abstract class"), Add_this_to_unresolved_variable: diag(90008, ts.DiagnosticCategory.Message, "Add_this_to_unresolved_variable_90008", "Add 'this.' to unresolved variable"), Import_0_from_module_1: diag(90013, ts.DiagnosticCategory.Message, "Import_0_from_module_1_90013", "Import '{0}' from module \"{1}\""), Change_0_to_1: diag(90014, ts.DiagnosticCategory.Message, "Change_0_to_1_90014", "Change '{0}' to '{1}'"), Add_0_to_existing_import_declaration_from_1: diag(90015, ts.DiagnosticCategory.Message, "Add_0_to_existing_import_declaration_from_1_90015", "Add '{0}' to existing import declaration from \"{1}\""), Declare_property_0: diag(90016, ts.DiagnosticCategory.Message, "Declare_property_0_90016", "Declare property '{0}'"), Add_index_signature_for_property_0: diag(90017, ts.DiagnosticCategory.Message, "Add_index_signature_for_property_0_90017", "Add index signature for property '{0}'"), Disable_checking_for_this_file: diag(90018, ts.DiagnosticCategory.Message, "Disable_checking_for_this_file_90018", "Disable checking for this file"), Ignore_this_error_message: diag(90019, ts.DiagnosticCategory.Message, "Ignore_this_error_message_90019", "Ignore this error message"), Initialize_property_0_in_the_constructor: diag(90020, ts.DiagnosticCategory.Message, "Initialize_property_0_in_the_constructor_90020", "Initialize property '{0}' in the constructor"), Initialize_static_property_0: diag(90021, ts.DiagnosticCategory.Message, "Initialize_static_property_0_90021", "Initialize static property '{0}'"), Change_spelling_to_0: diag(90022, ts.DiagnosticCategory.Message, "Change_spelling_to_0_90022", "Change spelling to '{0}'"), Declare_method_0: diag(90023, ts.DiagnosticCategory.Message, "Declare_method_0_90023", "Declare method '{0}'"), Declare_static_method_0: diag(90024, ts.DiagnosticCategory.Message, "Declare_static_method_0_90024", "Declare static method '{0}'"), Prefix_0_with_an_underscore: diag(90025, ts.DiagnosticCategory.Message, "Prefix_0_with_an_underscore_90025", "Prefix '{0}' with an underscore"), Rewrite_as_the_indexed_access_type_0: diag(90026, ts.DiagnosticCategory.Message, "Rewrite_as_the_indexed_access_type_0_90026", "Rewrite as the indexed access type '{0}'"), Declare_static_property_0: diag(90027, ts.DiagnosticCategory.Message, "Declare_static_property_0_90027", "Declare static property '{0}'"), Call_decorator_expression: diag(90028, ts.DiagnosticCategory.Message, "Call_decorator_expression_90028", "Call decorator expression"), Convert_function_to_an_ES2015_class: diag(95001, ts.DiagnosticCategory.Message, "Convert_function_to_an_ES2015_class_95001", "Convert function to an ES2015 class"), Convert_function_0_to_class: diag(95002, ts.DiagnosticCategory.Message, "Convert_function_0_to_class_95002", "Convert function '{0}' to class"), Extract_symbol: diag(95003, ts.DiagnosticCategory.Message, "Extract_symbol_95003", "Extract symbol"), Extract_to_0_in_1: diag(95004, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_95004", "Extract to {0} in {1}"), Extract_function: diag(95005, ts.DiagnosticCategory.Message, "Extract_function_95005", "Extract function"), Extract_constant: diag(95006, ts.DiagnosticCategory.Message, "Extract_constant_95006", "Extract constant"), Extract_to_0_in_enclosing_scope: diag(95007, ts.DiagnosticCategory.Message, "Extract_to_0_in_enclosing_scope_95007", "Extract to {0} in enclosing scope"), Extract_to_0_in_1_scope: diag(95008, ts.DiagnosticCategory.Message, "Extract_to_0_in_1_scope_95008", "Extract to {0} in {1} scope"), Annotate_with_type_from_JSDoc: diag(95009, ts.DiagnosticCategory.Message, "Annotate_with_type_from_JSDoc_95009", "Annotate with type from JSDoc"), Annotate_with_types_from_JSDoc: diag(95010, ts.DiagnosticCategory.Message, "Annotate_with_types_from_JSDoc_95010", "Annotate with types from JSDoc"), Infer_type_of_0_from_usage: diag(95011, ts.DiagnosticCategory.Message, "Infer_type_of_0_from_usage_95011", "Infer type of '{0}' from usage"), Infer_parameter_types_from_usage: diag(95012, ts.DiagnosticCategory.Message, "Infer_parameter_types_from_usage_95012", "Infer parameter types from usage"), Convert_to_default_import: diag(95013, ts.DiagnosticCategory.Message, "Convert_to_default_import_95013", "Convert to default import"), Install_0: diag(95014, ts.DiagnosticCategory.Message, "Install_0_95014", "Install '{0}'"), }; })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { ts.emptyArray = []; ts.emptyMap = ts.createMap(); ts.externalHelpersModuleNameText = "tslib"; function getDeclarationOfKind(symbol, kind) { var declarations = symbol.declarations; if (declarations) { for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) { var declaration = declarations_1[_i]; if (declaration.kind === kind) { return declaration; } } } return undefined; } ts.getDeclarationOfKind = getDeclarationOfKind; var stringWriter = createSingleLineStringWriter(); function createSingleLineStringWriter() { var str = ""; var writeText = function (text) { return str += text; }; return { string: function () { return str; }, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, writeSpace: writeText, writeStringLiteral: writeText, writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, // Completely ignore indentation for string writers. And map newlines to // a single space. writeLine: function () { return str += " "; }, increaseIndent: ts.noop, decreaseIndent: ts.noop, clear: function () { return str = ""; }, trackSymbol: ts.noop, reportInaccessibleThisError: ts.noop, reportInaccessibleUniqueSymbolError: ts.noop, reportPrivateInBaseOfClassExpression: ts.noop, }; } function usingSingleLineStringWriter(action) { var oldString = stringWriter.string(); try { action(stringWriter); return stringWriter.string(); } finally { stringWriter.clear(); stringWriter.writeKeyword(oldString); } } ts.usingSingleLineStringWriter = usingSingleLineStringWriter; function getFullWidth(node) { return node.end - node.pos; } ts.getFullWidth = getFullWidth; function getResolvedModule(sourceFile, moduleNameText) { return sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules.get(moduleNameText); } ts.getResolvedModule = getResolvedModule; function setResolvedModule(sourceFile, moduleNameText, resolvedModule) { if (!sourceFile.resolvedModules) { sourceFile.resolvedModules = ts.createMap(); } sourceFile.resolvedModules.set(moduleNameText, resolvedModule); } ts.setResolvedModule = setResolvedModule; function setResolvedTypeReferenceDirective(sourceFile, typeReferenceDirectiveName, resolvedTypeReferenceDirective) { if (!sourceFile.resolvedTypeReferenceDirectiveNames) { sourceFile.resolvedTypeReferenceDirectiveNames = ts.createMap(); } sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective); } ts.setResolvedTypeReferenceDirective = setResolvedTypeReferenceDirective; function moduleResolutionIsEqualTo(oldResolution, newResolution) { return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport && oldResolution.extension === newResolution.extension && oldResolution.resolvedFileName === newResolution.resolvedFileName && packageIdIsEqual(oldResolution.packageId, newResolution.packageId); } ts.moduleResolutionIsEqualTo = moduleResolutionIsEqualTo; function packageIdIsEqual(a, b) { return a === b || a && b && a.name === b.name && a.subModuleName === b.subModuleName && a.version === b.version; } function typeDirectiveIsEqualTo(oldResolution, newResolution) { return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.primary === newResolution.primary; } ts.typeDirectiveIsEqualTo = typeDirectiveIsEqualTo; function hasChangesInResolutions(names, newResolutions, oldResolutions, comparer) { ts.Debug.assert(names.length === newResolutions.length); for (var i = 0; i < names.length; i++) { var newResolution = newResolutions[i]; var oldResolution = oldResolutions && oldResolutions.get(names[i]); var changed = oldResolution ? !newResolution || !comparer(oldResolution, newResolution) : newResolution; if (changed) { return true; } } return false; } ts.hasChangesInResolutions = hasChangesInResolutions; // Returns true if this node contains a parse error anywhere underneath it. function containsParseError(node) { aggregateChildData(node); return (node.flags & 131072 /* ThisNodeOrAnySubNodesHasError */) !== 0; } ts.containsParseError = containsParseError; function aggregateChildData(node) { if (!(node.flags & 262144 /* HasAggregatedChildData */)) { // A node is considered to contain a parse error if: // a) the parser explicitly marked that it had an error // b) any of it's children reported that it had an error. var thisNodeOrAnySubNodesHasError = ((node.flags & 32768 /* ThisNodeHasError */) !== 0) || ts.forEachChild(node, containsParseError); // If so, mark ourselves accordingly. if (thisNodeOrAnySubNodesHasError) { node.flags |= 131072 /* ThisNodeOrAnySubNodesHasError */; } // Also mark that we've propagated the child information to this node. This way we can // always consult the bit directly on this node without needing to check its children // again. node.flags |= 262144 /* HasAggregatedChildData */; } } function getSourceFileOfNode(node) { while (node && node.kind !== 269 /* SourceFile */) { node = node.parent; } return node; } ts.getSourceFileOfNode = getSourceFileOfNode; function isStatementWithLocals(node) { switch (node.kind) { case 208 /* Block */: case 236 /* CaseBlock */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: return true; } return false; } ts.isStatementWithLocals = isStatementWithLocals; function getStartPositionOfLine(line, sourceFile) { ts.Debug.assert(line >= 0); return ts.getLineStarts(sourceFile)[line]; } ts.getStartPositionOfLine = getStartPositionOfLine; // This is a useful function for debugging purposes. function nodePosToString(node) { var file = getSourceFileOfNode(node); var loc = ts.getLineAndCharacterOfPosition(file, node.pos); return file.fileName + "(" + (loc.line + 1) + "," + (loc.character + 1) + ")"; } ts.nodePosToString = nodePosToString; function getEndLinePosition(line, sourceFile) { ts.Debug.assert(line >= 0); var lineStarts = ts.getLineStarts(sourceFile); var lineIndex = line; var sourceText = sourceFile.text; if (lineIndex + 1 === lineStarts.length) { // last line - return EOF return sourceText.length - 1; } else { // current line start var start = lineStarts[lineIndex]; // take the start position of the next line - 1 = it should be some line break var pos = lineStarts[lineIndex + 1] - 1; ts.Debug.assert(ts.isLineBreak(sourceText.charCodeAt(pos))); // walk backwards skipping line breaks, stop the the beginning of current line. // i.e: // // $ <- end of line for this position should match the start position while (start <= pos && ts.isLineBreak(sourceText.charCodeAt(pos))) { pos--; } return pos; } } ts.getEndLinePosition = getEndLinePosition; // Returns true if this node is missing from the actual source code. A 'missing' node is different // from 'undefined/defined'. When a node is undefined (which can happen for optional nodes // in the tree), it is definitely missing. However, a node may be defined, but still be // missing. This happens whenever the parser knows it needs to parse something, but can't // get anything in the source code that it expects at that location. For example: // // let a: ; // // Here, the Type in the Type-Annotation is not-optional (as there is a colon in the source // code). So the parser will attempt to parse out a type, and will create an actual node. // However, this node will be 'missing' in the sense that no actual source-code/tokens are // contained within it. function nodeIsMissing(node) { if (node === undefined) { return true; } return node.pos === node.end && node.pos >= 0 && node.kind !== 1 /* EndOfFileToken */; } ts.nodeIsMissing = nodeIsMissing; function nodeIsPresent(node) { return !nodeIsMissing(node); } ts.nodeIsPresent = nodeIsPresent; /** * Determine if the given comment is a triple-slash * * @return true if the comment is a triple-slash comment else false */ function isRecognizedTripleSlashComment(text, commentPos, commentEnd) { // Verify this is /// comment, but do the regexp match only when we first can find /// in the comment text // so that we don't end up computing comment string and doing match for all // comments if (text.charCodeAt(commentPos + 1) === 47 /* slash */ && commentPos + 2 < commentEnd && text.charCodeAt(commentPos + 2) === 47 /* slash */) { var textSubStr = text.substring(commentPos, commentEnd); return textSubStr.match(ts.fullTripleSlashReferencePathRegEx) || textSubStr.match(ts.fullTripleSlashAMDReferencePathRegEx) || textSubStr.match(fullTripleSlashReferenceTypeReferenceDirectiveRegEx) || textSubStr.match(defaultLibReferenceRegEx) ? true : false; } return false; } ts.isRecognizedTripleSlashComment = isRecognizedTripleSlashComment; function isPinnedComment(text, comment) { return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && text.charCodeAt(comment.pos + 2) === 33 /* exclamation */; } ts.isPinnedComment = isPinnedComment; function getTokenPosOfNode(node, sourceFile, includeJsDoc) { // With nodes that have no width (i.e. 'Missing' nodes), we actually *don't* // want to skip trivia because this will launch us forward to the next token. if (nodeIsMissing(node)) { return node.pos; } if (ts.isJSDocNode(node)) { return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); } if (includeJsDoc && ts.hasJSDocNodes(node)) { return getTokenPosOfNode(node.jsDoc[0]); } // For a syntax list, it is possible that one of its children has JSDocComment nodes, while // the syntax list itself considers them as normal trivia. Therefore if we simply skip // trivia for the list, we may have skipped the JSDocComment as well. So we should process its // first child to determine the actual position of its first token. if (node.kind === 290 /* SyntaxList */ && node._children.length > 0) { return getTokenPosOfNode(node._children[0], sourceFile, includeJsDoc); } return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos); } ts.getTokenPosOfNode = getTokenPosOfNode; function getNonDecoratorTokenPosOfNode(node, sourceFile) { if (nodeIsMissing(node) || !node.decorators) { return getTokenPosOfNode(node, sourceFile); } return ts.skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.decorators.end); } ts.getNonDecoratorTokenPosOfNode = getNonDecoratorTokenPosOfNode; function getSourceTextOfNodeFromSourceFile(sourceFile, node, includeTrivia) { if (includeTrivia === void 0) { includeTrivia = false; } if (nodeIsMissing(node)) { return ""; } var text = sourceFile.text; return text.substring(includeTrivia ? node.pos : ts.skipTrivia(text, node.pos), node.end); } ts.getSourceTextOfNodeFromSourceFile = getSourceTextOfNodeFromSourceFile; function getTextOfNodeFromSourceText(sourceText, node) { if (nodeIsMissing(node)) { return ""; } return sourceText.substring(ts.skipTrivia(sourceText, node.pos), node.end); } ts.getTextOfNodeFromSourceText = getTextOfNodeFromSourceText; function getTextOfNode(node, includeTrivia) { if (includeTrivia === void 0) { includeTrivia = false; } return getSourceTextOfNodeFromSourceFile(getSourceFileOfNode(node), node, includeTrivia); } ts.getTextOfNode = getTextOfNode; function getPos(range) { return range.pos; } /** * Note: it is expected that the `nodeArray` and the `node` are within the same file. * For example, searching for a `SourceFile` in a `SourceFile[]` wouldn't work. */ function indexOfNode(nodeArray, node) { return ts.binarySearch(nodeArray, node, getPos, ts.compareValues); } ts.indexOfNode = indexOfNode; /** * Gets flags that control emit behavior of a node. */ function getEmitFlags(node) { var emitNode = node.emitNode; return emitNode && emitNode.flags; } ts.getEmitFlags = getEmitFlags; function getLiteralText(node, sourceFile) { // If we don't need to downlevel and we can reach the original source text using // the node's parent reference, then simply get the text as it was originally written. if (!nodeIsSynthesized(node) && node.parent) { return getSourceTextOfNodeFromSourceFile(sourceFile, node); } var escapeText = getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ? escapeString : escapeNonAsciiString; // If we can't reach the original source text, use the canonical form if it's a number, // or a (possibly escaped) quoted form of the original text if it's string-like. switch (node.kind) { case 9 /* StringLiteral */: if (node.singleQuote) { return "'" + escapeText(node.text, 39 /* singleQuote */) + "'"; } else { return '"' + escapeText(node.text, 34 /* doubleQuote */) + '"'; } case 13 /* NoSubstitutionTemplateLiteral */: return "`" + escapeText(node.text, 96 /* backtick */) + "`"; case 14 /* TemplateHead */: // tslint:disable-next-line no-invalid-template-strings return "`" + escapeText(node.text, 96 /* backtick */) + "${"; case 15 /* TemplateMiddle */: // tslint:disable-next-line no-invalid-template-strings return "}" + escapeText(node.text, 96 /* backtick */) + "${"; case 16 /* TemplateTail */: return "}" + escapeText(node.text, 96 /* backtick */) + "`"; case 8 /* NumericLiteral */: case 12 /* RegularExpressionLiteral */: return node.text; } ts.Debug.fail("Literal kind '" + node.kind + "' not accounted for."); } ts.getLiteralText = getLiteralText; function getTextOfConstantValue(value) { return ts.isString(value) ? '"' + escapeNonAsciiString(value) + '"' : "" + value; } ts.getTextOfConstantValue = getTextOfConstantValue; // Add an extra underscore to identifiers that start with two underscores to avoid issues with magic names like '__proto__' function escapeLeadingUnderscores(identifier) { return (identifier.length >= 2 && identifier.charCodeAt(0) === 95 /* _ */ && identifier.charCodeAt(1) === 95 /* _ */ ? "_" + identifier : identifier); } ts.escapeLeadingUnderscores = escapeLeadingUnderscores; /** * @deprecated Use `id.escapedText` to get the escaped text of an Identifier. * @param identifier The identifier to escape */ function escapeIdentifier(identifier) { return identifier; } ts.escapeIdentifier = escapeIdentifier; // Make an identifier from an external module name by extracting the string after the last "/" and replacing // all non-alphanumeric characters with underscores function makeIdentifierFromModuleName(moduleName) { return ts.getBaseFileName(moduleName).replace(/^(\d)/, "_$1").replace(/\W/g, "_"); } ts.makeIdentifierFromModuleName = makeIdentifierFromModuleName; function isBlockOrCatchScoped(declaration) { return (ts.getCombinedNodeFlags(declaration) & 3 /* BlockScoped */) !== 0 || isCatchClauseVariableDeclarationOrBindingElement(declaration); } ts.isBlockOrCatchScoped = isBlockOrCatchScoped; function isCatchClauseVariableDeclarationOrBindingElement(declaration) { var node = getRootDeclaration(declaration); return node.kind === 227 /* VariableDeclaration */ && node.parent.kind === 264 /* CatchClause */; } ts.isCatchClauseVariableDeclarationOrBindingElement = isCatchClauseVariableDeclarationOrBindingElement; function isAmbientModule(node) { return node && node.kind === 234 /* ModuleDeclaration */ && (node.name.kind === 9 /* StringLiteral */ || isGlobalScopeAugmentation(node)); } ts.isAmbientModule = isAmbientModule; function isModuleWithStringLiteralName(node) { return ts.isModuleDeclaration(node) && node.name.kind === 9 /* StringLiteral */; } ts.isModuleWithStringLiteralName = isModuleWithStringLiteralName; function isNonGlobalAmbientModule(node) { return ts.isModuleDeclaration(node) && ts.isStringLiteral(node.name); } ts.isNonGlobalAmbientModule = isNonGlobalAmbientModule; /** Given a symbol for a module, checks that it is a shorthand ambient module. */ function isShorthandAmbientModuleSymbol(moduleSymbol) { return isShorthandAmbientModule(moduleSymbol.valueDeclaration); } ts.isShorthandAmbientModuleSymbol = isShorthandAmbientModuleSymbol; function isShorthandAmbientModule(node) { // The only kind of module that can be missing a body is a shorthand ambient module. return node && node.kind === 234 /* ModuleDeclaration */ && (!node.body); } function isBlockScopedContainerTopLevel(node) { return node.kind === 269 /* SourceFile */ || node.kind === 234 /* ModuleDeclaration */ || ts.isFunctionLike(node); } ts.isBlockScopedContainerTopLevel = isBlockScopedContainerTopLevel; function isGlobalScopeAugmentation(module) { return !!(module.flags & 512 /* GlobalAugmentation */); } ts.isGlobalScopeAugmentation = isGlobalScopeAugmentation; function isExternalModuleAugmentation(node) { // external module augmentation is a ambient module declaration that is either: // - defined in the top level scope and source file is an external module // - defined inside ambient module declaration located in the top level scope and source file not an external module if (!node || !isAmbientModule(node)) { return false; } switch (node.parent.kind) { case 269 /* SourceFile */: return ts.isExternalModule(node.parent); case 235 /* ModuleBlock */: return isAmbientModule(node.parent.parent) && !ts.isExternalModule(node.parent.parent.parent); } return false; } ts.isExternalModuleAugmentation = isExternalModuleAugmentation; function isEffectiveExternalModule(node, compilerOptions) { return ts.isExternalModule(node) || compilerOptions.isolatedModules || ((ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS) && !!node.commonJsModuleIndicator); } ts.isEffectiveExternalModule = isEffectiveExternalModule; function isBlockScope(node, parentNode) { switch (node.kind) { case 269 /* SourceFile */: case 236 /* CaseBlock */: case 264 /* CatchClause */: case 234 /* ModuleDeclaration */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 153 /* Constructor */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return true; case 208 /* Block */: // function block is not considered block-scope container // see comment in binder.ts: bind(...), case for SyntaxKind.Block return parentNode && !ts.isFunctionLike(parentNode); } return false; } ts.isBlockScope = isBlockScope; function isDeclarationWithTypeParameters(node) { switch (node.kind) { case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 151 /* MethodSignature */: case 158 /* IndexSignature */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 277 /* JSDocFunctionType */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 287 /* JSDocTemplateTag */: case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return true; default: ts.assertTypeIsNever(node); return false; } } ts.isDeclarationWithTypeParameters = isDeclarationWithTypeParameters; function isAnyImportSyntax(node) { switch (node.kind) { case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: return true; default: return false; } } ts.isAnyImportSyntax = isAnyImportSyntax; // Gets the nearest enclosing block scope container that has the provided node // as a descendant, that is not the provided node. function getEnclosingBlockScopeContainer(node) { var current = node.parent; while (current) { if (isBlockScope(current, current.parent)) { return current; } current = current.parent; } } ts.getEnclosingBlockScopeContainer = getEnclosingBlockScopeContainer; // Return display name of an identifier // Computed property names will just be emitted as "[]", where is the source // text of the expression in the computed property. function declarationNameToString(name) { return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name); } ts.declarationNameToString = declarationNameToString; function getNameFromIndexInfo(info) { return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined; } ts.getNameFromIndexInfo = getNameFromIndexInfo; function getTextOfPropertyName(name) { switch (name.kind) { case 71 /* Identifier */: return name.escapedText; case 9 /* StringLiteral */: case 8 /* NumericLiteral */: return escapeLeadingUnderscores(name.text); case 145 /* ComputedPropertyName */: if (isStringOrNumericLiteral(name.expression)) { return escapeLeadingUnderscores(name.expression.text); } } return undefined; } ts.getTextOfPropertyName = getTextOfPropertyName; function entityNameToString(name) { switch (name.kind) { case 71 /* Identifier */: return getFullWidth(name) === 0 ? ts.idText(name) : getTextOfNode(name); case 144 /* QualifiedName */: return entityNameToString(name.left) + "." + entityNameToString(name.right); case 180 /* PropertyAccessExpression */: return entityNameToString(name.expression) + "." + entityNameToString(name.name); } } ts.entityNameToString = entityNameToString; function createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3) { var sourceFile = getSourceFileOfNode(node); return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3); } ts.createDiagnosticForNode = createDiagnosticForNode; function createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3) { var span = getErrorSpanForNode(sourceFile, node); return ts.createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3); } ts.createDiagnosticForNodeInSourceFile = createDiagnosticForNodeInSourceFile; function createDiagnosticForNodeFromMessageChain(node, messageChain) { var sourceFile = getSourceFileOfNode(node); var span = getErrorSpanForNode(sourceFile, node); return { file: sourceFile, start: span.start, length: span.length, code: messageChain.code, category: messageChain.category, messageText: messageChain.next ? messageChain : messageChain.messageText }; } ts.createDiagnosticForNodeFromMessageChain = createDiagnosticForNodeFromMessageChain; function getSpanOfTokenAtPosition(sourceFile, pos) { var scanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ true, sourceFile.languageVariant, sourceFile.text, /*onError:*/ undefined, pos); scanner.scan(); var start = scanner.getTokenPos(); return ts.createTextSpanFromBounds(start, scanner.getTextPos()); } ts.getSpanOfTokenAtPosition = getSpanOfTokenAtPosition; function getErrorSpanForArrowFunction(sourceFile, node) { var pos = ts.skipTrivia(sourceFile.text, node.pos); if (node.body && node.body.kind === 208 /* 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 269 /* 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 227 /* VariableDeclaration */: case 177 /* BindingElement */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 234 /* ModuleDeclaration */: case 233 /* EnumDeclaration */: case 268 /* EnumMember */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 232 /* TypeAliasDeclaration */: errorNode = node.name; break; case 188 /* ArrowFunction */: return getErrorSpanForArrowFunction(sourceFile, node); } if (errorNode === undefined) { // If we don't have a better node, then just set the error on the first token of // construct. return getSpanOfTokenAtPosition(sourceFile, node.pos); } var pos = nodeIsMissing(errorNode) ? errorNode.pos : ts.skipTrivia(sourceFile.text, errorNode.pos); return ts.createTextSpanFromBounds(pos, errorNode.end); } ts.getErrorSpanForNode = getErrorSpanForNode; function isExternalOrCommonJsModule(file) { return (file.externalModuleIndicator || file.commonJsModuleIndicator) !== undefined; } ts.isExternalOrCommonJsModule = isExternalOrCommonJsModule; function isConstEnumDeclaration(node) { return node.kind === 233 /* EnumDeclaration */ && isConst(node); } ts.isConstEnumDeclaration = isConstEnumDeclaration; function isConst(node) { return !!(ts.getCombinedNodeFlags(node) & 2 /* Const */) || !!(ts.getCombinedModifierFlags(node) & 2048 /* Const */); } ts.isConst = isConst; function isLet(node) { return !!(ts.getCombinedNodeFlags(node) & 1 /* Let */); } ts.isLet = isLet; function isSuperCall(n) { return n.kind === 182 /* CallExpression */ && n.expression.kind === 97 /* SuperKeyword */; } ts.isSuperCall = isSuperCall; function isImportCall(n) { return n.kind === 182 /* CallExpression */ && n.expression.kind === 91 /* ImportKeyword */; } ts.isImportCall = isImportCall; function isPrologueDirective(node) { return node.kind === 211 /* ExpressionStatement */ && node.expression.kind === 9 /* StringLiteral */; } ts.isPrologueDirective = isPrologueDirective; function getLeadingCommentRangesOfNode(node, sourceFileOfNode) { return node.kind !== 10 /* JsxText */ ? ts.getLeadingCommentRanges(sourceFileOfNode.text, node.pos) : undefined; } ts.getLeadingCommentRangesOfNode = getLeadingCommentRangesOfNode; function getJSDocCommentRanges(node, text) { var commentRanges = (node.kind === 147 /* Parameter */ || node.kind === 146 /* TypeParameter */ || node.kind === 187 /* FunctionExpression */ || node.kind === 188 /* ArrowFunction */ || node.kind === 186 /* ParenthesizedExpression */) ? ts.concatenate(ts.getTrailingCommentRanges(text, node.pos), ts.getLeadingCommentRanges(text, node.pos)) : ts.getLeadingCommentRanges(text, node.pos); // True if the comment starts with '/**' but not if it is '/**/' return ts.filter(commentRanges, function (comment) { return text.charCodeAt(comment.pos + 1) === 42 /* asterisk */ && text.charCodeAt(comment.pos + 2) === 42 /* asterisk */ && text.charCodeAt(comment.pos + 3) !== 47 /* slash */; }); } ts.getJSDocCommentRanges = getJSDocCommentRanges; ts.fullTripleSlashReferencePathRegEx = /^(\/\/\/\s*/; var fullTripleSlashReferenceTypeReferenceDirectiveRegEx = /^(\/\/\/\s*/; ts.fullTripleSlashAMDReferencePathRegEx = /^(\/\/\/\s*/; var defaultLibReferenceRegEx = /^(\/\/\/\s*/; function isPartOfTypeNode(node) { if (159 /* FirstTypeNode */ <= node.kind && node.kind <= 174 /* LastTypeNode */) { return true; } switch (node.kind) { case 119 /* AnyKeyword */: case 133 /* NumberKeyword */: case 136 /* StringKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: case 139 /* UndefinedKeyword */: case 130 /* NeverKeyword */: return true; case 105 /* VoidKeyword */: return node.parent.kind !== 191 /* VoidExpression */; case 202 /* ExpressionWithTypeArguments */: return !isExpressionWithTypeArgumentsInClassExtendsClause(node); // Identifiers and qualified names may be type nodes, depending on their context. Climb // above them to find the lowest container case 71 /* Identifier */: // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. if (node.parent.kind === 144 /* QualifiedName */ && node.parent.right === node) { node = node.parent; } else if (node.parent.kind === 180 /* PropertyAccessExpression */ && node.parent.name === node) { node = node.parent; } // At this point, node is either a qualified name or an identifier ts.Debug.assert(node.kind === 71 /* Identifier */ || node.kind === 144 /* QualifiedName */ || node.kind === 180 /* PropertyAccessExpression */, "'node' was expected to be a qualified name, identifier or property access in 'isPartOfTypeNode'."); // falls through case 144 /* QualifiedName */: case 180 /* PropertyAccessExpression */: case 99 /* ThisKeyword */: var parent = node.parent; if (parent.kind === 163 /* TypeQuery */) { return false; } // Do not recursively call isPartOfTypeNode on the parent. In the example: // // let a: A.B.C; // // Calling isPartOfTypeNode would consider the qualified name A.B a type node. // Only C and A.B.C are type nodes. if (159 /* FirstTypeNode */ <= parent.kind && parent.kind <= 174 /* LastTypeNode */) { return true; } switch (parent.kind) { case 202 /* ExpressionWithTypeArguments */: return !isExpressionWithTypeArgumentsInClassExtendsClause(parent); case 146 /* TypeParameter */: return node === parent.constraint; case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 147 /* Parameter */: case 227 /* VariableDeclaration */: return node === parent.type; case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 153 /* Constructor */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return node === parent.type; case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: return node === parent.type; case 185 /* TypeAssertionExpression */: return node === parent.type; case 182 /* CallExpression */: case 183 /* NewExpression */: return parent.typeArguments && ts.indexOf(parent.typeArguments, node) >= 0; case 184 /* TaggedTemplateExpression */: // TODO (drosen): TaggedTemplateExpressions may eventually support type arguments. return false; } } return false; } ts.isPartOfTypeNode = isPartOfTypeNode; function isChildOfNodeWithKind(node, kind) { while (node) { if (node.kind === kind) { return true; } node = node.parent; } return false; } ts.isChildOfNodeWithKind = isChildOfNodeWithKind; // Warning: This has the same semantics as the forEach family of functions, // in that traversal terminates in the event that 'visitor' supplies a truthy value. function forEachReturnStatement(body, visitor) { return traverse(body); function traverse(node) { switch (node.kind) { case 220 /* ReturnStatement */: return visitor(node); case 236 /* CaseBlock */: case 208 /* Block */: case 212 /* IfStatement */: case 213 /* DoStatement */: case 214 /* WhileStatement */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 221 /* WithStatement */: case 222 /* SwitchStatement */: case 261 /* CaseClause */: case 262 /* DefaultClause */: case 223 /* LabeledStatement */: case 225 /* TryStatement */: case 264 /* CatchClause */: return ts.forEachChild(node, traverse); } } } ts.forEachReturnStatement = forEachReturnStatement; function forEachYieldExpression(body, visitor) { return traverse(body); function traverse(node) { switch (node.kind) { case 198 /* YieldExpression */: visitor(node); var operand = node.expression; if (operand) { traverse(operand); } return; case 233 /* EnumDeclaration */: case 231 /* InterfaceDeclaration */: case 234 /* ModuleDeclaration */: case 232 /* TypeAliasDeclaration */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: // These are not allowed inside a generator now, but eventually they may be allowed // as local types. Regardless, any yield statements contained within them should be // skipped in this traversal. return; default: if (ts.isFunctionLike(node)) { var name = node.name; if (name && name.kind === 145 /* ComputedPropertyName */) { // Note that we will not include methods/accessors of a class because they would require // first descending into the class. This is by design. traverse(name.expression); return; } } else if (!isPartOfTypeNode(node)) { // This is the general case, which should include mostly expressions and statements. // Also includes NodeArrays. ts.forEachChild(node, traverse); } } } } ts.forEachYieldExpression = forEachYieldExpression; /** * Gets the most likely element type for a TypeNode. This is not an exhaustive test * as it assumes a rest argument can only be an array type (either T[], or Array). * * @param node The type node. */ function getRestParameterElementType(node) { if (node && node.kind === 165 /* ArrayType */) { return node.elementType; } else if (node && node.kind === 160 /* TypeReference */) { return ts.singleOrUndefined(node.typeArguments); } else { return undefined; } } ts.getRestParameterElementType = getRestParameterElementType; function getMembersOfDeclaration(node) { switch (node.kind) { case 231 /* InterfaceDeclaration */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 164 /* TypeLiteral */: return node.members; case 179 /* ObjectLiteralExpression */: return node.properties; } } ts.getMembersOfDeclaration = getMembersOfDeclaration; function isVariableLike(node) { if (node) { switch (node.kind) { case 177 /* BindingElement */: case 268 /* EnumMember */: case 147 /* Parameter */: case 265 /* PropertyAssignment */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 266 /* ShorthandPropertyAssignment */: case 227 /* VariableDeclaration */: return true; } } return false; } ts.isVariableLike = isVariableLike; function isVariableDeclarationInVariableStatement(node) { return node.parent.kind === 228 /* VariableDeclarationList */ && node.parent.parent.kind === 209 /* VariableStatement */; } ts.isVariableDeclarationInVariableStatement = isVariableDeclarationInVariableStatement; function isValidESSymbolDeclaration(node) { return ts.isVariableDeclaration(node) ? isConst(node) && ts.isIdentifier(node.name) && isVariableDeclarationInVariableStatement(node) : ts.isPropertyDeclaration(node) ? hasReadonlyModifier(node) && hasStaticModifier(node) : ts.isPropertySignature(node) && hasReadonlyModifier(node); } ts.isValidESSymbolDeclaration = isValidESSymbolDeclaration; function introducesArgumentsExoticObject(node) { switch (node.kind) { case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: return true; } return false; } ts.introducesArgumentsExoticObject = introducesArgumentsExoticObject; function unwrapInnermostStatementOfLabel(node, beforeUnwrapLabelCallback) { while (true) { if (beforeUnwrapLabelCallback) { beforeUnwrapLabelCallback(node); } if (node.statement.kind !== 223 /* LabeledStatement */) { return node.statement; } node = node.statement; } } ts.unwrapInnermostStatementOfLabel = unwrapInnermostStatementOfLabel; function isFunctionBlock(node) { return node && node.kind === 208 /* Block */ && ts.isFunctionLike(node.parent); } ts.isFunctionBlock = isFunctionBlock; function isObjectLiteralMethod(node) { return node && node.kind === 152 /* MethodDeclaration */ && node.parent.kind === 179 /* ObjectLiteralExpression */; } ts.isObjectLiteralMethod = isObjectLiteralMethod; function isObjectLiteralOrClassExpressionMethod(node) { return node.kind === 152 /* MethodDeclaration */ && (node.parent.kind === 179 /* ObjectLiteralExpression */ || node.parent.kind === 200 /* ClassExpression */); } ts.isObjectLiteralOrClassExpressionMethod = isObjectLiteralOrClassExpressionMethod; function isIdentifierTypePredicate(predicate) { return predicate && predicate.kind === 1 /* Identifier */; } ts.isIdentifierTypePredicate = isIdentifierTypePredicate; function isThisTypePredicate(predicate) { return predicate && predicate.kind === 0 /* This */; } ts.isThisTypePredicate = isThisTypePredicate; function getPropertyAssignment(objectLiteral, key, key2) { return ts.filter(objectLiteral.properties, function (property) { if (property.kind === 265 /* PropertyAssignment */) { var propName = getTextOfPropertyName(property.name); return key === propName || (key2 && key2 === propName); } }); } ts.getPropertyAssignment = getPropertyAssignment; function getContainingFunction(node) { return ts.findAncestor(node.parent, ts.isFunctionLike); } ts.getContainingFunction = getContainingFunction; function getContainingClass(node) { return ts.findAncestor(node.parent, ts.isClassLike); } ts.getContainingClass = getContainingClass; function getThisContainer(node, includeArrowFunctions) { while (true) { node = node.parent; if (!node) { return undefined; } switch (node.kind) { case 145 /* ComputedPropertyName */: // If the grandparent node is an object literal (as opposed to a class), // then the computed property is not a 'this' container. // A computed property name in a class needs to be a this container // so that we can error on it. if (ts.isClassLike(node.parent.parent)) { return node; } // If this is a computed property, then the parent should not // make it a this container. The parent might be a property // in an object literal, like a method or accessor. But in order for // such a parent to be a this container, the reference must be in // the *body* of the container. node = node.parent; break; case 148 /* Decorator */: // Decorators are always applied outside of the body of a class or method. if (node.parent.kind === 147 /* Parameter */ && ts.isClassElement(node.parent.parent)) { // If the decorator's parent is a Parameter, we resolve the this container from // the grandparent class declaration. node = node.parent.parent; } else if (ts.isClassElement(node.parent)) { // If the decorator's parent is a class element, we resolve the 'this' container // from the parent class declaration. node = node.parent; } break; case 188 /* ArrowFunction */: if (!includeArrowFunctions) { continue; } // falls through case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 234 /* ModuleDeclaration */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 233 /* EnumDeclaration */: case 269 /* SourceFile */: return node; } } } ts.getThisContainer = getThisContainer; function getNewTargetContainer(node) { var container = getThisContainer(node, /*includeArrowFunctions*/ false); if (container) { switch (container.kind) { case 153 /* Constructor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: return container; } } return undefined; } ts.getNewTargetContainer = getNewTargetContainer; /** * Given an super call/property node, returns the closest node where * - a super call/property access is legal in the node and not legal in the parent node the node. * i.e. super call is legal in constructor but not legal in the class body. * - the container is an arrow function (so caller might need to call getSuperContainer again in case it needs to climb higher) * - a super call/property is definitely illegal in the container (but might be legal in some subnode) * i.e. super property access is illegal in function declaration but can be legal in the statement list */ function getSuperContainer(node, stopOnFunctions) { while (true) { node = node.parent; if (!node) { return node; } switch (node.kind) { case 145 /* ComputedPropertyName */: node = node.parent; break; case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: if (!stopOnFunctions) { continue; } // falls through case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return node; case 148 /* Decorator */: // Decorators are always applied outside of the body of a class or method. if (node.parent.kind === 147 /* Parameter */ && ts.isClassElement(node.parent.parent)) { // If the decorator's parent is a Parameter, we resolve the this container from // the grandparent class declaration. node = node.parent.parent; } else if (ts.isClassElement(node.parent)) { // If the decorator's parent is a class element, we resolve the 'this' container // from the parent class declaration. node = node.parent; } break; } } } ts.getSuperContainer = getSuperContainer; function getImmediatelyInvokedFunctionExpression(func) { if (func.kind === 187 /* FunctionExpression */ || func.kind === 188 /* ArrowFunction */) { var prev = func; var parent = func.parent; while (parent.kind === 186 /* ParenthesizedExpression */) { prev = parent; parent = parent.parent; } if (parent.kind === 182 /* CallExpression */ && parent.expression === prev) { return parent; } } } ts.getImmediatelyInvokedFunctionExpression = getImmediatelyInvokedFunctionExpression; /** * Determines whether a node is a property or element access expression for `super`. */ function isSuperProperty(node) { var kind = node.kind; return (kind === 180 /* PropertyAccessExpression */ || kind === 181 /* ElementAccessExpression */) && node.expression.kind === 97 /* SuperKeyword */; } ts.isSuperProperty = isSuperProperty; /** * Determines whether a node is a property or element access expression for `this`. */ function isThisProperty(node) { var kind = node.kind; return (kind === 180 /* PropertyAccessExpression */ || kind === 181 /* ElementAccessExpression */) && node.expression.kind === 99 /* ThisKeyword */; } ts.isThisProperty = isThisProperty; function getEntityNameFromTypeNode(node) { switch (node.kind) { case 160 /* TypeReference */: return node.typeName; case 202 /* ExpressionWithTypeArguments */: return isEntityNameExpression(node.expression) ? node.expression : undefined; case 71 /* Identifier */: case 144 /* QualifiedName */: return node; } return undefined; } ts.getEntityNameFromTypeNode = getEntityNameFromTypeNode; function getInvokedExpression(node) { if (node.kind === 184 /* TaggedTemplateExpression */) { return node.tag; } else if (ts.isJsxOpeningLikeElement(node)) { return node.tagName; } // Will either be a CallExpression, NewExpression, or Decorator. return node.expression; } ts.getInvokedExpression = getInvokedExpression; function nodeCanBeDecorated(node, parent, grandparent) { switch (node.kind) { case 230 /* ClassDeclaration */: // classes are valid targets return true; case 150 /* PropertyDeclaration */: // property declarations are valid if their parent is a class declaration. return parent.kind === 230 /* ClassDeclaration */; case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 152 /* MethodDeclaration */: // if this method has a body and its parent is a class declaration, this is a valid target. return node.body !== undefined && parent.kind === 230 /* ClassDeclaration */; case 147 /* Parameter */: // if the parameter's parent has a body and its grandparent is a class declaration, this is a valid target; return parent.body !== undefined && (parent.kind === 153 /* Constructor */ || parent.kind === 152 /* MethodDeclaration */ || parent.kind === 155 /* SetAccessor */) && grandparent.kind === 230 /* ClassDeclaration */; } return false; } ts.nodeCanBeDecorated = nodeCanBeDecorated; function nodeIsDecorated(node, parent, grandparent) { return node.decorators !== undefined && nodeCanBeDecorated(node, parent, grandparent); } ts.nodeIsDecorated = nodeIsDecorated; function nodeOrChildIsDecorated(node, parent, grandparent) { return nodeIsDecorated(node, parent, grandparent) || childIsDecorated(node, parent); } ts.nodeOrChildIsDecorated = nodeOrChildIsDecorated; function childIsDecorated(node, parent) { switch (node.kind) { case 230 /* ClassDeclaration */: return ts.forEach(node.members, function (m) { return nodeOrChildIsDecorated(m, node, parent); }); case 152 /* MethodDeclaration */: case 155 /* SetAccessor */: return ts.forEach(node.parameters, function (p) { return nodeIsDecorated(p, node, parent); }); } } ts.childIsDecorated = childIsDecorated; function isJSXTagName(node) { var parent = node.parent; if (parent.kind === 252 /* JsxOpeningElement */ || parent.kind === 251 /* JsxSelfClosingElement */ || parent.kind === 253 /* JsxClosingElement */) { return parent.tagName === node; } return false; } ts.isJSXTagName = isJSXTagName; function isExpressionNode(node) { switch (node.kind) { case 97 /* SuperKeyword */: case 95 /* NullKeyword */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 12 /* RegularExpressionLiteral */: case 178 /* ArrayLiteralExpression */: case 179 /* ObjectLiteralExpression */: case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: case 182 /* CallExpression */: case 183 /* NewExpression */: case 184 /* TaggedTemplateExpression */: case 203 /* AsExpression */: case 185 /* TypeAssertionExpression */: case 204 /* NonNullExpression */: case 186 /* ParenthesizedExpression */: case 187 /* FunctionExpression */: case 200 /* ClassExpression */: case 188 /* ArrowFunction */: case 191 /* VoidExpression */: case 189 /* DeleteExpression */: case 190 /* TypeOfExpression */: case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: case 195 /* BinaryExpression */: case 196 /* ConditionalExpression */: case 199 /* SpreadElement */: case 197 /* TemplateExpression */: case 13 /* NoSubstitutionTemplateLiteral */: case 201 /* OmittedExpression */: case 250 /* JsxElement */: case 251 /* JsxSelfClosingElement */: case 254 /* JsxFragment */: case 198 /* YieldExpression */: case 192 /* AwaitExpression */: case 205 /* MetaProperty */: return true; case 144 /* QualifiedName */: while (node.parent.kind === 144 /* QualifiedName */) { node = node.parent; } return node.parent.kind === 163 /* TypeQuery */ || isJSXTagName(node); case 71 /* Identifier */: if (node.parent.kind === 163 /* TypeQuery */ || isJSXTagName(node)) { return true; } // falls through case 8 /* NumericLiteral */: case 9 /* StringLiteral */: case 99 /* ThisKeyword */: return isInExpressionContext(node); default: return false; } } ts.isExpressionNode = isExpressionNode; function isInExpressionContext(node) { var parent = node.parent; switch (parent.kind) { case 227 /* VariableDeclaration */: case 147 /* Parameter */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 268 /* EnumMember */: case 265 /* PropertyAssignment */: case 177 /* BindingElement */: return parent.initializer === node; case 211 /* ExpressionStatement */: case 212 /* IfStatement */: case 213 /* DoStatement */: case 214 /* WhileStatement */: case 220 /* ReturnStatement */: case 221 /* WithStatement */: case 222 /* SwitchStatement */: case 261 /* CaseClause */: case 224 /* ThrowStatement */: return parent.expression === node; case 215 /* ForStatement */: var forStatement = parent; return (forStatement.initializer === node && forStatement.initializer.kind !== 228 /* VariableDeclarationList */) || forStatement.condition === node || forStatement.incrementor === node; case 216 /* ForInStatement */: case 217 /* ForOfStatement */: var forInStatement = parent; return (forInStatement.initializer === node && forInStatement.initializer.kind !== 228 /* VariableDeclarationList */) || forInStatement.expression === node; case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: return node === parent.expression; case 206 /* TemplateSpan */: return node === parent.expression; case 145 /* ComputedPropertyName */: return node === parent.expression; case 148 /* Decorator */: case 260 /* JsxExpression */: case 259 /* JsxSpreadAttribute */: case 267 /* SpreadAssignment */: return true; case 202 /* ExpressionWithTypeArguments */: return parent.expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); default: return isExpressionNode(parent); } } ts.isInExpressionContext = isInExpressionContext; function isExternalModuleImportEqualsDeclaration(node) { return node.kind === 238 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 249 /* 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 === 238 /* ImportEqualsDeclaration */ && node.moduleReference.kind !== 249 /* ExternalModuleReference */; } ts.isInternalModuleImportEqualsDeclaration = isInternalModuleImportEqualsDeclaration; function isSourceFileJavaScript(file) { return isInJavaScriptFile(file); } ts.isSourceFileJavaScript = isSourceFileJavaScript; function isInJavaScriptFile(node) { return node && !!(node.flags & 65536 /* JavaScriptFile */); } ts.isInJavaScriptFile = isInJavaScriptFile; function isInJSDoc(node) { return node && !!(node.flags & 1048576 /* JSDoc */); } ts.isInJSDoc = isInJSDoc; function isJSDocIndexSignature(node) { return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object" && node.typeArguments && node.typeArguments.length === 2 && (node.typeArguments[0].kind === 136 /* StringKeyword */ || node.typeArguments[0].kind === 133 /* NumberKeyword */); } ts.isJSDocIndexSignature = isJSDocIndexSignature; /** * Returns true if the node is a CallExpression to the identifier 'require' with * exactly one argument (of the form 'require("name")'). * This function does not test if the node is in a JavaScript file or not. */ function isRequireCall(callExpression, checkArgumentIsStringLiteral) { if (callExpression.kind !== 182 /* CallExpression */) { return false; } var _a = callExpression, expression = _a.expression, args = _a.arguments; if (expression.kind !== 71 /* Identifier */ || expression.escapedText !== "require") { return false; } if (args.length !== 1) { return false; } var arg = args[0]; return !checkArgumentIsStringLiteral || arg.kind === 9 /* StringLiteral */ || arg.kind === 13 /* NoSubstitutionTemplateLiteral */; } ts.isRequireCall = isRequireCall; function isSingleOrDoubleQuote(charCode) { return charCode === 39 /* singleQuote */ || charCode === 34 /* doubleQuote */; } ts.isSingleOrDoubleQuote = isSingleOrDoubleQuote; function isStringDoubleQuoted(str, sourceFile) { return getSourceTextOfNodeFromSourceFile(sourceFile, str).charCodeAt(0) === 34 /* doubleQuote */; } ts.isStringDoubleQuoted = isStringDoubleQuoted; /** * Returns true if the node is a variable declaration whose initializer is a function or class expression. * This function does not test if the node is in a JavaScript file or not. */ function isDeclarationOfFunctionOrClassExpression(s) { if (s.valueDeclaration && s.valueDeclaration.kind === 227 /* VariableDeclaration */) { var declaration = s.valueDeclaration; return declaration.initializer && (declaration.initializer.kind === 187 /* FunctionExpression */ || declaration.initializer.kind === 200 /* ClassExpression */); } return false; } ts.isDeclarationOfFunctionOrClassExpression = isDeclarationOfFunctionOrClassExpression; function getRightMostAssignedExpression(node) { while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) { node = node.right; } return node; } ts.getRightMostAssignedExpression = getRightMostAssignedExpression; function isExportsIdentifier(node) { return ts.isIdentifier(node) && node.escapedText === "exports"; } ts.isExportsIdentifier = isExportsIdentifier; function isModuleExportsPropertyAccessExpression(node) { return ts.isPropertyAccessExpression(node) && ts.isIdentifier(node.expression) && node.expression.escapedText === "module" && node.name.escapedText === "exports"; } ts.isModuleExportsPropertyAccessExpression = isModuleExportsPropertyAccessExpression; /// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property /// assignments we treat as special in the binder function getSpecialPropertyAssignmentKind(expr) { if (!isInJavaScriptFile(expr)) { return 0 /* None */; } if (expr.operatorToken.kind !== 58 /* EqualsToken */ || expr.left.kind !== 180 /* PropertyAccessExpression */) { return 0 /* None */; } var lhs = expr.left; if (lhs.expression.kind === 71 /* Identifier */) { var lhsId = lhs.expression; if (lhsId.escapedText === "exports") { // exports.name = expr return 1 /* ExportsProperty */; } else if (lhsId.escapedText === "module" && lhs.name.escapedText === "exports") { // module.exports = expr return 2 /* ModuleExports */; } else { // F.x = expr return 5 /* Property */; } } else if (lhs.expression.kind === 99 /* ThisKeyword */) { return 4 /* ThisProperty */; } else if (lhs.expression.kind === 180 /* PropertyAccessExpression */) { // chained dot, e.g. x.y.z = expr; this var is the 'x.y' part var innerPropertyAccess = lhs.expression; if (innerPropertyAccess.expression.kind === 71 /* Identifier */) { // module.exports.name = expr var innerPropertyAccessIdentifier = innerPropertyAccess.expression; if (innerPropertyAccessIdentifier.escapedText === "module" && innerPropertyAccess.name.escapedText === "exports") { return 1 /* ExportsProperty */; } if (innerPropertyAccess.name.escapedText === "prototype") { return 3 /* PrototypeProperty */; } } } return 0 /* None */; } ts.getSpecialPropertyAssignmentKind = getSpecialPropertyAssignmentKind; function isSpecialPropertyDeclaration(expr) { return isInJavaScriptFile(expr) && expr.parent && expr.parent.kind === 211 /* ExpressionStatement */ && !!ts.getJSDocTypeTag(expr.parent); } ts.isSpecialPropertyDeclaration = isSpecialPropertyDeclaration; function getExternalModuleName(node) { if (node.kind === 239 /* ImportDeclaration */) { return node.moduleSpecifier; } if (node.kind === 238 /* ImportEqualsDeclaration */) { var reference = node.moduleReference; if (reference.kind === 249 /* ExternalModuleReference */) { return reference.expression; } } if (node.kind === 245 /* ExportDeclaration */) { return node.moduleSpecifier; } if (isModuleWithStringLiteralName(node)) { return node.name; } } ts.getExternalModuleName = getExternalModuleName; function getNamespaceDeclarationNode(node) { if (node.kind === 238 /* ImportEqualsDeclaration */) { return node; } var importClause = node.importClause; if (importClause && importClause.namedBindings && importClause.namedBindings.kind === 241 /* NamespaceImport */) { return importClause.namedBindings; } } ts.getNamespaceDeclarationNode = getNamespaceDeclarationNode; function isDefaultImport(node) { return node.kind === 239 /* ImportDeclaration */ && node.importClause && !!node.importClause.name; } ts.isDefaultImport = isDefaultImport; function hasQuestionToken(node) { if (node) { switch (node.kind) { case 147 /* Parameter */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 266 /* ShorthandPropertyAssignment */: case 265 /* PropertyAssignment */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return node.questionToken !== undefined; } } return false; } ts.hasQuestionToken = hasQuestionToken; function isJSDocConstructSignature(node) { return node.kind === 277 /* JSDocFunctionType */ && node.parameters.length > 0 && node.parameters[0].name && node.parameters[0].name.escapedText === "new"; } ts.isJSDocConstructSignature = isJSDocConstructSignature; function getAllJSDocs(node) { if (ts.isJSDocTypedefTag(node)) { return [node.parent]; } return getJSDocCommentsAndTags(node); } ts.getAllJSDocs = getAllJSDocs; function getSourceOfAssignment(node) { return ts.isExpressionStatement(node) && node.expression && ts.isBinaryExpression(node.expression) && node.expression.operatorToken.kind === 58 /* EqualsToken */ && node.expression.right; } ts.getSourceOfAssignment = getSourceOfAssignment; function getSingleInitializerOfVariableStatement(node, child) { return ts.isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0].initializer === child) && node.declarationList.declarations[0].initializer; } ts.getSingleInitializerOfVariableStatement = getSingleInitializerOfVariableStatement; function getSingleVariableOfVariableStatement(node, child) { return ts.isVariableStatement(node) && node.declarationList.declarations.length > 0 && (!child || node.declarationList.declarations[0] === child) && node.declarationList.declarations[0]; } ts.getSingleVariableOfVariableStatement = getSingleVariableOfVariableStatement; function getNestedModuleDeclaration(node) { return node.kind === 234 /* ModuleDeclaration */ && node.body && node.body.kind === 234 /* ModuleDeclaration */ && node.body; } ts.getNestedModuleDeclaration = getNestedModuleDeclaration; function getJSDocCommentsAndTags(node) { var result; getJSDocCommentsAndTagsWorker(node); return result || ts.emptyArray; function getJSDocCommentsAndTagsWorker(node) { var parent = node.parent; if (parent && (parent.kind === 265 /* PropertyAssignment */ || getNestedModuleDeclaration(parent))) { getJSDocCommentsAndTagsWorker(parent); } // Try to recognize this pattern when node is initializer of variable declaration and JSDoc comments are on containing variable statement. // /** // * @param {number} name // * @returns {number} // */ // var x = function(name) { return name.length; } if (parent && parent.parent && (getSingleVariableOfVariableStatement(parent.parent, node) || getSourceOfAssignment(parent.parent))) { getJSDocCommentsAndTagsWorker(parent.parent); } if (parent && parent.parent && parent.parent.parent && getSingleInitializerOfVariableStatement(parent.parent.parent, node)) { getJSDocCommentsAndTagsWorker(parent.parent.parent); } if (ts.isBinaryExpression(node) && getSpecialPropertyAssignmentKind(node) !== 0 /* None */ || node.kind === 180 /* PropertyAccessExpression */ && node.parent && node.parent.kind === 211 /* ExpressionStatement */) { getJSDocCommentsAndTagsWorker(parent); } // Pull parameter comments from declaring function as well if (node.kind === 147 /* Parameter */) { result = ts.addRange(result, ts.getJSDocParameterTags(node)); } if (isVariableLike(node) && node.initializer && ts.hasJSDocNodes(node.initializer)) { result = ts.addRange(result, node.initializer.jsDoc); } if (ts.hasJSDocNodes(node)) { result = ts.addRange(result, node.jsDoc); } } } ts.getJSDocCommentsAndTags = getJSDocCommentsAndTags; /** Does the opposite of `getJSDocParameterTags`: given a JSDoc parameter, finds the parameter corresponding to it. */ function getParameterSymbolFromJSDoc(node) { if (node.symbol) { return node.symbol; } if (!ts.isIdentifier(node.name)) { return undefined; } var name = node.name.escapedText; var decl = getHostSignatureFromJSDoc(node); if (!decl) { return undefined; } var parameter = ts.find(decl.parameters, function (p) { return p.name.kind === 71 /* Identifier */ && p.name.escapedText === name; }); return parameter && parameter.symbol; } ts.getParameterSymbolFromJSDoc = getParameterSymbolFromJSDoc; function getHostSignatureFromJSDoc(node) { var host = getJSDocHost(node); var decl = getSourceOfAssignment(host) || getSingleInitializerOfVariableStatement(host) || getSingleVariableOfVariableStatement(host) || getNestedModuleDeclaration(host) || host; return decl && ts.isFunctionLike(decl) ? decl : undefined; } ts.getHostSignatureFromJSDoc = getHostSignatureFromJSDoc; function getJSDocHost(node) { ts.Debug.assert(node.parent.kind === 279 /* JSDocComment */); return node.parent.parent; } ts.getJSDocHost = getJSDocHost; function getTypeParameterFromJsDoc(node) { var name = node.name.escapedText; var typeParameters = node.parent.parent.parent.typeParameters; return ts.find(typeParameters, function (p) { return p.name.escapedText === name; }); } ts.getTypeParameterFromJsDoc = getTypeParameterFromJsDoc; function hasRestParameter(s) { var last = ts.lastOrUndefined(s.parameters); return last && isRestParameter(last); } ts.hasRestParameter = hasRestParameter; function isRestParameter(node) { return node.dotDotDotToken !== undefined; } ts.isRestParameter = isRestParameter; var AssignmentKind; (function (AssignmentKind) { AssignmentKind[AssignmentKind["None"] = 0] = "None"; AssignmentKind[AssignmentKind["Definite"] = 1] = "Definite"; AssignmentKind[AssignmentKind["Compound"] = 2] = "Compound"; })(AssignmentKind = ts.AssignmentKind || (ts.AssignmentKind = {})); function getAssignmentTargetKind(node) { var parent = node.parent; while (true) { switch (parent.kind) { case 195 /* BinaryExpression */: var binaryOperator = parent.operatorToken.kind; return isAssignmentOperator(binaryOperator) && parent.left === node ? binaryOperator === 58 /* EqualsToken */ ? 1 /* Definite */ : 2 /* Compound */ : 0 /* None */; case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: var unaryOperator = parent.operator; return unaryOperator === 43 /* PlusPlusToken */ || unaryOperator === 44 /* MinusMinusToken */ ? 2 /* Compound */ : 0 /* None */; case 216 /* ForInStatement */: case 217 /* ForOfStatement */: return parent.initializer === node ? 1 /* Definite */ : 0 /* None */; case 186 /* ParenthesizedExpression */: case 178 /* ArrayLiteralExpression */: case 199 /* SpreadElement */: node = parent; break; case 266 /* ShorthandPropertyAssignment */: if (parent.name !== node) { return 0 /* None */; } node = parent.parent; break; case 265 /* PropertyAssignment */: if (parent.name === node) { return 0 /* None */; } node = parent.parent; break; default: return 0 /* None */; } parent = node.parent; } } ts.getAssignmentTargetKind = getAssignmentTargetKind; // A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property // assignment in an object literal that is an assignment target, or if it is parented by an array literal that is // an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ a }] = xxx'. // (Note that `p` is not a target in the above examples, only `a`.) function isAssignmentTarget(node) { return getAssignmentTargetKind(node) !== 0 /* None */; } ts.isAssignmentTarget = isAssignmentTarget; function walkUp(node, kind) { while (node && node.kind === kind) { node = node.parent; } return node; } function walkUpParenthesizedTypes(node) { return walkUp(node, 169 /* ParenthesizedType */); } ts.walkUpParenthesizedTypes = walkUpParenthesizedTypes; function walkUpParenthesizedExpressions(node) { return walkUp(node, 186 /* ParenthesizedExpression */); } ts.walkUpParenthesizedExpressions = walkUpParenthesizedExpressions; // a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped function isDeleteTarget(node) { if (node.kind !== 180 /* PropertyAccessExpression */ && node.kind !== 181 /* ElementAccessExpression */) { return false; } node = walkUpParenthesizedExpressions(node.parent); return node && node.kind === 189 /* DeleteExpression */; } ts.isDeleteTarget = isDeleteTarget; function isNodeDescendantOf(node, ancestor) { while (node) { if (node === ancestor) return true; node = node.parent; } return false; } ts.isNodeDescendantOf = isNodeDescendantOf; // True if the given identifier, string literal, or number literal is the name of a declaration node function isDeclarationName(name) { switch (name.kind) { case 71 /* Identifier */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: return ts.isDeclaration(name.parent) && name.parent.name === name; default: return false; } } ts.isDeclarationName = isDeclarationName; // See GH#16030 function isAnyDeclarationName(name) { switch (name.kind) { case 71 /* Identifier */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: if (ts.isDeclaration(name.parent)) { return name.parent.name === name; } var binExp = name.parent.parent; return ts.isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== 0 /* None */ && ts.getNameOfDeclaration(binExp) === name; default: return false; } } ts.isAnyDeclarationName = isAnyDeclarationName; function isLiteralComputedPropertyDeclarationName(node) { return (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) && node.parent.kind === 145 /* ComputedPropertyName */ && ts.isDeclaration(node.parent.parent); } ts.isLiteralComputedPropertyDeclarationName = isLiteralComputedPropertyDeclarationName; // Return true if the given identifier is classified as an IdentifierName function isIdentifierName(node) { var parent = node.parent; switch (parent.kind) { case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 268 /* EnumMember */: case 265 /* PropertyAssignment */: case 180 /* PropertyAccessExpression */: // Name in member declaration or property name in property access return parent.name === node; case 144 /* QualifiedName */: // Name on right hand side of dot in a type query if (parent.right === node) { while (parent.kind === 144 /* QualifiedName */) { parent = parent.parent; } return parent.kind === 163 /* TypeQuery */; } return false; case 177 /* BindingElement */: case 243 /* ImportSpecifier */: // Property name in binding element or import specifier return parent.propertyName === node; case 247 /* ExportSpecifier */: case 257 /* JsxAttribute */: // Any name in an export specifier or JSX Attribute return true; } return false; } ts.isIdentifierName = isIdentifierName; // An alias symbol is created by one of the following declarations: // import = ... // import from ... // import * as from ... // import { x as } from ... // export { x as } from ... // export = // export default function isAliasSymbolDeclaration(node) { return node.kind === 238 /* ImportEqualsDeclaration */ || node.kind === 237 /* NamespaceExportDeclaration */ || node.kind === 240 /* ImportClause */ && !!node.name || node.kind === 241 /* NamespaceImport */ || node.kind === 243 /* ImportSpecifier */ || node.kind === 247 /* ExportSpecifier */ || node.kind === 244 /* ExportAssignment */ && exportAssignmentIsAlias(node); } ts.isAliasSymbolDeclaration = isAliasSymbolDeclaration; function exportAssignmentIsAlias(node) { return isEntityNameExpression(node.expression); } ts.exportAssignmentIsAlias = exportAssignmentIsAlias; function getClassExtendsHeritageClauseElement(node) { var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */); return heritageClause && heritageClause.types.length > 0 ? heritageClause.types[0] : undefined; } ts.getClassExtendsHeritageClauseElement = getClassExtendsHeritageClauseElement; function getClassImplementsHeritageClauseElements(node) { var heritageClause = getHeritageClause(node.heritageClauses, 108 /* ImplementsKeyword */); return heritageClause ? heritageClause.types : undefined; } ts.getClassImplementsHeritageClauseElements = getClassImplementsHeritageClauseElements; function getInterfaceBaseTypeNodes(node) { var heritageClause = getHeritageClause(node.heritageClauses, 85 /* ExtendsKeyword */); return heritageClause ? heritageClause.types : undefined; } ts.getInterfaceBaseTypeNodes = getInterfaceBaseTypeNodes; function getHeritageClause(clauses, kind) { if (clauses) { for (var _i = 0, clauses_1 = clauses; _i < clauses_1.length; _i++) { var clause = clauses_1[_i]; if (clause.token === kind) { return clause; } } } return undefined; } ts.getHeritageClause = getHeritageClause; function tryResolveScriptReference(host, sourceFile, reference) { if (!host.getCompilerOptions().noResolve) { var referenceFileName = ts.isRootedDiskPath(reference.fileName) ? reference.fileName : ts.combinePaths(ts.getDirectoryPath(sourceFile.fileName), reference.fileName); return host.getSourceFile(referenceFileName); } } ts.tryResolveScriptReference = tryResolveScriptReference; function getAncestor(node, kind) { while (node) { if (node.kind === kind) { return node; } node = node.parent; } return undefined; } ts.getAncestor = getAncestor; function getFileReferenceFromReferencePath(comment, commentRange) { var simpleReferenceRegEx = /^\/\/\/\s*, where name * is a property of the Symbol constructor that denotes a built in * Symbol. */ function hasDynamicName(declaration) { var name = ts.getNameOfDeclaration(declaration); return name && isDynamicName(name); } ts.hasDynamicName = hasDynamicName; function isDynamicName(name) { return name.kind === 145 /* ComputedPropertyName */ && !isStringOrNumericLiteral(name.expression) && !isWellKnownSymbolSyntactically(name.expression); } ts.isDynamicName = isDynamicName; /** * Checks if the expression is of the form: * Symbol.name * where Symbol is literally the word "Symbol", and name is any identifierName */ function isWellKnownSymbolSyntactically(node) { return ts.isPropertyAccessExpression(node) && isESSymbolIdentifier(node.expression); } ts.isWellKnownSymbolSyntactically = isWellKnownSymbolSyntactically; function getPropertyNameForPropertyNameNode(name) { if (name.kind === 71 /* Identifier */) { return name.escapedText; } if (name.kind === 9 /* StringLiteral */ || name.kind === 8 /* NumericLiteral */) { return escapeLeadingUnderscores(name.text); } if (name.kind === 145 /* ComputedPropertyName */) { var nameExpression = name.expression; if (isWellKnownSymbolSyntactically(nameExpression)) { return getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name)); } else if (nameExpression.kind === 9 /* StringLiteral */ || nameExpression.kind === 8 /* NumericLiteral */) { return escapeLeadingUnderscores(nameExpression.text); } } return undefined; } ts.getPropertyNameForPropertyNameNode = getPropertyNameForPropertyNameNode; function getTextOfIdentifierOrLiteral(node) { if (node) { if (node.kind === 71 /* Identifier */) { return ts.idText(node); } if (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) { return node.text; } } return undefined; } ts.getTextOfIdentifierOrLiteral = getTextOfIdentifierOrLiteral; function getEscapedTextOfIdentifierOrLiteral(node) { if (node) { if (node.kind === 71 /* Identifier */) { return node.escapedText; } if (node.kind === 9 /* StringLiteral */ || node.kind === 8 /* NumericLiteral */) { return escapeLeadingUnderscores(node.text); } } return undefined; } ts.getEscapedTextOfIdentifierOrLiteral = getEscapedTextOfIdentifierOrLiteral; function getPropertyNameForKnownSymbolName(symbolName) { return "__@" + symbolName; } ts.getPropertyNameForKnownSymbolName = getPropertyNameForKnownSymbolName; /** * Includes the word "Symbol" with unicode escapes */ function isESSymbolIdentifier(node) { return node.kind === 71 /* Identifier */ && node.escapedText === "Symbol"; } ts.isESSymbolIdentifier = isESSymbolIdentifier; function isPushOrUnshiftIdentifier(node) { return node.escapedText === "push" || node.escapedText === "unshift"; } ts.isPushOrUnshiftIdentifier = isPushOrUnshiftIdentifier; function isParameterDeclaration(node) { var root = getRootDeclaration(node); return root.kind === 147 /* Parameter */; } ts.isParameterDeclaration = isParameterDeclaration; function getRootDeclaration(node) { while (node.kind === 177 /* BindingElement */) { node = node.parent.parent; } return node; } ts.getRootDeclaration = getRootDeclaration; function nodeStartsNewLexicalEnvironment(node) { var kind = node.kind; return kind === 153 /* Constructor */ || kind === 187 /* FunctionExpression */ || kind === 229 /* FunctionDeclaration */ || kind === 188 /* ArrowFunction */ || kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */ || kind === 234 /* ModuleDeclaration */ || kind === 269 /* SourceFile */; } ts.nodeStartsNewLexicalEnvironment = nodeStartsNewLexicalEnvironment; function nodeIsSynthesized(range) { return ts.positionIsSynthesized(range.pos) || ts.positionIsSynthesized(range.end); } ts.nodeIsSynthesized = nodeIsSynthesized; function getOriginalSourceFile(sourceFile) { return ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; } ts.getOriginalSourceFile = getOriginalSourceFile; var Associativity; (function (Associativity) { Associativity[Associativity["Left"] = 0] = "Left"; Associativity[Associativity["Right"] = 1] = "Right"; })(Associativity = ts.Associativity || (ts.Associativity = {})); function getExpressionAssociativity(expression) { var operator = getOperator(expression); var hasArguments = expression.kind === 183 /* NewExpression */ && expression.arguments !== undefined; return getOperatorAssociativity(expression.kind, operator, hasArguments); } ts.getExpressionAssociativity = getExpressionAssociativity; function getOperatorAssociativity(kind, operator, hasArguments) { switch (kind) { case 183 /* NewExpression */: return hasArguments ? 0 /* Left */ : 1 /* Right */; case 193 /* PrefixUnaryExpression */: case 190 /* TypeOfExpression */: case 191 /* VoidExpression */: case 189 /* DeleteExpression */: case 192 /* AwaitExpression */: case 196 /* ConditionalExpression */: case 198 /* YieldExpression */: return 1 /* Right */; case 195 /* BinaryExpression */: switch (operator) { case 40 /* AsteriskAsteriskToken */: case 58 /* EqualsToken */: case 59 /* PlusEqualsToken */: case 60 /* MinusEqualsToken */: case 62 /* AsteriskAsteriskEqualsToken */: case 61 /* AsteriskEqualsToken */: case 63 /* SlashEqualsToken */: case 64 /* PercentEqualsToken */: case 65 /* LessThanLessThanEqualsToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 68 /* AmpersandEqualsToken */: case 70 /* CaretEqualsToken */: case 69 /* BarEqualsToken */: return 1 /* Right */; } } return 0 /* Left */; } ts.getOperatorAssociativity = getOperatorAssociativity; function getExpressionPrecedence(expression) { var operator = getOperator(expression); var hasArguments = expression.kind === 183 /* NewExpression */ && expression.arguments !== undefined; return getOperatorPrecedence(expression.kind, operator, hasArguments); } ts.getExpressionPrecedence = getExpressionPrecedence; function getOperator(expression) { if (expression.kind === 195 /* BinaryExpression */) { return expression.operatorToken.kind; } else if (expression.kind === 193 /* PrefixUnaryExpression */ || expression.kind === 194 /* PostfixUnaryExpression */) { return expression.operator; } else { return expression.kind; } } ts.getOperator = getOperator; function getOperatorPrecedence(nodeKind, operatorKind, hasArguments) { switch (nodeKind) { case 99 /* ThisKeyword */: case 97 /* SuperKeyword */: case 71 /* Identifier */: case 95 /* NullKeyword */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 8 /* NumericLiteral */: case 9 /* StringLiteral */: case 178 /* ArrayLiteralExpression */: case 179 /* ObjectLiteralExpression */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 200 /* ClassExpression */: case 250 /* JsxElement */: case 251 /* JsxSelfClosingElement */: case 254 /* JsxFragment */: case 12 /* RegularExpressionLiteral */: case 13 /* NoSubstitutionTemplateLiteral */: case 197 /* TemplateExpression */: case 186 /* ParenthesizedExpression */: case 201 /* OmittedExpression */: return 19; case 184 /* TaggedTemplateExpression */: case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: return 18; case 183 /* NewExpression */: return hasArguments ? 18 : 17; case 182 /* CallExpression */: return 17; case 194 /* PostfixUnaryExpression */: return 16; case 193 /* PrefixUnaryExpression */: case 190 /* TypeOfExpression */: case 191 /* VoidExpression */: case 189 /* DeleteExpression */: case 192 /* AwaitExpression */: return 15; case 195 /* BinaryExpression */: switch (operatorKind) { case 51 /* ExclamationToken */: case 52 /* TildeToken */: return 15; case 40 /* AsteriskAsteriskToken */: case 39 /* AsteriskToken */: case 41 /* SlashToken */: case 42 /* PercentToken */: return 14; case 37 /* PlusToken */: case 38 /* MinusToken */: return 13; case 45 /* LessThanLessThanToken */: case 46 /* GreaterThanGreaterThanToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: return 12; case 27 /* LessThanToken */: case 30 /* LessThanEqualsToken */: case 29 /* GreaterThanToken */: case 31 /* GreaterThanEqualsToken */: case 92 /* InKeyword */: case 93 /* InstanceOfKeyword */: return 11; case 32 /* EqualsEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: return 10; case 48 /* AmpersandToken */: return 9; case 50 /* CaretToken */: return 8; case 49 /* BarToken */: return 7; case 53 /* AmpersandAmpersandToken */: return 6; case 54 /* BarBarToken */: return 5; case 58 /* EqualsToken */: case 59 /* PlusEqualsToken */: case 60 /* MinusEqualsToken */: case 62 /* AsteriskAsteriskEqualsToken */: case 61 /* AsteriskEqualsToken */: case 63 /* SlashEqualsToken */: case 64 /* PercentEqualsToken */: case 65 /* LessThanLessThanEqualsToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 68 /* AmpersandEqualsToken */: case 70 /* CaretEqualsToken */: case 69 /* BarEqualsToken */: return 3; case 26 /* CommaToken */: return 0; default: return -1; } case 196 /* ConditionalExpression */: return 4; case 198 /* YieldExpression */: return 2; case 199 /* SpreadElement */: return 1; case 293 /* CommaListExpression */: return 0; default: return -1; } } ts.getOperatorPrecedence = getOperatorPrecedence; function createDiagnosticCollection() { var nonFileDiagnostics = []; var fileDiagnostics = ts.createMap(); var hasReadNonFileDiagnostics = false; var diagnosticsModified = false; var modificationCount = 0; return { add: add, getGlobalDiagnostics: getGlobalDiagnostics, getDiagnostics: getDiagnostics, getModificationCount: getModificationCount, reattachFileDiagnostics: reattachFileDiagnostics }; function getModificationCount() { return modificationCount; } function reattachFileDiagnostics(newFile) { ts.forEach(fileDiagnostics.get(newFile.fileName), function (diagnostic) { return diagnostic.file = newFile; }); } function add(diagnostic) { var diagnostics; if (diagnostic.file) { diagnostics = fileDiagnostics.get(diagnostic.file.fileName); if (!diagnostics) { diagnostics = []; fileDiagnostics.set(diagnostic.file.fileName, diagnostics); } } else { // If we've already read the non-file diagnostics, do not modify the existing array. if (hasReadNonFileDiagnostics) { hasReadNonFileDiagnostics = false; nonFileDiagnostics = nonFileDiagnostics.slice(); } diagnostics = nonFileDiagnostics; } diagnostics.push(diagnostic); diagnosticsModified = true; modificationCount++; } function getGlobalDiagnostics() { sortAndDeduplicate(); hasReadNonFileDiagnostics = true; return nonFileDiagnostics; } function getDiagnostics(fileName) { sortAndDeduplicate(); if (fileName) { return fileDiagnostics.get(fileName) || []; } var allDiagnostics = []; function pushDiagnostic(d) { allDiagnostics.push(d); } ts.forEach(nonFileDiagnostics, pushDiagnostic); fileDiagnostics.forEach(function (diagnostics) { ts.forEach(diagnostics, pushDiagnostic); }); return ts.sortAndDeduplicateDiagnostics(allDiagnostics); } function sortAndDeduplicate() { if (!diagnosticsModified) { return; } diagnosticsModified = false; nonFileDiagnostics = ts.sortAndDeduplicateDiagnostics(nonFileDiagnostics); fileDiagnostics.forEach(function (diagnostics, key) { fileDiagnostics.set(key, ts.sortAndDeduplicateDiagnostics(diagnostics)); }); } } ts.createDiagnosticCollection = createDiagnosticCollection; // This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator, // paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in // the language service. These characters should be escaped when printing, and if any characters are added, // the map below must be updated. Note that this regexp *does not* include the 'delete' character. // There is no reason for this other than that JSON.stringify does not handle it either. var doubleQuoteEscapedCharsRegExp = /[\\\"\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var singleQuoteEscapedCharsRegExp = /[\\\'\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var backtickQuoteEscapedCharsRegExp = /[\\\`\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g; var escapedCharsMap = ts.createMapFromTemplate({ "\0": "\\0", "\t": "\\t", "\v": "\\v", "\f": "\\f", "\b": "\\b", "\r": "\\r", "\n": "\\n", "\\": "\\\\", "\"": "\\\"", "\'": "\\\'", "\`": "\\\`", "\u2028": "\\u2028", "\u2029": "\\u2029", "\u0085": "\\u0085" // nextLine }); var escapedNullRegExp = /\\0[0-9]/g; /** * Based heavily on the abstract 'Quote'/'QuoteJSONString' operation from ECMA-262 (24.3.2.2), * but augmented for a few select characters (e.g. lineSeparator, paragraphSeparator, nextLine) * Note that this doesn't actually wrap the input in double quotes. */ function escapeString(s, quoteChar) { var escapedCharsRegExp = quoteChar === 96 /* backtick */ ? backtickQuoteEscapedCharsRegExp : quoteChar === 39 /* singleQuote */ ? singleQuoteEscapedCharsRegExp : doubleQuoteEscapedCharsRegExp; return s.replace(escapedCharsRegExp, getReplacement).replace(escapedNullRegExp, nullReplacement); } ts.escapeString = escapeString; function nullReplacement(c) { return "\\x00" + c.charAt(c.length - 1); } function getReplacement(c) { return escapedCharsMap.get(c) || get16BitUnicodeEscapeSequence(c.charCodeAt(0)); } function isIntrinsicJsxName(name) { var ch = name.charCodeAt(0); return (ch >= 97 /* a */ && ch <= 122 /* z */) || name.indexOf("-") > -1; } ts.isIntrinsicJsxName = isIntrinsicJsxName; function get16BitUnicodeEscapeSequence(charCode) { var hexCharCode = charCode.toString(16).toUpperCase(); var paddedHexCode = ("0000" + hexCharCode).slice(-4); return "\\u" + paddedHexCode; } var nonAsciiCharacters = /[^\u0000-\u007F]/g; function escapeNonAsciiString(s, quoteChar) { s = escapeString(s, quoteChar); // Replace non-ASCII characters with '\uNNNN' escapes if any exist. // Otherwise just return the original string. return nonAsciiCharacters.test(s) ? s.replace(nonAsciiCharacters, function (c) { return get16BitUnicodeEscapeSequence(c.charCodeAt(0)); }) : s; } ts.escapeNonAsciiString = escapeNonAsciiString; var indentStrings = ["", " "]; function getIndentString(level) { if (indentStrings[level] === undefined) { indentStrings[level] = getIndentString(level - 1) + indentStrings[1]; } return indentStrings[level]; } ts.getIndentString = getIndentString; function getIndentSize() { return indentStrings[1].length; } ts.getIndentSize = getIndentSize; function createTextWriter(newLine) { var output; var indent; var lineStart; var lineCount; var linePos; function write(s) { if (s && s.length) { if (lineStart) { output += getIndentString(indent); lineStart = false; } output += s; } } function reset() { output = ""; indent = 0; lineStart = true; lineCount = 0; linePos = 0; } function rawWrite(s) { if (s !== undefined) { if (lineStart) { lineStart = false; } output += s; } } function writeLiteral(s) { if (s && s.length) { write(s); var lineStartsOfS = ts.computeLineStarts(s); if (lineStartsOfS.length > 1) { lineCount = lineCount + lineStartsOfS.length - 1; linePos = output.length - s.length + ts.lastOrUndefined(lineStartsOfS); } } } function writeLine() { if (!lineStart) { output += newLine; lineCount++; linePos = output.length; lineStart = true; } } function writeTextOfNode(text, node) { write(getTextOfNodeFromSourceText(text, node)); } reset(); return { write: write, rawWrite: rawWrite, writeTextOfNode: writeTextOfNode, writeLiteral: writeLiteral, writeLine: writeLine, increaseIndent: function () { indent++; }, decreaseIndent: function () { indent--; }, getIndent: function () { return indent; }, getTextPos: function () { return output.length; }, getLine: function () { return lineCount + 1; }, getColumn: function () { return lineStart ? indent * getIndentSize() + 1 : output.length - linePos + 1; }, getText: function () { return output; }, isAtStartOfLine: function () { return lineStart; }, reset: reset }; } ts.createTextWriter = createTextWriter; function getResolvedExternalModuleName(host, file) { return file.moduleName || getExternalModuleNameFromPath(host, file.fileName); } ts.getResolvedExternalModuleName = getResolvedExternalModuleName; function getExternalModuleNameFromDeclaration(host, resolver, declaration) { var file = resolver.getExternalModuleFileFromDeclaration(declaration); if (!file || file.isDeclarationFile) { return undefined; } return getResolvedExternalModuleName(host, file); } ts.getExternalModuleNameFromDeclaration = getExternalModuleNameFromDeclaration; /** * Resolves a local path to a path which is absolute to the base of the emit */ function getExternalModuleNameFromPath(host, fileName) { var getCanonicalFileName = function (f) { return host.getCanonicalFileName(f); }; var dir = ts.toPath(host.getCommonSourceDirectory(), host.getCurrentDirectory(), getCanonicalFileName); var filePath = ts.getNormalizedAbsolutePath(fileName, host.getCurrentDirectory()); var relativePath = ts.getRelativePathToDirectoryOrUrl(dir, filePath, dir, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); return ts.removeFileExtension(relativePath); } ts.getExternalModuleNameFromPath = getExternalModuleNameFromPath; function getOwnEmitOutputFilePath(sourceFile, host, extension) { var compilerOptions = host.getCompilerOptions(); var emitOutputFilePathWithoutExtension; if (compilerOptions.outDir) { emitOutputFilePathWithoutExtension = ts.removeFileExtension(getSourceFilePathInNewDir(sourceFile, host, compilerOptions.outDir)); } else { emitOutputFilePathWithoutExtension = ts.removeFileExtension(sourceFile.fileName); } return emitOutputFilePathWithoutExtension + extension; } ts.getOwnEmitOutputFilePath = getOwnEmitOutputFilePath; function getDeclarationEmitOutputFilePath(sourceFile, host) { var options = host.getCompilerOptions(); var outputDir = options.declarationDir || options.outDir; // Prefer declaration folder if specified var path = outputDir ? getSourceFilePathInNewDir(sourceFile, host, outputDir) : sourceFile.fileName; return ts.removeFileExtension(path) + ".d.ts" /* Dts */; } ts.getDeclarationEmitOutputFilePath = getDeclarationEmitOutputFilePath; /** * Gets the source files that are expected to have an emit output. * * Originally part of `forEachExpectedEmitFile`, this functionality was extracted to support * transformations. * * @param host An EmitHost. * @param targetSourceFile An optional target source file to emit. */ function getSourceFilesToEmit(host, targetSourceFile) { var options = host.getCompilerOptions(); var isSourceFileFromExternalLibrary = function (file) { return host.isSourceFileFromExternalLibrary(file); }; if (options.outFile || options.out) { var moduleKind = ts.getEmitModuleKind(options); var moduleEmitEnabled_1 = moduleKind === ts.ModuleKind.AMD || moduleKind === ts.ModuleKind.System; // Can emit only sources that are not declaration file and are either non module code or module with --module or --target es6 specified return ts.filter(host.getSourceFiles(), function (sourceFile) { return (moduleEmitEnabled_1 || !ts.isExternalModule(sourceFile)) && sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary); }); } else { var sourceFiles = targetSourceFile === undefined ? host.getSourceFiles() : [targetSourceFile]; return ts.filter(sourceFiles, function (sourceFile) { return sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary); }); } } ts.getSourceFilesToEmit = getSourceFilesToEmit; /** Don't call this for `--outFile`, just for `--outDir` or plain emit. `--outFile` needs additional checks. */ function sourceFileMayBeEmitted(sourceFile, options, isSourceFileFromExternalLibrary) { return !(options.noEmitForJsFiles && isSourceFileJavaScript(sourceFile)) && !sourceFile.isDeclarationFile && !isSourceFileFromExternalLibrary(sourceFile); } ts.sourceFileMayBeEmitted = sourceFileMayBeEmitted; function getSourceFilePathInNewDir(sourceFile, host, newDirPath) { var sourceFilePath = ts.getNormalizedAbsolutePath(sourceFile.fileName, host.getCurrentDirectory()); var commonSourceDirectory = host.getCommonSourceDirectory(); var isSourceFileInCommonSourceDirectory = host.getCanonicalFileName(sourceFilePath).indexOf(host.getCanonicalFileName(commonSourceDirectory)) === 0; sourceFilePath = isSourceFileInCommonSourceDirectory ? sourceFilePath.substring(commonSourceDirectory.length) : sourceFilePath; return ts.combinePaths(newDirPath, sourceFilePath); } ts.getSourceFilePathInNewDir = getSourceFilePathInNewDir; function writeFile(host, diagnostics, fileName, data, writeByteOrderMark, sourceFiles) { host.writeFile(fileName, data, writeByteOrderMark, function (hostErrorMessage) { diagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Could_not_write_file_0_Colon_1, fileName, hostErrorMessage)); }, sourceFiles); } ts.writeFile = writeFile; function getLineOfLocalPosition(currentSourceFile, pos) { return ts.getLineAndCharacterOfPosition(currentSourceFile, pos).line; } ts.getLineOfLocalPosition = getLineOfLocalPosition; function getLineOfLocalPositionFromLineMap(lineMap, pos) { return ts.computeLineAndCharacterOfPosition(lineMap, pos).line; } ts.getLineOfLocalPositionFromLineMap = getLineOfLocalPositionFromLineMap; function getFirstConstructorWithBody(node) { return ts.forEach(node.members, function (member) { if (member.kind === 153 /* Constructor */ && nodeIsPresent(member.body)) { return member; } }); } ts.getFirstConstructorWithBody = getFirstConstructorWithBody; function getSetAccessorValueParameter(accessor) { if (accessor && accessor.parameters.length > 0) { var hasThis = accessor.parameters.length === 2 && parameterIsThisKeyword(accessor.parameters[0]); return accessor.parameters[hasThis ? 1 : 0]; } } /** Get the type annotation for the value parameter. */ function getSetAccessorTypeAnnotationNode(accessor) { var parameter = getSetAccessorValueParameter(accessor); return parameter && parameter.type; } ts.getSetAccessorTypeAnnotationNode = getSetAccessorTypeAnnotationNode; function getThisParameter(signature) { if (signature.parameters.length) { var thisParameter = signature.parameters[0]; if (parameterIsThisKeyword(thisParameter)) { return thisParameter; } } } ts.getThisParameter = getThisParameter; function parameterIsThisKeyword(parameter) { return isThisIdentifier(parameter.name); } ts.parameterIsThisKeyword = parameterIsThisKeyword; function isThisIdentifier(node) { return node && node.kind === 71 /* Identifier */ && identifierIsThisKeyword(node); } ts.isThisIdentifier = isThisIdentifier; function identifierIsThisKeyword(id) { return id.originalKeywordKind === 99 /* ThisKeyword */; } ts.identifierIsThisKeyword = identifierIsThisKeyword; function getAllAccessorDeclarations(declarations, accessor) { var firstAccessor; var secondAccessor; var getAccessor; var setAccessor; if (hasDynamicName(accessor)) { firstAccessor = accessor; if (accessor.kind === 154 /* GetAccessor */) { getAccessor = accessor; } else if (accessor.kind === 155 /* SetAccessor */) { setAccessor = accessor; } else { ts.Debug.fail("Accessor has wrong kind"); } } else { ts.forEach(declarations, function (member) { if ((member.kind === 154 /* GetAccessor */ || member.kind === 155 /* SetAccessor */) && hasModifier(member, 32 /* Static */) === hasModifier(accessor, 32 /* Static */)) { var memberName = getPropertyNameForPropertyNameNode(member.name); var accessorName = getPropertyNameForPropertyNameNode(accessor.name); if (memberName === accessorName) { if (!firstAccessor) { firstAccessor = member; } else if (!secondAccessor) { secondAccessor = member; } if (member.kind === 154 /* GetAccessor */ && !getAccessor) { getAccessor = member; } if (member.kind === 155 /* SetAccessor */ && !setAccessor) { setAccessor = member; } } } }); } return { firstAccessor: firstAccessor, secondAccessor: secondAccessor, getAccessor: getAccessor, setAccessor: setAccessor }; } ts.getAllAccessorDeclarations = getAllAccessorDeclarations; /** * Gets the effective type annotation of a variable, parameter, or property. If the node was * parsed in a JavaScript file, gets the type annotation from JSDoc. */ function getEffectiveTypeAnnotationNode(node, checkJSDoc) { if (node.type) { return node.type; } if (checkJSDoc || isInJavaScriptFile(node)) { return ts.getJSDocType(node); } } ts.getEffectiveTypeAnnotationNode = getEffectiveTypeAnnotationNode; /** * Gets the effective return type annotation of a signature. If the node was parsed in a * JavaScript file, gets the return type annotation from JSDoc. */ function getEffectiveReturnTypeNode(node, checkJSDoc) { if (node.type) { return node.type; } if (checkJSDoc || isInJavaScriptFile(node)) { return ts.getJSDocReturnType(node); } } ts.getEffectiveReturnTypeNode = getEffectiveReturnTypeNode; /** * Gets the effective type parameters. If the node was parsed in a * JavaScript file, gets the type parameters from the `@template` tag from JSDoc. */ function getEffectiveTypeParameterDeclarations(node, checkJSDoc) { if (node.typeParameters) { return node.typeParameters; } if (checkJSDoc || isInJavaScriptFile(node)) { var templateTag = ts.getJSDocTemplateTag(node); return templateTag && templateTag.typeParameters; } } ts.getEffectiveTypeParameterDeclarations = getEffectiveTypeParameterDeclarations; /** * Gets the effective type annotation of the value parameter of a set accessor. If the node * was parsed in a JavaScript file, gets the type annotation from JSDoc. */ function getEffectiveSetAccessorTypeAnnotationNode(node, checkJSDoc) { var parameter = getSetAccessorValueParameter(node); return parameter && getEffectiveTypeAnnotationNode(parameter, checkJSDoc); } ts.getEffectiveSetAccessorTypeAnnotationNode = getEffectiveSetAccessorTypeAnnotationNode; function emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments) { emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, node.pos, leadingComments); } ts.emitNewLineBeforeLeadingComments = emitNewLineBeforeLeadingComments; function emitNewLineBeforeLeadingCommentsOfPosition(lineMap, writer, pos, leadingComments) { // If the leading comments start on different line than the start of node, write new line if (leadingComments && leadingComments.length && pos !== leadingComments[0].pos && getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, leadingComments[0].pos)) { writer.writeLine(); } } ts.emitNewLineBeforeLeadingCommentsOfPosition = emitNewLineBeforeLeadingCommentsOfPosition; function emitNewLineBeforeLeadingCommentOfPosition(lineMap, writer, pos, commentPos) { // If the leading comments start on different line than the start of node, write new line if (pos !== commentPos && getLineOfLocalPositionFromLineMap(lineMap, pos) !== getLineOfLocalPositionFromLineMap(lineMap, commentPos)) { writer.writeLine(); } } ts.emitNewLineBeforeLeadingCommentOfPosition = emitNewLineBeforeLeadingCommentOfPosition; function emitComments(text, lineMap, writer, comments, leadingSeparator, trailingSeparator, newLine, writeComment) { if (comments && comments.length > 0) { if (leadingSeparator) { writer.write(" "); } var emitInterveningSeparator = false; for (var _i = 0, comments_1 = comments; _i < comments_1.length; _i++) { var comment = comments_1[_i]; if (emitInterveningSeparator) { writer.write(" "); emitInterveningSeparator = false; } writeComment(text, lineMap, writer, comment.pos, comment.end, newLine); if (comment.hasTrailingNewLine) { writer.writeLine(); } else { emitInterveningSeparator = true; } } if (emitInterveningSeparator && trailingSeparator) { writer.write(" "); } } } ts.emitComments = emitComments; /** * Detached comment is a comment at the top of file or function body that is separated from * the next statement by space. */ function emitDetachedComments(text, lineMap, writer, writeComment, node, newLine, removeComments) { var leadingComments; var currentDetachedCommentInfo; if (removeComments) { // removeComments is true, only reserve pinned comment at the top of file // For example: // /*! Pinned Comment */ // // var x = 10; if (node.pos === 0) { leadingComments = ts.filter(ts.getLeadingCommentRanges(text, node.pos), isPinnedCommentLocal); } } else { // removeComments is false, just get detached as normal and bypass the process to filter comment leadingComments = ts.getLeadingCommentRanges(text, node.pos); } if (leadingComments) { var detachedComments = []; var lastComment = void 0; for (var _i = 0, leadingComments_1 = leadingComments; _i < leadingComments_1.length; _i++) { var comment = leadingComments_1[_i]; if (lastComment) { var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, lastComment.end); var commentLine = getLineOfLocalPositionFromLineMap(lineMap, comment.pos); if (commentLine >= lastCommentLine + 2) { // There was a blank line between the last comment and this comment. This // comment is not part of the copyright comments. Return what we have so // far. break; } } detachedComments.push(comment); lastComment = comment; } if (detachedComments.length) { // All comments look like they could have been part of the copyright header. Make // sure there is at least one blank line between it and the node. If not, it's not // a copyright header. var lastCommentLine = getLineOfLocalPositionFromLineMap(lineMap, ts.lastOrUndefined(detachedComments).end); var nodeLine = getLineOfLocalPositionFromLineMap(lineMap, ts.skipTrivia(text, node.pos)); if (nodeLine >= lastCommentLine + 2) { // Valid detachedComments emitNewLineBeforeLeadingComments(lineMap, writer, node, leadingComments); emitComments(text, lineMap, writer, detachedComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, writeComment); currentDetachedCommentInfo = { nodePos: node.pos, detachedCommentEndPos: ts.lastOrUndefined(detachedComments).end }; } } } return currentDetachedCommentInfo; function isPinnedCommentLocal(comment) { return isPinnedComment(text, comment); } } ts.emitDetachedComments = emitDetachedComments; function writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine) { if (text.charCodeAt(commentPos + 1) === 42 /* asterisk */) { var firstCommentLineAndCharacter = ts.computeLineAndCharacterOfPosition(lineMap, commentPos); var lineCount = lineMap.length; var firstCommentLineIndent = void 0; for (var pos = commentPos, currentLine = firstCommentLineAndCharacter.line; pos < commentEnd; currentLine++) { var nextLineStart = (currentLine + 1) === lineCount ? text.length + 1 : lineMap[currentLine + 1]; if (pos !== commentPos) { // If we are not emitting first line, we need to write the spaces to adjust the alignment if (firstCommentLineIndent === undefined) { firstCommentLineIndent = calculateIndent(text, lineMap[firstCommentLineAndCharacter.line], commentPos); } // These are number of spaces writer is going to write at current indent var currentWriterIndentSpacing = writer.getIndent() * getIndentSize(); // Number of spaces we want to be writing // eg: Assume writer indent // module m { // /* starts at character 9 this is line 1 // * starts at character pos 4 line --1 = 8 - 8 + 3 // More left indented comment */ --2 = 8 - 8 + 2 // class c { } // } // module m { // /* this is line 1 -- Assume current writer indent 8 // * line --3 = 8 - 4 + 5 // More right indented comment */ --4 = 8 - 4 + 11 // class c { } // } var spacesToEmit = currentWriterIndentSpacing - firstCommentLineIndent + calculateIndent(text, pos, nextLineStart); if (spacesToEmit > 0) { var numberOfSingleSpacesToEmit = spacesToEmit % getIndentSize(); var indentSizeSpaceString = getIndentString((spacesToEmit - numberOfSingleSpacesToEmit) / getIndentSize()); // Write indent size string ( in eg 1: = "", 2: "" , 3: string with 8 spaces 4: string with 12 spaces writer.rawWrite(indentSizeSpaceString); // Emit the single spaces (in eg: 1: 3 spaces, 2: 2 spaces, 3: 1 space, 4: 3 spaces) while (numberOfSingleSpacesToEmit) { writer.rawWrite(" "); numberOfSingleSpacesToEmit--; } } else { // No spaces to emit write empty string writer.rawWrite(""); } } // Write the comment line text writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart); pos = nextLineStart; } } else { // Single line comment of style //.... writer.write(text.substring(commentPos, commentEnd)); } } ts.writeCommentRange = writeCommentRange; function writeTrimmedCurrentLine(text, commentEnd, writer, newLine, pos, nextLineStart) { var end = Math.min(commentEnd, nextLineStart - 1); var currentLineText = text.substring(pos, end).replace(/^\s+|\s+$/g, ""); if (currentLineText) { // trimmed forward and ending spaces text writer.write(currentLineText); if (end !== commentEnd) { writer.writeLine(); } } else { // Empty string - make sure we write empty line writer.writeLiteral(newLine); } } function calculateIndent(text, pos, end) { var currentLineIndent = 0; for (; pos < end && ts.isWhiteSpaceSingleLine(text.charCodeAt(pos)); pos++) { if (text.charCodeAt(pos) === 9 /* tab */) { // Tabs = TabSize = indent size and go to next tabStop currentLineIndent += getIndentSize() - (currentLineIndent % getIndentSize()); } else { // Single space currentLineIndent++; } } return currentLineIndent; } function hasModifiers(node) { return getModifierFlags(node) !== 0 /* None */; } ts.hasModifiers = hasModifiers; function hasModifier(node, flags) { return !!getSelectedModifierFlags(node, flags); } ts.hasModifier = hasModifier; function hasStaticModifier(node) { return hasModifier(node, 32 /* Static */); } ts.hasStaticModifier = hasStaticModifier; function hasReadonlyModifier(node) { return hasModifier(node, 64 /* Readonly */); } ts.hasReadonlyModifier = hasReadonlyModifier; function getSelectedModifierFlags(node, flags) { return getModifierFlags(node) & flags; } ts.getSelectedModifierFlags = getSelectedModifierFlags; function getModifierFlags(node) { if (node.modifierFlagsCache & 536870912 /* HasComputedFlags */) { return node.modifierFlagsCache & ~536870912 /* HasComputedFlags */; } var flags = getModifierFlagsNoCache(node); node.modifierFlagsCache = flags | 536870912 /* HasComputedFlags */; return flags; } ts.getModifierFlags = getModifierFlags; function getModifierFlagsNoCache(node) { var flags = 0 /* None */; if (node.modifiers) { for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) { var modifier = _a[_i]; flags |= modifierToFlag(modifier.kind); } } if (node.flags & 4 /* NestedNamespace */ || (node.kind === 71 /* Identifier */ && node.isInJSDocNamespace)) { flags |= 1 /* Export */; } return flags; } ts.getModifierFlagsNoCache = getModifierFlagsNoCache; function modifierToFlag(token) { switch (token) { case 115 /* StaticKeyword */: return 32 /* Static */; case 114 /* PublicKeyword */: return 4 /* Public */; case 113 /* ProtectedKeyword */: return 16 /* Protected */; case 112 /* PrivateKeyword */: return 8 /* Private */; case 117 /* AbstractKeyword */: return 128 /* Abstract */; case 84 /* ExportKeyword */: return 1 /* Export */; case 124 /* DeclareKeyword */: return 2 /* Ambient */; case 76 /* ConstKeyword */: return 2048 /* Const */; case 79 /* DefaultKeyword */: return 512 /* Default */; case 120 /* AsyncKeyword */: return 256 /* Async */; case 131 /* ReadonlyKeyword */: return 64 /* Readonly */; } return 0 /* None */; } ts.modifierToFlag = modifierToFlag; function isLogicalOperator(token) { return token === 54 /* BarBarToken */ || token === 53 /* AmpersandAmpersandToken */ || token === 51 /* ExclamationToken */; } ts.isLogicalOperator = isLogicalOperator; function isAssignmentOperator(token) { return token >= 58 /* FirstAssignment */ && token <= 70 /* LastAssignment */; } ts.isAssignmentOperator = isAssignmentOperator; /** Get `C` given `N` if `N` is in the position `class C extends N` where `N` is an ExpressionWithTypeArguments. */ function tryGetClassExtendingExpressionWithTypeArguments(node) { if (node.kind === 202 /* ExpressionWithTypeArguments */ && node.parent.token === 85 /* ExtendsKeyword */ && ts.isClassLike(node.parent.parent)) { return node.parent.parent; } } ts.tryGetClassExtendingExpressionWithTypeArguments = tryGetClassExtendingExpressionWithTypeArguments; function isAssignmentExpression(node, excludeCompoundAssignment) { return ts.isBinaryExpression(node) && (excludeCompoundAssignment ? node.operatorToken.kind === 58 /* EqualsToken */ : isAssignmentOperator(node.operatorToken.kind)) && ts.isLeftHandSideExpression(node.left); } ts.isAssignmentExpression = isAssignmentExpression; function isDestructuringAssignment(node) { if (isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) { var kind = node.left.kind; return kind === 179 /* ObjectLiteralExpression */ || kind === 178 /* ArrayLiteralExpression */; } return false; } ts.isDestructuringAssignment = isDestructuringAssignment; function isExpressionWithTypeArgumentsInClassExtendsClause(node) { return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined; } ts.isExpressionWithTypeArgumentsInClassExtendsClause = isExpressionWithTypeArgumentsInClassExtendsClause; function isExpressionWithTypeArgumentsInClassImplementsClause(node) { return node.kind === 202 /* ExpressionWithTypeArguments */ && isEntityNameExpression(node.expression) && node.parent && node.parent.token === 108 /* ImplementsKeyword */ && node.parent.parent && ts.isClassLike(node.parent.parent); } ts.isExpressionWithTypeArgumentsInClassImplementsClause = isExpressionWithTypeArgumentsInClassImplementsClause; function isEntityNameExpression(node) { return node.kind === 71 /* Identifier */ || node.kind === 180 /* PropertyAccessExpression */ && isEntityNameExpression(node.expression); } ts.isEntityNameExpression = isEntityNameExpression; function isRightSideOfQualifiedNameOrPropertyAccess(node) { return (node.parent.kind === 144 /* QualifiedName */ && node.parent.right === node) || (node.parent.kind === 180 /* PropertyAccessExpression */ && node.parent.name === node); } ts.isRightSideOfQualifiedNameOrPropertyAccess = isRightSideOfQualifiedNameOrPropertyAccess; function isEmptyObjectLiteral(expression) { return expression.kind === 179 /* ObjectLiteralExpression */ && expression.properties.length === 0; } ts.isEmptyObjectLiteral = isEmptyObjectLiteral; function isEmptyArrayLiteral(expression) { return expression.kind === 178 /* ArrayLiteralExpression */ && expression.elements.length === 0; } ts.isEmptyArrayLiteral = isEmptyArrayLiteral; function getLocalSymbolForExportDefault(symbol) { return isExportDefaultSymbol(symbol) ? symbol.declarations[0].localSymbol : undefined; } ts.getLocalSymbolForExportDefault = getLocalSymbolForExportDefault; function isExportDefaultSymbol(symbol) { return symbol && ts.length(symbol.declarations) > 0 && hasModifier(symbol.declarations[0], 512 /* Default */); } /** Return ".ts", ".d.ts", or ".tsx", if that is the extension. */ function tryExtractTypeScriptExtension(fileName) { return ts.find(ts.supportedTypescriptExtensionsForExtractExtension, function (extension) { return ts.fileExtensionIs(fileName, extension); }); } ts.tryExtractTypeScriptExtension = tryExtractTypeScriptExtension; /** * Replace each instance of non-ascii characters by one, two, three, or four escape sequences * representing the UTF-8 encoding of the character, and return the expanded char code list. */ function getExpandedCharCodes(input) { var output = []; var length = input.length; for (var i = 0; i < length; i++) { var charCode = input.charCodeAt(i); // handel utf8 if (charCode < 0x80) { output.push(charCode); } else if (charCode < 0x800) { output.push((charCode >> 6) | 192); output.push((charCode & 63) | 128); } else if (charCode < 0x10000) { output.push((charCode >> 12) | 224); output.push(((charCode >> 6) & 63) | 128); output.push((charCode & 63) | 128); } else if (charCode < 0x20000) { output.push((charCode >> 18) | 240); output.push(((charCode >> 12) & 63) | 128); output.push(((charCode >> 6) & 63) | 128); output.push((charCode & 63) | 128); } else { ts.Debug.assert(false, "Unexpected code point"); } } return output; } var base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; /** * Converts a string to a base-64 encoded ASCII string. */ function convertToBase64(input) { var result = ""; var charCodes = getExpandedCharCodes(input); var i = 0; var length = charCodes.length; var byte1, byte2, byte3, byte4; while (i < length) { // Convert every 6-bits in the input 3 character points // into a base64 digit byte1 = charCodes[i] >> 2; byte2 = (charCodes[i] & 3) << 4 | charCodes[i + 1] >> 4; byte3 = (charCodes[i + 1] & 15) << 2 | charCodes[i + 2] >> 6; byte4 = charCodes[i + 2] & 63; // We are out of characters in the input, set the extra // digits to 64 (padding character). if (i + 1 >= length) { byte3 = byte4 = 64; } else if (i + 2 >= length) { byte4 = 64; } // Write to the output result += base64Digits.charAt(byte1) + base64Digits.charAt(byte2) + base64Digits.charAt(byte3) + base64Digits.charAt(byte4); i += 3; } return result; } ts.convertToBase64 = convertToBase64; var carriageReturnLineFeed = "\r\n"; var lineFeed = "\n"; function getNewLineCharacter(options, system) { switch (options.newLine) { case 0 /* CarriageReturnLineFeed */: return carriageReturnLineFeed; case 1 /* LineFeed */: return lineFeed; } return system ? system.newLine : ts.sys ? ts.sys.newLine : carriageReturnLineFeed; } ts.getNewLineCharacter = getNewLineCharacter; /** * Formats an enum value as a string for debugging and debug assertions. */ function formatEnum(value, enumObject, isFlags) { if (value === void 0) { value = 0; } var members = getEnumMembers(enumObject); if (value === 0) { return members.length > 0 && members[0][0] === 0 ? members[0][1] : "0"; } if (isFlags) { var result = ""; var remainingFlags = value; for (var i = members.length - 1; i >= 0 && remainingFlags !== 0; i--) { var _a = members[i], enumValue = _a[0], enumName = _a[1]; if (enumValue !== 0 && (remainingFlags & enumValue) === enumValue) { remainingFlags &= ~enumValue; result = "" + enumName + (result ? ", " : "") + result; } } if (remainingFlags === 0) { return result; } } else { for (var _i = 0, members_1 = members; _i < members_1.length; _i++) { var _b = members_1[_i], enumValue = _b[0], enumName = _b[1]; if (enumValue === value) { return enumName; } } } return value.toString(); } function getEnumMembers(enumObject) { var result = []; for (var name in enumObject) { var value = enumObject[name]; if (typeof value === "number") { result.push([value, name]); } } return ts.stableSort(result, function (x, y) { return ts.compareValues(x[0], y[0]); }); } function formatSyntaxKind(kind) { return formatEnum(kind, ts.SyntaxKind, /*isFlags*/ false); } ts.formatSyntaxKind = formatSyntaxKind; function formatModifierFlags(flags) { return formatEnum(flags, ts.ModifierFlags, /*isFlags*/ true); } ts.formatModifierFlags = formatModifierFlags; function formatTransformFlags(flags) { return formatEnum(flags, ts.TransformFlags, /*isFlags*/ true); } ts.formatTransformFlags = formatTransformFlags; function formatEmitFlags(flags) { return formatEnum(flags, ts.EmitFlags, /*isFlags*/ true); } ts.formatEmitFlags = formatEmitFlags; function formatSymbolFlags(flags) { return formatEnum(flags, ts.SymbolFlags, /*isFlags*/ true); } ts.formatSymbolFlags = formatSymbolFlags; function formatTypeFlags(flags) { return formatEnum(flags, ts.TypeFlags, /*isFlags*/ true); } ts.formatTypeFlags = formatTypeFlags; function formatObjectFlags(flags) { return formatEnum(flags, ts.ObjectFlags, /*isFlags*/ true); } ts.formatObjectFlags = formatObjectFlags; /** * Creates a new TextRange from the provided pos and end. * * @param pos The start position. * @param end The end position. */ function createRange(pos, end) { return { pos: pos, end: end }; } ts.createRange = createRange; /** * Creates a new TextRange from a provided range with a new end position. * * @param range A TextRange. * @param end The new end position. */ function moveRangeEnd(range, end) { return createRange(range.pos, end); } ts.moveRangeEnd = moveRangeEnd; /** * Creates a new TextRange from a provided range with a new start position. * * @param range A TextRange. * @param pos The new Start position. */ function moveRangePos(range, pos) { return createRange(pos, range.end); } ts.moveRangePos = moveRangePos; /** * Moves the start position of a range past any decorators. */ function moveRangePastDecorators(node) { return node.decorators && node.decorators.length > 0 ? moveRangePos(node, node.decorators.end) : node; } ts.moveRangePastDecorators = moveRangePastDecorators; /** * Moves the start position of a range past any decorators or modifiers. */ function moveRangePastModifiers(node) { return node.modifiers && node.modifiers.length > 0 ? moveRangePos(node, node.modifiers.end) : moveRangePastDecorators(node); } ts.moveRangePastModifiers = moveRangePastModifiers; /** * Determines whether a TextRange has the same start and end positions. * * @param range A TextRange. */ function isCollapsedRange(range) { return range.pos === range.end; } ts.isCollapsedRange = isCollapsedRange; /** * Creates a new TextRange for a token at the provides start position. * * @param pos The start position. * @param token The token. */ function createTokenRange(pos, token) { return createRange(pos, pos + ts.tokenToString(token).length); } ts.createTokenRange = createTokenRange; function rangeIsOnSingleLine(range, sourceFile) { return rangeStartIsOnSameLineAsRangeEnd(range, range, sourceFile); } ts.rangeIsOnSingleLine = rangeIsOnSingleLine; function rangeStartPositionsAreOnSameLine(range1, range2, sourceFile) { return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), getStartPositionOfRange(range2, sourceFile), sourceFile); } ts.rangeStartPositionsAreOnSameLine = rangeStartPositionsAreOnSameLine; function rangeEndPositionsAreOnSameLine(range1, range2, sourceFile) { return positionsAreOnSameLine(range1.end, range2.end, sourceFile); } ts.rangeEndPositionsAreOnSameLine = rangeEndPositionsAreOnSameLine; function rangeStartIsOnSameLineAsRangeEnd(range1, range2, sourceFile) { return positionsAreOnSameLine(getStartPositionOfRange(range1, sourceFile), range2.end, sourceFile); } ts.rangeStartIsOnSameLineAsRangeEnd = rangeStartIsOnSameLineAsRangeEnd; function rangeEndIsOnSameLineAsRangeStart(range1, range2, sourceFile) { return positionsAreOnSameLine(range1.end, getStartPositionOfRange(range2, sourceFile), sourceFile); } ts.rangeEndIsOnSameLineAsRangeStart = rangeEndIsOnSameLineAsRangeStart; function positionsAreOnSameLine(pos1, pos2, sourceFile) { return pos1 === pos2 || getLineOfLocalPosition(sourceFile, pos1) === getLineOfLocalPosition(sourceFile, pos2); } ts.positionsAreOnSameLine = positionsAreOnSameLine; function getStartPositionOfRange(range, sourceFile) { return ts.positionIsSynthesized(range.pos) ? -1 : ts.skipTrivia(sourceFile.text, range.pos); } ts.getStartPositionOfRange = getStartPositionOfRange; /** * Determines whether a name was originally the declaration name of an enum or namespace * declaration. */ function isDeclarationNameOfEnumOrNamespace(node) { var parseNode = ts.getParseTreeNode(node); if (parseNode) { switch (parseNode.parent.kind) { case 233 /* EnumDeclaration */: case 234 /* ModuleDeclaration */: return parseNode === parseNode.parent.name; } } return false; } ts.isDeclarationNameOfEnumOrNamespace = isDeclarationNameOfEnumOrNamespace; function getInitializedVariables(node) { return ts.filter(node.declarations, isInitializedVariable); } ts.getInitializedVariables = getInitializedVariables; function isInitializedVariable(node) { return node.initializer !== undefined; } function isWatchSet(options) { // Firefox has Object.prototype.watch return options.watch && options.hasOwnProperty("watch"); } ts.isWatchSet = isWatchSet; function getCheckFlags(symbol) { return symbol.flags & 33554432 /* Transient */ ? symbol.checkFlags : 0; } ts.getCheckFlags = getCheckFlags; function getDeclarationModifierFlagsFromSymbol(s) { if (s.valueDeclaration) { var flags = ts.getCombinedModifierFlags(s.valueDeclaration); return s.parent && s.parent.flags & 32 /* Class */ ? flags : flags & ~28 /* AccessibilityModifier */; } if (getCheckFlags(s) & 6 /* Synthetic */) { var checkFlags = s.checkFlags; var accessModifier = checkFlags & 256 /* ContainsPrivate */ ? 8 /* Private */ : checkFlags & 64 /* ContainsPublic */ ? 4 /* Public */ : 16 /* Protected */; var staticModifier = checkFlags & 512 /* ContainsStatic */ ? 32 /* Static */ : 0; return accessModifier | staticModifier; } if (s.flags & 4194304 /* Prototype */) { return 4 /* Public */ | 32 /* Static */; } return 0; } ts.getDeclarationModifierFlagsFromSymbol = getDeclarationModifierFlagsFromSymbol; function skipAlias(symbol, checker) { return symbol.flags & 2097152 /* Alias */ ? checker.getAliasedSymbol(symbol) : symbol; } ts.skipAlias = skipAlias; /** See comment on `declareModuleMember` in `binder.ts`. */ function getCombinedLocalAndExportSymbolFlags(symbol) { return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags; } ts.getCombinedLocalAndExportSymbolFlags = getCombinedLocalAndExportSymbolFlags; function isWriteOnlyAccess(node) { return accessKind(node) === 1 /* Write */; } ts.isWriteOnlyAccess = isWriteOnlyAccess; function isWriteAccess(node) { return accessKind(node) !== 0 /* Read */; } ts.isWriteAccess = isWriteAccess; var AccessKind; (function (AccessKind) { /** Only reads from a variable. */ AccessKind[AccessKind["Read"] = 0] = "Read"; /** Only writes to a variable without using the result. E.g.: `x++;`. */ AccessKind[AccessKind["Write"] = 1] = "Write"; /** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */ AccessKind[AccessKind["ReadWrite"] = 2] = "ReadWrite"; })(AccessKind || (AccessKind = {})); function accessKind(node) { var parent = node.parent; if (!parent) return 0 /* Read */; switch (parent.kind) { case 194 /* PostfixUnaryExpression */: case 193 /* PrefixUnaryExpression */: var operator = parent.operator; return operator === 43 /* PlusPlusToken */ || operator === 44 /* MinusMinusToken */ ? writeOrReadWrite() : 0 /* Read */; case 195 /* BinaryExpression */: var _a = parent, left = _a.left, operatorToken = _a.operatorToken; return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : 0 /* Read */; case 180 /* PropertyAccessExpression */: return parent.name !== node ? 0 /* Read */ : accessKind(parent); default: return 0 /* Read */; } function writeOrReadWrite() { // If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect. return parent.parent && parent.parent.kind === 211 /* ExpressionStatement */ ? 1 /* Write */ : 2 /* ReadWrite */; } } function compareDataObjects(dst, src) { if (!dst || !src || Object.keys(dst).length !== Object.keys(src).length) { return false; } for (var e in dst) { if (typeof dst[e] === "object") { if (!compareDataObjects(dst[e], src[e])) { return false; } } else if (typeof dst[e] !== "function") { if (dst[e] !== src[e]) { return false; } } } return true; } ts.compareDataObjects = compareDataObjects; /** * clears already present map by calling onDeleteExistingValue callback before deleting that key/value */ function clearMap(map, onDeleteValue) { // Remove all map.forEach(onDeleteValue); map.clear(); } ts.clearMap = clearMap; /** * Mutates the map with newMap such that keys in map will be same as newMap. */ function mutateMap(map, newMap, options) { var createNewValue = options.createNewValue, onDeleteValue = options.onDeleteValue, onExistingValue = options.onExistingValue; // Needs update map.forEach(function (existingValue, key) { var valueInNewMap = newMap.get(key); // Not present any more in new map, remove it if (valueInNewMap === undefined) { map.delete(key); onDeleteValue(existingValue, key); } else if (onExistingValue) { onExistingValue(existingValue, valueInNewMap, key); } }); // Add new values that are not already present newMap.forEach(function (valueInNewMap, key) { if (!map.has(key)) { // New values map.set(key, createNewValue(key, valueInNewMap)); } }); } ts.mutateMap = mutateMap; /** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */ function forEachAncestorDirectory(directory, callback) { while (true) { var result = callback(directory); if (result !== undefined) { return result; } var parentPath = ts.getDirectoryPath(directory); if (parentPath === directory) { return undefined; } directory = parentPath; } } ts.forEachAncestorDirectory = forEachAncestorDirectory; // Return true if the given type is the constructor type for an abstract class function isAbstractConstructorType(type) { return !!(getObjectFlags(type) & 16 /* Anonymous */) && !!type.symbol && isAbstractConstructorSymbol(type.symbol); } ts.isAbstractConstructorType = isAbstractConstructorType; function isAbstractConstructorSymbol(symbol) { if (symbol.flags & 32 /* Class */) { var declaration = getClassLikeDeclarationOfSymbol(symbol); return !!declaration && hasModifier(declaration, 128 /* Abstract */); } return false; } ts.isAbstractConstructorSymbol = isAbstractConstructorSymbol; function getClassLikeDeclarationOfSymbol(symbol) { return ts.find(symbol.declarations, ts.isClassLike); } ts.getClassLikeDeclarationOfSymbol = getClassLikeDeclarationOfSymbol; function getObjectFlags(type) { return type.flags & 65536 /* Object */ ? type.objectFlags : 0; } ts.getObjectFlags = getObjectFlags; function typeHasCallOrConstructSignatures(type, checker) { return checker.getSignaturesOfType(type, 0 /* Call */).length !== 0 || checker.getSignaturesOfType(type, 1 /* Construct */).length !== 0; } ts.typeHasCallOrConstructSignatures = typeHasCallOrConstructSignatures; })(ts || (ts = {})); (function (ts) { function getDefaultLibFileName(options) { switch (options.target) { case 6 /* ESNext */: return "lib.esnext.full.d.ts"; case 4 /* ES2017 */: return "lib.es2017.full.d.ts"; case 3 /* ES2016 */: return "lib.es2016.full.d.ts"; case 2 /* ES2015 */: return "lib.es6.d.ts"; // We don't use lib.es2015.full.d.ts due to breaking change. default: return "lib.d.ts"; } } ts.getDefaultLibFileName = getDefaultLibFileName; function textSpanEnd(span) { return span.start + span.length; } ts.textSpanEnd = textSpanEnd; function textSpanIsEmpty(span) { return span.length === 0; } ts.textSpanIsEmpty = textSpanIsEmpty; function textSpanContainsPosition(span, position) { return position >= span.start && position < textSpanEnd(span); } ts.textSpanContainsPosition = textSpanContainsPosition; // Returns true if 'span' contains 'other'. function textSpanContainsTextSpan(span, other) { return other.start >= span.start && textSpanEnd(other) <= textSpanEnd(span); } ts.textSpanContainsTextSpan = textSpanContainsTextSpan; function textSpanOverlapsWith(span, other) { var overlapStart = Math.max(span.start, other.start); var overlapEnd = Math.min(textSpanEnd(span), textSpanEnd(other)); return overlapStart < overlapEnd; } ts.textSpanOverlapsWith = textSpanOverlapsWith; function textSpanOverlap(span1, span2) { var overlapStart = Math.max(span1.start, span2.start); var overlapEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2)); if (overlapStart < overlapEnd) { return createTextSpanFromBounds(overlapStart, overlapEnd); } return undefined; } ts.textSpanOverlap = textSpanOverlap; function textSpanIntersectsWithTextSpan(span, other) { return other.start <= textSpanEnd(span) && textSpanEnd(other) >= span.start; } ts.textSpanIntersectsWithTextSpan = textSpanIntersectsWithTextSpan; function textSpanIntersectsWith(span, start, length) { var end = start + length; return start <= textSpanEnd(span) && end >= span.start; } ts.textSpanIntersectsWith = textSpanIntersectsWith; function decodedTextSpanIntersectsWith(start1, length1, start2, length2) { var end1 = start1 + length1; var end2 = start2 + length2; return start2 <= end1 && end2 >= start1; } ts.decodedTextSpanIntersectsWith = decodedTextSpanIntersectsWith; function textSpanIntersectsWithPosition(span, position) { return position <= textSpanEnd(span) && position >= span.start; } ts.textSpanIntersectsWithPosition = textSpanIntersectsWithPosition; function textSpanIntersection(span1, span2) { var intersectStart = Math.max(span1.start, span2.start); var intersectEnd = Math.min(textSpanEnd(span1), textSpanEnd(span2)); if (intersectStart <= intersectEnd) { return createTextSpanFromBounds(intersectStart, intersectEnd); } return undefined; } ts.textSpanIntersection = textSpanIntersection; function createTextSpan(start, length) { if (start < 0) { throw new Error("start < 0"); } if (length < 0) { throw new Error("length < 0"); } return { start: start, length: length }; } ts.createTextSpan = createTextSpan; function createTextSpanFromBounds(start, end) { return createTextSpan(start, end - start); } ts.createTextSpanFromBounds = createTextSpanFromBounds; function textChangeRangeNewSpan(range) { return createTextSpan(range.span.start, range.newLength); } ts.textChangeRangeNewSpan = textChangeRangeNewSpan; function textChangeRangeIsUnchanged(range) { return textSpanIsEmpty(range.span) && range.newLength === 0; } ts.textChangeRangeIsUnchanged = textChangeRangeIsUnchanged; function createTextChangeRange(span, newLength) { if (newLength < 0) { throw new Error("newLength < 0"); } return { span: span, newLength: newLength }; } ts.createTextChangeRange = createTextChangeRange; ts.unchangedTextChangeRange = createTextChangeRange(createTextSpan(0, 0), 0); /** * Called to merge all the changes that occurred across several versions of a script snapshot * into a single change. i.e. if a user keeps making successive edits to a script we will * have a text change from V1 to V2, V2 to V3, ..., Vn. * * This function will then merge those changes into a single change range valid between V1 and * Vn. */ function collapseTextChangeRangesAcrossMultipleVersions(changes) { if (changes.length === 0) { return ts.unchangedTextChangeRange; } if (changes.length === 1) { return changes[0]; } // We change from talking about { { oldStart, oldLength }, newLength } to { oldStart, oldEnd, newEnd } // as it makes things much easier to reason about. var change0 = changes[0]; var oldStartN = change0.span.start; var oldEndN = textSpanEnd(change0.span); var newEndN = oldStartN + change0.newLength; for (var i = 1; i < changes.length; i++) { var nextChange = changes[i]; // Consider the following case: // i.e. two edits. The first represents the text change range { { 10, 50 }, 30 }. i.e. The span starting // at 10, with length 50 is reduced to length 30. The second represents the text change range { { 30, 30 }, 40 }. // i.e. the span starting at 30 with length 30 is increased to length 40. // // 0 10 20 30 40 50 60 70 80 90 100 // ------------------------------------------------------------------------------------------------------- // | / // | /---- // T1 | /---- // | /---- // | /---- // ------------------------------------------------------------------------------------------------------- // | \ // | \ // T2 | \ // | \ // | \ // ------------------------------------------------------------------------------------------------------- // // Merging these turns out to not be too difficult. First, determining the new start of the change is trivial // it's just the min of the old and new starts. i.e.: // // 0 10 20 30 40 50 60 70 80 90 100 // ------------------------------------------------------------*------------------------------------------ // | / // | /---- // T1 | /---- // | /---- // | /---- // ----------------------------------------$-------------------$------------------------------------------ // . | \ // . | \ // T2 . | \ // . | \ // . | \ // ----------------------------------------------------------------------*-------------------------------- // // (Note the dots represent the newly inferred start. // Determining the new and old end is also pretty simple. Basically it boils down to paying attention to the // absolute positions at the asterisks, and the relative change between the dollar signs. Basically, we see // which if the two $'s precedes the other, and we move that one forward until they line up. in this case that // means: // // 0 10 20 30 40 50 60 70 80 90 100 // --------------------------------------------------------------------------------*---------------------- // | / // | /---- // T1 | /---- // | /---- // | /---- // ------------------------------------------------------------$------------------------------------------ // . | \ // . | \ // T2 . | \ // . | \ // . | \ // ----------------------------------------------------------------------*-------------------------------- // // In other words (in this case), we're recognizing that the second edit happened after where the first edit // ended with a delta of 20 characters (60 - 40). Thus, if we go back in time to where the first edit started // that's the same as if we started at char 80 instead of 60. // // As it so happens, the same logic applies if the second edit precedes the first edit. In that case rather // than pushing the first edit forward to match the second, we'll push the second edit forward to match the // first. // // In this case that means we have { oldStart: 10, oldEnd: 80, newEnd: 70 } or, in TextChangeRange // semantics: { { start: 10, length: 70 }, newLength: 60 } // // The math then works out as follows. // If we have { oldStart1, oldEnd1, newEnd1 } and { oldStart2, oldEnd2, newEnd2 } then we can compute the // final result like so: // // { // oldStart3: Min(oldStart1, oldStart2), // oldEnd3 : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)), // newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)) // } var oldStart1 = oldStartN; var oldEnd1 = oldEndN; var newEnd1 = newEndN; var oldStart2 = nextChange.span.start; var oldEnd2 = textSpanEnd(nextChange.span); var newEnd2 = oldStart2 + nextChange.newLength; oldStartN = Math.min(oldStart1, oldStart2); oldEndN = Math.max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)); newEndN = Math.max(newEnd2, newEnd2 + (newEnd1 - oldEnd2)); } return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength*/ newEndN - oldStartN); } ts.collapseTextChangeRangesAcrossMultipleVersions = collapseTextChangeRangesAcrossMultipleVersions; function getTypeParameterOwner(d) { if (d && d.kind === 146 /* TypeParameter */) { for (var current = d; current; current = current.parent) { if (ts.isFunctionLike(current) || ts.isClassLike(current) || current.kind === 231 /* InterfaceDeclaration */) { return current; } } } } ts.getTypeParameterOwner = getTypeParameterOwner; function isParameterPropertyDeclaration(node) { return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) && node.parent.kind === 153 /* Constructor */ && ts.isClassLike(node.parent.parent); } ts.isParameterPropertyDeclaration = isParameterPropertyDeclaration; function isEmptyBindingPattern(node) { if (ts.isBindingPattern(node)) { return ts.every(node.elements, isEmptyBindingElement); } return false; } ts.isEmptyBindingPattern = isEmptyBindingPattern; function isEmptyBindingElement(node) { if (ts.isOmittedExpression(node)) { return true; } return isEmptyBindingPattern(node.name); } ts.isEmptyBindingElement = isEmptyBindingElement; function walkUpBindingElementsAndPatterns(node) { while (node && (node.kind === 177 /* BindingElement */ || ts.isBindingPattern(node))) { node = node.parent; } return node; } function getCombinedModifierFlags(node) { node = walkUpBindingElementsAndPatterns(node); var flags = ts.getModifierFlags(node); if (node.kind === 227 /* VariableDeclaration */) { node = node.parent; } if (node && node.kind === 228 /* VariableDeclarationList */) { flags |= ts.getModifierFlags(node); node = node.parent; } if (node && node.kind === 209 /* VariableStatement */) { flags |= ts.getModifierFlags(node); } return flags; } ts.getCombinedModifierFlags = getCombinedModifierFlags; // Returns the node flags for this node and all relevant parent nodes. This is done so that // nodes like variable declarations and binding elements can returned a view of their flags // that includes the modifiers from their container. i.e. flags like export/declare aren't // stored on the variable declaration directly, but on the containing variable statement // (if it has one). Similarly, flags for let/const are store on the variable declaration // list. By calling this function, all those flags are combined so that the client can treat // the node as if it actually had those flags. function getCombinedNodeFlags(node) { node = walkUpBindingElementsAndPatterns(node); var flags = node.flags; if (node.kind === 227 /* VariableDeclaration */) { node = node.parent; } if (node && node.kind === 228 /* VariableDeclarationList */) { flags |= node.flags; node = node.parent; } if (node && node.kind === 209 /* VariableStatement */) { flags |= node.flags; } return flags; } ts.getCombinedNodeFlags = getCombinedNodeFlags; /** * Checks to see if the locale is in the appropriate format, * and if it is, attempts to set the appropriate language. */ function validateLocaleAndSetLanguage(locale, sys, errors) { var matchResult = /^([a-z]+)([_\-]([a-z]+))?$/.exec(locale.toLowerCase()); if (!matchResult) { if (errors) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Locale_must_be_of_the_form_language_or_language_territory_For_example_0_or_1, "en", "ja-jp")); } return; } var language = matchResult[1]; var territory = matchResult[3]; // First try the entire locale, then fall back to just language if that's all we have. // Either ways do not fail, and fallback to the English diagnostic strings. if (!trySetLanguageAndTerritory(language, territory, errors)) { trySetLanguageAndTerritory(language, /*territory*/ undefined, errors); } // Set the UI locale for string collation ts.setUILocale(locale); function trySetLanguageAndTerritory(language, territory, errors) { var compilerFilePath = ts.normalizePath(sys.getExecutingFilePath()); var containingDirectoryPath = ts.getDirectoryPath(compilerFilePath); var filePath = ts.combinePaths(containingDirectoryPath, language); if (territory) { filePath = filePath + "-" + territory; } filePath = sys.resolvePath(ts.combinePaths(filePath, "diagnosticMessages.generated.json")); if (!sys.fileExists(filePath)) { return false; } // TODO: Add codePage support for readFile? var fileContents = ""; try { fileContents = sys.readFile(filePath); } catch (e) { if (errors) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unable_to_open_file_0, filePath)); } return false; } try { ts.localizedDiagnosticMessages = JSON.parse(fileContents); } catch (e) { if (errors) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Corrupted_locale_file_0, filePath)); } return false; } return true; } } ts.validateLocaleAndSetLanguage = validateLocaleAndSetLanguage; function getOriginalNode(node, nodeTest) { if (node) { while (node.original !== undefined) { node = node.original; } } return !nodeTest || nodeTest(node) ? node : undefined; } ts.getOriginalNode = getOriginalNode; /** * Gets a value indicating whether a node originated in the parse tree. * * @param node The node to test. */ function isParseTreeNode(node) { return (node.flags & 8 /* Synthesized */) === 0; } ts.isParseTreeNode = isParseTreeNode; function getParseTreeNode(node, nodeTest) { if (node === undefined || isParseTreeNode(node)) { return node; } node = getOriginalNode(node); if (isParseTreeNode(node) && (!nodeTest || nodeTest(node))) { return node; } return undefined; } ts.getParseTreeNode = getParseTreeNode; /** * Remove extra underscore from escaped identifier text content. * * @param identifier The escaped identifier text. * @returns The unescaped identifier text. */ function unescapeLeadingUnderscores(identifier) { var id = identifier; return id.length >= 3 && id.charCodeAt(0) === 95 /* _ */ && id.charCodeAt(1) === 95 /* _ */ && id.charCodeAt(2) === 95 /* _ */ ? id.substr(1) : id; } ts.unescapeLeadingUnderscores = unescapeLeadingUnderscores; function idText(identifier) { return unescapeLeadingUnderscores(identifier.escapedText); } ts.idText = idText; function symbolName(symbol) { return unescapeLeadingUnderscores(symbol.escapedName); } ts.symbolName = symbolName; /** * Remove extra underscore from escaped identifier text content. * @deprecated Use `id.text` for the unescaped text. * @param identifier The escaped identifier text. * @returns The unescaped identifier text. */ function unescapeIdentifier(id) { return id; } ts.unescapeIdentifier = unescapeIdentifier; /** * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol * will be merged with) */ function nameForNamelessJSDocTypedef(declaration) { var hostNode = declaration.parent.parent; if (!hostNode) { return undefined; } // Covers classes, functions - any named declaration host node if (ts.isDeclaration(hostNode)) { return getDeclarationIdentifier(hostNode); } // Covers remaining cases switch (hostNode.kind) { case 209 /* VariableStatement */: if (hostNode.declarationList && hostNode.declarationList.declarations[0]) { return getDeclarationIdentifier(hostNode.declarationList.declarations[0]); } return undefined; case 211 /* ExpressionStatement */: var expr = hostNode.expression; switch (expr.kind) { case 180 /* PropertyAccessExpression */: return expr.name; case 181 /* ElementAccessExpression */: var arg = expr.argumentExpression; if (ts.isIdentifier(arg)) { return arg; } } return undefined; case 1 /* EndOfFileToken */: return undefined; case 186 /* ParenthesizedExpression */: { return getDeclarationIdentifier(hostNode.expression); } case 223 /* LabeledStatement */: { if (ts.isDeclaration(hostNode.statement) || ts.isExpression(hostNode.statement)) { return getDeclarationIdentifier(hostNode.statement); } return undefined; } default: ts.Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!"); } } function getDeclarationIdentifier(node) { var name = getNameOfDeclaration(node); return ts.isIdentifier(name) ? name : undefined; } function getNameOfJSDocTypedef(declaration) { return declaration.name || nameForNamelessJSDocTypedef(declaration); } ts.getNameOfJSDocTypedef = getNameOfJSDocTypedef; function getNameOfDeclaration(declaration) { if (!declaration) { return undefined; } switch (declaration.kind) { case 71 /* Identifier */: return declaration; case 289 /* JSDocPropertyTag */: case 284 /* JSDocParameterTag */: { var name = declaration.name; if (name.kind === 144 /* QualifiedName */) { return name.right; } break; } case 195 /* BinaryExpression */: { var expr = declaration; switch (ts.getSpecialPropertyAssignmentKind(expr)) { case 1 /* ExportsProperty */: case 4 /* ThisProperty */: case 5 /* Property */: case 3 /* PrototypeProperty */: return expr.left.name; default: return undefined; } } case 288 /* JSDocTypedefTag */: return getNameOfJSDocTypedef(declaration); case 244 /* ExportAssignment */: { var expression = declaration.expression; return ts.isIdentifier(expression) ? expression : undefined; } } return declaration.name; } ts.getNameOfDeclaration = getNameOfDeclaration; /** * Gets the JSDoc parameter tags for the node if present. * * @remarks Returns any JSDoc param tag that matches the provided * parameter, whether a param tag on a containing function * expression, or a param tag on a variable declaration whose * initializer is the containing function. The tags closest to the * node are returned first, so in the previous example, the param * tag on the containing function expression would be first. * * Does not return tags for binding patterns, because JSDoc matches * parameters by name and binding patterns do not have a name. */ function getJSDocParameterTags(param) { if (param.name && ts.isIdentifier(param.name)) { var name_1 = param.name.escapedText; return getJSDocTags(param.parent).filter(function (tag) { return ts.isJSDocParameterTag(tag) && ts.isIdentifier(tag.name) && tag.name.escapedText === name_1; }); } // a binding pattern doesn't have a name, so it's not possible to match it a JSDoc parameter, which is identified by name return undefined; } ts.getJSDocParameterTags = getJSDocParameterTags; /** * Return true if the node has JSDoc parameter tags. * * @remarks Includes parameter tags that are not directly on the node, * for example on a variable declaration whose initializer is a function expression. */ function hasJSDocParameterTags(node) { return !!getFirstJSDocTag(node, 284 /* JSDocParameterTag */); } ts.hasJSDocParameterTags = hasJSDocParameterTags; /** Gets the JSDoc augments tag for the node if present */ function getJSDocAugmentsTag(node) { return getFirstJSDocTag(node, 282 /* JSDocAugmentsTag */); } ts.getJSDocAugmentsTag = getJSDocAugmentsTag; /** Gets the JSDoc class tag for the node if present */ function getJSDocClassTag(node) { return getFirstJSDocTag(node, 283 /* JSDocClassTag */); } ts.getJSDocClassTag = getJSDocClassTag; /** Gets the JSDoc return tag for the node if present */ function getJSDocReturnTag(node) { return getFirstJSDocTag(node, 285 /* JSDocReturnTag */); } ts.getJSDocReturnTag = getJSDocReturnTag; /** Gets the JSDoc template tag for the node if present */ function getJSDocTemplateTag(node) { return getFirstJSDocTag(node, 287 /* JSDocTemplateTag */); } ts.getJSDocTemplateTag = getJSDocTemplateTag; /** Gets the JSDoc type tag for the node if present and valid */ function getJSDocTypeTag(node) { // We should have already issued an error if there were multiple type jsdocs, so just use the first one. var tag = getFirstJSDocTag(node, 286 /* JSDocTypeTag */); if (tag && tag.typeExpression && tag.typeExpression.type) { return tag; } return undefined; } ts.getJSDocTypeTag = getJSDocTypeTag; /** * Gets the type node for the node if provided via JSDoc. * * @remarks The search includes any JSDoc param tag that relates * to the provided parameter, for example a type tag on the * parameter itself, or a param tag on a containing function * expression, or a param tag on a variable declaration whose * initializer is the containing function. The tags closest to the * node are examined first, so in the previous example, the type * tag directly on the node would be returned. */ function getJSDocType(node) { var tag = getFirstJSDocTag(node, 286 /* JSDocTypeTag */); if (!tag && node.kind === 147 /* Parameter */) { var paramTags = getJSDocParameterTags(node); if (paramTags) { tag = ts.find(paramTags, function (tag) { return !!tag.typeExpression; }); } } return tag && tag.typeExpression && tag.typeExpression.type; } ts.getJSDocType = getJSDocType; /** * Gets the return type node for the node if provided via JSDoc's return tag. * * @remarks `getJSDocReturnTag` just gets the whole JSDoc tag. This function * gets the type from inside the braces. */ function getJSDocReturnType(node) { var returnTag = getJSDocReturnTag(node); return returnTag && returnTag.typeExpression && returnTag.typeExpression.type; } ts.getJSDocReturnType = getJSDocReturnType; /** Get all JSDoc tags related to a node, including those on parent nodes. */ function getJSDocTags(node) { var tags = node.jsDocCache; // If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing. if (tags === undefined) { node.jsDocCache = tags = ts.flatMap(ts.getJSDocCommentsAndTags(node), function (j) { return ts.isJSDoc(j) ? j.tags : j; }); } return tags; } ts.getJSDocTags = getJSDocTags; /** Get the first JSDoc tag of a specified kind, or undefined if not present. */ function getFirstJSDocTag(node, kind) { var tags = getJSDocTags(node); return ts.find(tags, function (doc) { return doc.kind === kind; }); } /** Gets all JSDoc tags of a specified kind, or undefined if not present. */ function getAllJSDocTagsOfKind(node, kind) { var tags = getJSDocTags(node); return ts.filter(tags, function (doc) { return doc.kind === kind; }); } ts.getAllJSDocTagsOfKind = getAllJSDocTagsOfKind; })(ts || (ts = {})); // Simple node tests of the form `node.kind === SyntaxKind.Foo`. (function (ts) { // Literals function isNumericLiteral(node) { return node.kind === 8 /* NumericLiteral */; } ts.isNumericLiteral = isNumericLiteral; function isStringLiteral(node) { return node.kind === 9 /* StringLiteral */; } ts.isStringLiteral = isStringLiteral; function isJsxText(node) { return node.kind === 10 /* JsxText */; } ts.isJsxText = isJsxText; function isRegularExpressionLiteral(node) { return node.kind === 12 /* RegularExpressionLiteral */; } ts.isRegularExpressionLiteral = isRegularExpressionLiteral; function isNoSubstitutionTemplateLiteral(node) { return node.kind === 13 /* NoSubstitutionTemplateLiteral */; } ts.isNoSubstitutionTemplateLiteral = isNoSubstitutionTemplateLiteral; // Pseudo-literals function isTemplateHead(node) { return node.kind === 14 /* TemplateHead */; } ts.isTemplateHead = isTemplateHead; function isTemplateMiddle(node) { return node.kind === 15 /* TemplateMiddle */; } ts.isTemplateMiddle = isTemplateMiddle; function isTemplateTail(node) { return node.kind === 16 /* TemplateTail */; } ts.isTemplateTail = isTemplateTail; function isIdentifier(node) { return node.kind === 71 /* Identifier */; } ts.isIdentifier = isIdentifier; // Names function isQualifiedName(node) { return node.kind === 144 /* QualifiedName */; } ts.isQualifiedName = isQualifiedName; function isComputedPropertyName(node) { return node.kind === 145 /* ComputedPropertyName */; } ts.isComputedPropertyName = isComputedPropertyName; // Signature elements function isTypeParameterDeclaration(node) { return node.kind === 146 /* TypeParameter */; } ts.isTypeParameterDeclaration = isTypeParameterDeclaration; function isParameter(node) { return node.kind === 147 /* Parameter */; } ts.isParameter = isParameter; function isDecorator(node) { return node.kind === 148 /* Decorator */; } ts.isDecorator = isDecorator; // TypeMember function isPropertySignature(node) { return node.kind === 149 /* PropertySignature */; } ts.isPropertySignature = isPropertySignature; function isPropertyDeclaration(node) { return node.kind === 150 /* PropertyDeclaration */; } ts.isPropertyDeclaration = isPropertyDeclaration; function isMethodSignature(node) { return node.kind === 151 /* MethodSignature */; } ts.isMethodSignature = isMethodSignature; function isMethodDeclaration(node) { return node.kind === 152 /* MethodDeclaration */; } ts.isMethodDeclaration = isMethodDeclaration; function isConstructorDeclaration(node) { return node.kind === 153 /* Constructor */; } ts.isConstructorDeclaration = isConstructorDeclaration; function isGetAccessorDeclaration(node) { return node.kind === 154 /* GetAccessor */; } ts.isGetAccessorDeclaration = isGetAccessorDeclaration; function isSetAccessorDeclaration(node) { return node.kind === 155 /* SetAccessor */; } ts.isSetAccessorDeclaration = isSetAccessorDeclaration; function isCallSignatureDeclaration(node) { return node.kind === 156 /* CallSignature */; } ts.isCallSignatureDeclaration = isCallSignatureDeclaration; function isConstructSignatureDeclaration(node) { return node.kind === 157 /* ConstructSignature */; } ts.isConstructSignatureDeclaration = isConstructSignatureDeclaration; function isIndexSignatureDeclaration(node) { return node.kind === 158 /* IndexSignature */; } ts.isIndexSignatureDeclaration = isIndexSignatureDeclaration; // Type function isTypePredicateNode(node) { return node.kind === 159 /* TypePredicate */; } ts.isTypePredicateNode = isTypePredicateNode; function isTypeReferenceNode(node) { return node.kind === 160 /* TypeReference */; } ts.isTypeReferenceNode = isTypeReferenceNode; function isFunctionTypeNode(node) { return node.kind === 161 /* FunctionType */; } ts.isFunctionTypeNode = isFunctionTypeNode; function isConstructorTypeNode(node) { return node.kind === 162 /* ConstructorType */; } ts.isConstructorTypeNode = isConstructorTypeNode; function isTypeQueryNode(node) { return node.kind === 163 /* TypeQuery */; } ts.isTypeQueryNode = isTypeQueryNode; function isTypeLiteralNode(node) { return node.kind === 164 /* TypeLiteral */; } ts.isTypeLiteralNode = isTypeLiteralNode; function isArrayTypeNode(node) { return node.kind === 165 /* ArrayType */; } ts.isArrayTypeNode = isArrayTypeNode; function isTupleTypeNode(node) { return node.kind === 166 /* TupleType */; } ts.isTupleTypeNode = isTupleTypeNode; function isUnionTypeNode(node) { return node.kind === 167 /* UnionType */; } ts.isUnionTypeNode = isUnionTypeNode; function isIntersectionTypeNode(node) { return node.kind === 168 /* IntersectionType */; } ts.isIntersectionTypeNode = isIntersectionTypeNode; function isParenthesizedTypeNode(node) { return node.kind === 169 /* ParenthesizedType */; } ts.isParenthesizedTypeNode = isParenthesizedTypeNode; function isThisTypeNode(node) { return node.kind === 170 /* ThisType */; } ts.isThisTypeNode = isThisTypeNode; function isTypeOperatorNode(node) { return node.kind === 171 /* TypeOperator */; } ts.isTypeOperatorNode = isTypeOperatorNode; function isIndexedAccessTypeNode(node) { return node.kind === 172 /* IndexedAccessType */; } ts.isIndexedAccessTypeNode = isIndexedAccessTypeNode; function isMappedTypeNode(node) { return node.kind === 173 /* MappedType */; } ts.isMappedTypeNode = isMappedTypeNode; function isLiteralTypeNode(node) { return node.kind === 174 /* LiteralType */; } ts.isLiteralTypeNode = isLiteralTypeNode; // Binding patterns function isObjectBindingPattern(node) { return node.kind === 175 /* ObjectBindingPattern */; } ts.isObjectBindingPattern = isObjectBindingPattern; function isArrayBindingPattern(node) { return node.kind === 176 /* ArrayBindingPattern */; } ts.isArrayBindingPattern = isArrayBindingPattern; function isBindingElement(node) { return node.kind === 177 /* BindingElement */; } ts.isBindingElement = isBindingElement; // Expression function isArrayLiteralExpression(node) { return node.kind === 178 /* ArrayLiteralExpression */; } ts.isArrayLiteralExpression = isArrayLiteralExpression; function isObjectLiteralExpression(node) { return node.kind === 179 /* ObjectLiteralExpression */; } ts.isObjectLiteralExpression = isObjectLiteralExpression; function isPropertyAccessExpression(node) { return node.kind === 180 /* PropertyAccessExpression */; } ts.isPropertyAccessExpression = isPropertyAccessExpression; function isElementAccessExpression(node) { return node.kind === 181 /* ElementAccessExpression */; } ts.isElementAccessExpression = isElementAccessExpression; function isCallExpression(node) { return node.kind === 182 /* CallExpression */; } ts.isCallExpression = isCallExpression; function isNewExpression(node) { return node.kind === 183 /* NewExpression */; } ts.isNewExpression = isNewExpression; function isTaggedTemplateExpression(node) { return node.kind === 184 /* TaggedTemplateExpression */; } ts.isTaggedTemplateExpression = isTaggedTemplateExpression; function isTypeAssertion(node) { return node.kind === 185 /* TypeAssertionExpression */; } ts.isTypeAssertion = isTypeAssertion; function isParenthesizedExpression(node) { return node.kind === 186 /* ParenthesizedExpression */; } ts.isParenthesizedExpression = isParenthesizedExpression; function skipPartiallyEmittedExpressions(node) { while (node.kind === 292 /* PartiallyEmittedExpression */) { node = node.expression; } return node; } ts.skipPartiallyEmittedExpressions = skipPartiallyEmittedExpressions; function isFunctionExpression(node) { return node.kind === 187 /* FunctionExpression */; } ts.isFunctionExpression = isFunctionExpression; function isArrowFunction(node) { return node.kind === 188 /* ArrowFunction */; } ts.isArrowFunction = isArrowFunction; function isDeleteExpression(node) { return node.kind === 189 /* DeleteExpression */; } ts.isDeleteExpression = isDeleteExpression; function isTypeOfExpression(node) { return node.kind === 192 /* AwaitExpression */; } ts.isTypeOfExpression = isTypeOfExpression; function isVoidExpression(node) { return node.kind === 191 /* VoidExpression */; } ts.isVoidExpression = isVoidExpression; function isAwaitExpression(node) { return node.kind === 192 /* AwaitExpression */; } ts.isAwaitExpression = isAwaitExpression; function isPrefixUnaryExpression(node) { return node.kind === 193 /* PrefixUnaryExpression */; } ts.isPrefixUnaryExpression = isPrefixUnaryExpression; function isPostfixUnaryExpression(node) { return node.kind === 194 /* PostfixUnaryExpression */; } ts.isPostfixUnaryExpression = isPostfixUnaryExpression; function isBinaryExpression(node) { return node.kind === 195 /* BinaryExpression */; } ts.isBinaryExpression = isBinaryExpression; function isConditionalExpression(node) { return node.kind === 196 /* ConditionalExpression */; } ts.isConditionalExpression = isConditionalExpression; function isTemplateExpression(node) { return node.kind === 197 /* TemplateExpression */; } ts.isTemplateExpression = isTemplateExpression; function isYieldExpression(node) { return node.kind === 198 /* YieldExpression */; } ts.isYieldExpression = isYieldExpression; function isSpreadElement(node) { return node.kind === 199 /* SpreadElement */; } ts.isSpreadElement = isSpreadElement; function isClassExpression(node) { return node.kind === 200 /* ClassExpression */; } ts.isClassExpression = isClassExpression; function isOmittedExpression(node) { return node.kind === 201 /* OmittedExpression */; } ts.isOmittedExpression = isOmittedExpression; function isExpressionWithTypeArguments(node) { return node.kind === 202 /* ExpressionWithTypeArguments */; } ts.isExpressionWithTypeArguments = isExpressionWithTypeArguments; function isAsExpression(node) { return node.kind === 203 /* AsExpression */; } ts.isAsExpression = isAsExpression; function isNonNullExpression(node) { return node.kind === 204 /* NonNullExpression */; } ts.isNonNullExpression = isNonNullExpression; function isMetaProperty(node) { return node.kind === 205 /* MetaProperty */; } ts.isMetaProperty = isMetaProperty; // Misc function isTemplateSpan(node) { return node.kind === 206 /* TemplateSpan */; } ts.isTemplateSpan = isTemplateSpan; function isSemicolonClassElement(node) { return node.kind === 207 /* SemicolonClassElement */; } ts.isSemicolonClassElement = isSemicolonClassElement; // Block function isBlock(node) { return node.kind === 208 /* Block */; } ts.isBlock = isBlock; function isVariableStatement(node) { return node.kind === 209 /* VariableStatement */; } ts.isVariableStatement = isVariableStatement; function isEmptyStatement(node) { return node.kind === 210 /* EmptyStatement */; } ts.isEmptyStatement = isEmptyStatement; function isExpressionStatement(node) { return node.kind === 211 /* ExpressionStatement */; } ts.isExpressionStatement = isExpressionStatement; function isIfStatement(node) { return node.kind === 212 /* IfStatement */; } ts.isIfStatement = isIfStatement; function isDoStatement(node) { return node.kind === 213 /* DoStatement */; } ts.isDoStatement = isDoStatement; function isWhileStatement(node) { return node.kind === 214 /* WhileStatement */; } ts.isWhileStatement = isWhileStatement; function isForStatement(node) { return node.kind === 215 /* ForStatement */; } ts.isForStatement = isForStatement; function isForInStatement(node) { return node.kind === 216 /* ForInStatement */; } ts.isForInStatement = isForInStatement; function isForOfStatement(node) { return node.kind === 217 /* ForOfStatement */; } ts.isForOfStatement = isForOfStatement; function isContinueStatement(node) { return node.kind === 218 /* ContinueStatement */; } ts.isContinueStatement = isContinueStatement; function isBreakStatement(node) { return node.kind === 219 /* BreakStatement */; } ts.isBreakStatement = isBreakStatement; function isBreakOrContinueStatement(node) { return node.kind === 219 /* BreakStatement */ || node.kind === 218 /* ContinueStatement */; } ts.isBreakOrContinueStatement = isBreakOrContinueStatement; function isReturnStatement(node) { return node.kind === 220 /* ReturnStatement */; } ts.isReturnStatement = isReturnStatement; function isWithStatement(node) { return node.kind === 221 /* WithStatement */; } ts.isWithStatement = isWithStatement; function isSwitchStatement(node) { return node.kind === 222 /* SwitchStatement */; } ts.isSwitchStatement = isSwitchStatement; function isLabeledStatement(node) { return node.kind === 223 /* LabeledStatement */; } ts.isLabeledStatement = isLabeledStatement; function isThrowStatement(node) { return node.kind === 224 /* ThrowStatement */; } ts.isThrowStatement = isThrowStatement; function isTryStatement(node) { return node.kind === 225 /* TryStatement */; } ts.isTryStatement = isTryStatement; function isDebuggerStatement(node) { return node.kind === 226 /* DebuggerStatement */; } ts.isDebuggerStatement = isDebuggerStatement; function isVariableDeclaration(node) { return node.kind === 227 /* VariableDeclaration */; } ts.isVariableDeclaration = isVariableDeclaration; function isVariableDeclarationList(node) { return node.kind === 228 /* VariableDeclarationList */; } ts.isVariableDeclarationList = isVariableDeclarationList; function isFunctionDeclaration(node) { return node.kind === 229 /* FunctionDeclaration */; } ts.isFunctionDeclaration = isFunctionDeclaration; function isClassDeclaration(node) { return node.kind === 230 /* ClassDeclaration */; } ts.isClassDeclaration = isClassDeclaration; function isInterfaceDeclaration(node) { return node.kind === 231 /* InterfaceDeclaration */; } ts.isInterfaceDeclaration = isInterfaceDeclaration; function isTypeAliasDeclaration(node) { return node.kind === 232 /* TypeAliasDeclaration */; } ts.isTypeAliasDeclaration = isTypeAliasDeclaration; function isEnumDeclaration(node) { return node.kind === 233 /* EnumDeclaration */; } ts.isEnumDeclaration = isEnumDeclaration; function isModuleDeclaration(node) { return node.kind === 234 /* ModuleDeclaration */; } ts.isModuleDeclaration = isModuleDeclaration; function isModuleBlock(node) { return node.kind === 235 /* ModuleBlock */; } ts.isModuleBlock = isModuleBlock; function isCaseBlock(node) { return node.kind === 236 /* CaseBlock */; } ts.isCaseBlock = isCaseBlock; function isNamespaceExportDeclaration(node) { return node.kind === 237 /* NamespaceExportDeclaration */; } ts.isNamespaceExportDeclaration = isNamespaceExportDeclaration; function isImportEqualsDeclaration(node) { return node.kind === 238 /* ImportEqualsDeclaration */; } ts.isImportEqualsDeclaration = isImportEqualsDeclaration; function isImportDeclaration(node) { return node.kind === 239 /* ImportDeclaration */; } ts.isImportDeclaration = isImportDeclaration; function isImportClause(node) { return node.kind === 240 /* ImportClause */; } ts.isImportClause = isImportClause; function isNamespaceImport(node) { return node.kind === 241 /* NamespaceImport */; } ts.isNamespaceImport = isNamespaceImport; function isNamedImports(node) { return node.kind === 242 /* NamedImports */; } ts.isNamedImports = isNamedImports; function isImportSpecifier(node) { return node.kind === 243 /* ImportSpecifier */; } ts.isImportSpecifier = isImportSpecifier; function isExportAssignment(node) { return node.kind === 244 /* ExportAssignment */; } ts.isExportAssignment = isExportAssignment; function isExportDeclaration(node) { return node.kind === 245 /* ExportDeclaration */; } ts.isExportDeclaration = isExportDeclaration; function isNamedExports(node) { return node.kind === 246 /* NamedExports */; } ts.isNamedExports = isNamedExports; function isExportSpecifier(node) { return node.kind === 247 /* ExportSpecifier */; } ts.isExportSpecifier = isExportSpecifier; function isMissingDeclaration(node) { return node.kind === 248 /* MissingDeclaration */; } ts.isMissingDeclaration = isMissingDeclaration; // Module References function isExternalModuleReference(node) { return node.kind === 249 /* ExternalModuleReference */; } ts.isExternalModuleReference = isExternalModuleReference; // JSX function isJsxElement(node) { return node.kind === 250 /* JsxElement */; } ts.isJsxElement = isJsxElement; function isJsxSelfClosingElement(node) { return node.kind === 251 /* JsxSelfClosingElement */; } ts.isJsxSelfClosingElement = isJsxSelfClosingElement; function isJsxOpeningElement(node) { return node.kind === 252 /* JsxOpeningElement */; } ts.isJsxOpeningElement = isJsxOpeningElement; function isJsxClosingElement(node) { return node.kind === 253 /* JsxClosingElement */; } ts.isJsxClosingElement = isJsxClosingElement; function isJsxFragment(node) { return node.kind === 254 /* JsxFragment */; } ts.isJsxFragment = isJsxFragment; function isJsxOpeningFragment(node) { return node.kind === 255 /* JsxOpeningFragment */; } ts.isJsxOpeningFragment = isJsxOpeningFragment; function isJsxClosingFragment(node) { return node.kind === 256 /* JsxClosingFragment */; } ts.isJsxClosingFragment = isJsxClosingFragment; function isJsxAttribute(node) { return node.kind === 257 /* JsxAttribute */; } ts.isJsxAttribute = isJsxAttribute; function isJsxAttributes(node) { return node.kind === 258 /* JsxAttributes */; } ts.isJsxAttributes = isJsxAttributes; function isJsxSpreadAttribute(node) { return node.kind === 259 /* JsxSpreadAttribute */; } ts.isJsxSpreadAttribute = isJsxSpreadAttribute; function isJsxExpression(node) { return node.kind === 260 /* JsxExpression */; } ts.isJsxExpression = isJsxExpression; // Clauses function isCaseClause(node) { return node.kind === 261 /* CaseClause */; } ts.isCaseClause = isCaseClause; function isDefaultClause(node) { return node.kind === 262 /* DefaultClause */; } ts.isDefaultClause = isDefaultClause; function isHeritageClause(node) { return node.kind === 263 /* HeritageClause */; } ts.isHeritageClause = isHeritageClause; function isCatchClause(node) { return node.kind === 264 /* CatchClause */; } ts.isCatchClause = isCatchClause; // Property assignments function isPropertyAssignment(node) { return node.kind === 265 /* PropertyAssignment */; } ts.isPropertyAssignment = isPropertyAssignment; function isShorthandPropertyAssignment(node) { return node.kind === 266 /* ShorthandPropertyAssignment */; } ts.isShorthandPropertyAssignment = isShorthandPropertyAssignment; function isSpreadAssignment(node) { return node.kind === 267 /* SpreadAssignment */; } ts.isSpreadAssignment = isSpreadAssignment; // Enum function isEnumMember(node) { return node.kind === 268 /* EnumMember */; } ts.isEnumMember = isEnumMember; // Top-level nodes function isSourceFile(node) { return node.kind === 269 /* SourceFile */; } ts.isSourceFile = isSourceFile; function isBundle(node) { return node.kind === 270 /* Bundle */; } ts.isBundle = isBundle; // JSDoc function isJSDocTypeExpression(node) { return node.kind === 271 /* JSDocTypeExpression */; } ts.isJSDocTypeExpression = isJSDocTypeExpression; function isJSDocAllType(node) { return node.kind === 272 /* JSDocAllType */; } ts.isJSDocAllType = isJSDocAllType; function isJSDocUnknownType(node) { return node.kind === 273 /* JSDocUnknownType */; } ts.isJSDocUnknownType = isJSDocUnknownType; function isJSDocNullableType(node) { return node.kind === 274 /* JSDocNullableType */; } ts.isJSDocNullableType = isJSDocNullableType; function isJSDocNonNullableType(node) { return node.kind === 275 /* JSDocNonNullableType */; } ts.isJSDocNonNullableType = isJSDocNonNullableType; function isJSDocOptionalType(node) { return node.kind === 276 /* JSDocOptionalType */; } ts.isJSDocOptionalType = isJSDocOptionalType; function isJSDocFunctionType(node) { return node.kind === 277 /* JSDocFunctionType */; } ts.isJSDocFunctionType = isJSDocFunctionType; function isJSDocVariadicType(node) { return node.kind === 278 /* JSDocVariadicType */; } ts.isJSDocVariadicType = isJSDocVariadicType; function isJSDoc(node) { return node.kind === 279 /* JSDocComment */; } ts.isJSDoc = isJSDoc; function isJSDocAugmentsTag(node) { return node.kind === 282 /* JSDocAugmentsTag */; } ts.isJSDocAugmentsTag = isJSDocAugmentsTag; function isJSDocParameterTag(node) { return node.kind === 284 /* JSDocParameterTag */; } ts.isJSDocParameterTag = isJSDocParameterTag; function isJSDocReturnTag(node) { return node.kind === 285 /* JSDocReturnTag */; } ts.isJSDocReturnTag = isJSDocReturnTag; function isJSDocTypeTag(node) { return node.kind === 286 /* JSDocTypeTag */; } ts.isJSDocTypeTag = isJSDocTypeTag; function isJSDocTemplateTag(node) { return node.kind === 287 /* JSDocTemplateTag */; } ts.isJSDocTemplateTag = isJSDocTemplateTag; function isJSDocTypedefTag(node) { return node.kind === 288 /* JSDocTypedefTag */; } ts.isJSDocTypedefTag = isJSDocTypedefTag; function isJSDocPropertyTag(node) { return node.kind === 289 /* JSDocPropertyTag */; } ts.isJSDocPropertyTag = isJSDocPropertyTag; function isJSDocPropertyLikeTag(node) { return node.kind === 289 /* JSDocPropertyTag */ || node.kind === 284 /* JSDocParameterTag */; } ts.isJSDocPropertyLikeTag = isJSDocPropertyLikeTag; function isJSDocTypeLiteral(node) { return node.kind === 280 /* JSDocTypeLiteral */; } ts.isJSDocTypeLiteral = isJSDocTypeLiteral; })(ts || (ts = {})); // Node tests // // All node tests in the following list should *not* reference parent pointers so that // they may be used with transformations. (function (ts) { /* @internal */ function isSyntaxList(n) { return n.kind === 290 /* SyntaxList */; } ts.isSyntaxList = isSyntaxList; /* @internal */ function isNode(node) { return isNodeKind(node.kind); } ts.isNode = isNode; /* @internal */ function isNodeKind(kind) { return kind >= 144 /* FirstNode */; } ts.isNodeKind = isNodeKind; /** * True if node is of some token syntax kind. * For example, this is true for an IfKeyword but not for an IfStatement. */ function isToken(n) { return n.kind >= 0 /* FirstToken */ && n.kind <= 143 /* LastToken */; } ts.isToken = isToken; // Node Arrays /* @internal */ function isNodeArray(array) { return array.hasOwnProperty("pos") && array.hasOwnProperty("end"); } ts.isNodeArray = isNodeArray; // Literals /* @internal */ function isLiteralKind(kind) { return 8 /* FirstLiteralToken */ <= kind && kind <= 13 /* LastLiteralToken */; } ts.isLiteralKind = isLiteralKind; function isLiteralExpression(node) { return isLiteralKind(node.kind); } ts.isLiteralExpression = isLiteralExpression; // Pseudo-literals /* @internal */ function isTemplateLiteralKind(kind) { return 13 /* FirstTemplateToken */ <= kind && kind <= 16 /* LastTemplateToken */; } ts.isTemplateLiteralKind = isTemplateLiteralKind; function isTemplateMiddleOrTemplateTail(node) { var kind = node.kind; return kind === 15 /* TemplateMiddle */ || kind === 16 /* TemplateTail */; } ts.isTemplateMiddleOrTemplateTail = isTemplateMiddleOrTemplateTail; function isStringTextContainingNode(node) { return node.kind === 9 /* StringLiteral */ || isTemplateLiteralKind(node.kind); } ts.isStringTextContainingNode = isStringTextContainingNode; // Identifiers /* @internal */ function isGeneratedIdentifier(node) { // Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`. return ts.isIdentifier(node) && node.autoGenerateKind > 0 /* None */; } ts.isGeneratedIdentifier = isGeneratedIdentifier; // Keywords /* @internal */ function isModifierKind(token) { switch (token) { case 117 /* AbstractKeyword */: case 120 /* AsyncKeyword */: case 76 /* ConstKeyword */: case 124 /* DeclareKeyword */: case 79 /* DefaultKeyword */: case 84 /* ExportKeyword */: case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 131 /* ReadonlyKeyword */: case 115 /* StaticKeyword */: return true; } return false; } ts.isModifierKind = isModifierKind; function isModifier(node) { return isModifierKind(node.kind); } ts.isModifier = isModifier; function isEntityName(node) { var kind = node.kind; return kind === 144 /* QualifiedName */ || kind === 71 /* Identifier */; } ts.isEntityName = isEntityName; function isPropertyName(node) { var kind = node.kind; return kind === 71 /* Identifier */ || kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */ || kind === 145 /* ComputedPropertyName */; } ts.isPropertyName = isPropertyName; function isBindingName(node) { var kind = node.kind; return kind === 71 /* Identifier */ || kind === 175 /* ObjectBindingPattern */ || kind === 176 /* ArrayBindingPattern */; } ts.isBindingName = isBindingName; // Functions function isFunctionLike(node) { return node && isFunctionLikeKind(node.kind); } ts.isFunctionLike = isFunctionLike; /* @internal */ function isFunctionLikeDeclaration(node) { return node && isFunctionLikeDeclarationKind(node.kind); } ts.isFunctionLikeDeclaration = isFunctionLikeDeclaration; function isFunctionLikeDeclarationKind(kind) { switch (kind) { case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return true; default: return false; } } /* @internal */ function isFunctionLikeKind(kind) { switch (kind) { case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 161 /* FunctionType */: case 277 /* JSDocFunctionType */: case 162 /* ConstructorType */: return true; default: return isFunctionLikeDeclarationKind(kind); } } ts.isFunctionLikeKind = isFunctionLikeKind; /* @internal */ function isFunctionOrModuleBlock(node) { return ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isBlock(node) && isFunctionLike(node.parent); } ts.isFunctionOrModuleBlock = isFunctionOrModuleBlock; // Classes function isClassElement(node) { var kind = node.kind; return kind === 153 /* Constructor */ || kind === 150 /* PropertyDeclaration */ || kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */ || kind === 158 /* IndexSignature */ || kind === 207 /* SemicolonClassElement */ || kind === 248 /* MissingDeclaration */; } ts.isClassElement = isClassElement; function isClassLike(node) { return node && (node.kind === 230 /* ClassDeclaration */ || node.kind === 200 /* ClassExpression */); } ts.isClassLike = isClassLike; function isAccessor(node) { return node && (node.kind === 154 /* GetAccessor */ || node.kind === 155 /* SetAccessor */); } ts.isAccessor = isAccessor; // Type members function isTypeElement(node) { var kind = node.kind; return kind === 157 /* ConstructSignature */ || kind === 156 /* CallSignature */ || kind === 149 /* PropertySignature */ || kind === 151 /* MethodSignature */ || kind === 158 /* IndexSignature */ || kind === 248 /* MissingDeclaration */; } ts.isTypeElement = isTypeElement; function isObjectLiteralElementLike(node) { var kind = node.kind; return kind === 265 /* PropertyAssignment */ || kind === 266 /* ShorthandPropertyAssignment */ || kind === 267 /* SpreadAssignment */ || kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */ || kind === 248 /* MissingDeclaration */; } ts.isObjectLiteralElementLike = isObjectLiteralElementLike; // Type function isTypeNodeKind(kind) { return (kind >= 159 /* FirstTypeNode */ && kind <= 174 /* LastTypeNode */) || kind === 119 /* AnyKeyword */ || kind === 133 /* NumberKeyword */ || kind === 134 /* ObjectKeyword */ || kind === 122 /* BooleanKeyword */ || kind === 136 /* StringKeyword */ || kind === 137 /* SymbolKeyword */ || kind === 99 /* ThisKeyword */ || kind === 105 /* VoidKeyword */ || kind === 139 /* UndefinedKeyword */ || kind === 95 /* NullKeyword */ || kind === 130 /* NeverKeyword */ || kind === 202 /* ExpressionWithTypeArguments */ || kind === 272 /* JSDocAllType */ || kind === 273 /* JSDocUnknownType */ || kind === 274 /* JSDocNullableType */ || kind === 275 /* JSDocNonNullableType */ || kind === 276 /* JSDocOptionalType */ || kind === 277 /* JSDocFunctionType */ || kind === 278 /* JSDocVariadicType */; } /** * Node test that determines whether a node is a valid type node. * This differs from the `isPartOfTypeNode` function which determines whether a node is *part* * of a TypeNode. */ function isTypeNode(node) { return isTypeNodeKind(node.kind); } ts.isTypeNode = isTypeNode; function isFunctionOrConstructorTypeNode(node) { switch (node.kind) { case 161 /* FunctionType */: case 162 /* ConstructorType */: return true; } return false; } ts.isFunctionOrConstructorTypeNode = isFunctionOrConstructorTypeNode; // Binding patterns /* @internal */ function isBindingPattern(node) { if (node) { var kind = node.kind; return kind === 176 /* ArrayBindingPattern */ || kind === 175 /* ObjectBindingPattern */; } return false; } ts.isBindingPattern = isBindingPattern; /* @internal */ function isAssignmentPattern(node) { var kind = node.kind; return kind === 178 /* ArrayLiteralExpression */ || kind === 179 /* ObjectLiteralExpression */; } ts.isAssignmentPattern = isAssignmentPattern; /* @internal */ function isArrayBindingElement(node) { var kind = node.kind; return kind === 177 /* BindingElement */ || kind === 201 /* OmittedExpression */; } ts.isArrayBindingElement = isArrayBindingElement; /** * Determines whether the BindingOrAssignmentElement is a BindingElement-like declaration */ /* @internal */ function isDeclarationBindingElement(bindingElement) { switch (bindingElement.kind) { case 227 /* VariableDeclaration */: case 147 /* Parameter */: case 177 /* BindingElement */: return true; } return false; } ts.isDeclarationBindingElement = isDeclarationBindingElement; /** * Determines whether a node is a BindingOrAssignmentPattern */ /* @internal */ function isBindingOrAssignmentPattern(node) { return isObjectBindingOrAssignmentPattern(node) || isArrayBindingOrAssignmentPattern(node); } ts.isBindingOrAssignmentPattern = isBindingOrAssignmentPattern; /** * Determines whether a node is an ObjectBindingOrAssignmentPattern */ /* @internal */ function isObjectBindingOrAssignmentPattern(node) { switch (node.kind) { case 175 /* ObjectBindingPattern */: case 179 /* ObjectLiteralExpression */: return true; } return false; } ts.isObjectBindingOrAssignmentPattern = isObjectBindingOrAssignmentPattern; /** * Determines whether a node is an ArrayBindingOrAssignmentPattern */ /* @internal */ function isArrayBindingOrAssignmentPattern(node) { switch (node.kind) { case 176 /* ArrayBindingPattern */: case 178 /* ArrayLiteralExpression */: return true; } return false; } ts.isArrayBindingOrAssignmentPattern = isArrayBindingOrAssignmentPattern; // Expression function isPropertyAccessOrQualifiedName(node) { var kind = node.kind; return kind === 180 /* PropertyAccessExpression */ || kind === 144 /* QualifiedName */; } ts.isPropertyAccessOrQualifiedName = isPropertyAccessOrQualifiedName; function isCallLikeExpression(node) { switch (node.kind) { case 252 /* JsxOpeningElement */: case 251 /* JsxSelfClosingElement */: case 182 /* CallExpression */: case 183 /* NewExpression */: case 184 /* TaggedTemplateExpression */: case 148 /* Decorator */: return true; default: return false; } } ts.isCallLikeExpression = isCallLikeExpression; function isCallOrNewExpression(node) { return node.kind === 182 /* CallExpression */ || node.kind === 183 /* NewExpression */; } ts.isCallOrNewExpression = isCallOrNewExpression; function isTemplateLiteral(node) { var kind = node.kind; return kind === 197 /* TemplateExpression */ || kind === 13 /* NoSubstitutionTemplateLiteral */; } ts.isTemplateLiteral = isTemplateLiteral; /* @internal */ function isLeftHandSideExpression(node) { return isLeftHandSideExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isLeftHandSideExpression = isLeftHandSideExpression; function isLeftHandSideExpressionKind(kind) { switch (kind) { case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: case 183 /* NewExpression */: case 182 /* CallExpression */: case 250 /* JsxElement */: case 251 /* JsxSelfClosingElement */: case 254 /* JsxFragment */: case 184 /* TaggedTemplateExpression */: case 178 /* ArrayLiteralExpression */: case 186 /* ParenthesizedExpression */: case 179 /* ObjectLiteralExpression */: case 200 /* ClassExpression */: case 187 /* FunctionExpression */: case 71 /* Identifier */: case 12 /* RegularExpressionLiteral */: case 8 /* NumericLiteral */: case 9 /* StringLiteral */: case 13 /* NoSubstitutionTemplateLiteral */: case 197 /* TemplateExpression */: case 86 /* FalseKeyword */: case 95 /* NullKeyword */: case 99 /* ThisKeyword */: case 101 /* TrueKeyword */: case 97 /* SuperKeyword */: case 204 /* NonNullExpression */: case 205 /* MetaProperty */: case 91 /* ImportKeyword */:// technically this is only an Expression if it's in a CallExpression return true; default: return false; } } /* @internal */ function isUnaryExpression(node) { return isUnaryExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isUnaryExpression = isUnaryExpression; function isUnaryExpressionKind(kind) { switch (kind) { case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: case 189 /* DeleteExpression */: case 190 /* TypeOfExpression */: case 191 /* VoidExpression */: case 192 /* AwaitExpression */: case 185 /* TypeAssertionExpression */: return true; default: return isLeftHandSideExpressionKind(kind); } } /* @internal */ function isUnaryExpressionWithWrite(expr) { switch (expr.kind) { case 194 /* PostfixUnaryExpression */: return true; case 193 /* PrefixUnaryExpression */: return expr.operator === 43 /* PlusPlusToken */ || expr.operator === 44 /* MinusMinusToken */; default: return false; } } ts.isUnaryExpressionWithWrite = isUnaryExpressionWithWrite; /* @internal */ /** * Determines whether a node is an expression based only on its kind. * Use `isExpressionNode` if not in transforms. */ function isExpression(node) { return isExpressionKind(ts.skipPartiallyEmittedExpressions(node).kind); } ts.isExpression = isExpression; function isExpressionKind(kind) { switch (kind) { case 196 /* ConditionalExpression */: case 198 /* YieldExpression */: case 188 /* ArrowFunction */: case 195 /* BinaryExpression */: case 199 /* SpreadElement */: case 203 /* AsExpression */: case 201 /* OmittedExpression */: case 293 /* CommaListExpression */: case 292 /* PartiallyEmittedExpression */: return true; default: return isUnaryExpressionKind(kind); } } function isAssertionExpression(node) { var kind = node.kind; return kind === 185 /* TypeAssertionExpression */ || kind === 203 /* AsExpression */; } ts.isAssertionExpression = isAssertionExpression; /* @internal */ function isPartiallyEmittedExpression(node) { return node.kind === 292 /* PartiallyEmittedExpression */; } ts.isPartiallyEmittedExpression = isPartiallyEmittedExpression; /* @internal */ function isNotEmittedStatement(node) { return node.kind === 291 /* NotEmittedStatement */; } ts.isNotEmittedStatement = isNotEmittedStatement; /* @internal */ function isNotEmittedOrPartiallyEmittedNode(node) { return isNotEmittedStatement(node) || isPartiallyEmittedExpression(node); } ts.isNotEmittedOrPartiallyEmittedNode = isNotEmittedOrPartiallyEmittedNode; // Statement function isIterationStatement(node, lookInLabeledStatements) { switch (node.kind) { case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 213 /* DoStatement */: case 214 /* WhileStatement */: return true; case 223 /* LabeledStatement */: return lookInLabeledStatements && isIterationStatement(node.statement, lookInLabeledStatements); } return false; } ts.isIterationStatement = isIterationStatement; /* @internal */ function isForInOrOfStatement(node) { return node.kind === 216 /* ForInStatement */ || node.kind === 217 /* ForOfStatement */; } ts.isForInOrOfStatement = isForInOrOfStatement; // Element /* @internal */ function isConciseBody(node) { return ts.isBlock(node) || isExpression(node); } ts.isConciseBody = isConciseBody; /* @internal */ function isFunctionBody(node) { return ts.isBlock(node); } ts.isFunctionBody = isFunctionBody; /* @internal */ function isForInitializer(node) { return ts.isVariableDeclarationList(node) || isExpression(node); } ts.isForInitializer = isForInitializer; /* @internal */ function isModuleBody(node) { var kind = node.kind; return kind === 235 /* ModuleBlock */ || kind === 234 /* ModuleDeclaration */ || kind === 71 /* Identifier */; } ts.isModuleBody = isModuleBody; /* @internal */ function isNamespaceBody(node) { var kind = node.kind; return kind === 235 /* ModuleBlock */ || kind === 234 /* ModuleDeclaration */; } ts.isNamespaceBody = isNamespaceBody; /* @internal */ function isJSDocNamespaceBody(node) { var kind = node.kind; return kind === 71 /* Identifier */ || kind === 234 /* ModuleDeclaration */; } ts.isJSDocNamespaceBody = isJSDocNamespaceBody; /* @internal */ function isNamedImportBindings(node) { var kind = node.kind; return kind === 242 /* NamedImports */ || kind === 241 /* NamespaceImport */; } ts.isNamedImportBindings = isNamedImportBindings; /* @internal */ function isModuleOrEnumDeclaration(node) { return node.kind === 234 /* ModuleDeclaration */ || node.kind === 233 /* EnumDeclaration */; } ts.isModuleOrEnumDeclaration = isModuleOrEnumDeclaration; function isDeclarationKind(kind) { return kind === 188 /* ArrowFunction */ || kind === 177 /* BindingElement */ || kind === 230 /* ClassDeclaration */ || kind === 200 /* ClassExpression */ || kind === 153 /* Constructor */ || kind === 233 /* EnumDeclaration */ || kind === 268 /* EnumMember */ || kind === 247 /* ExportSpecifier */ || kind === 229 /* FunctionDeclaration */ || kind === 187 /* FunctionExpression */ || kind === 154 /* GetAccessor */ || kind === 240 /* ImportClause */ || kind === 238 /* ImportEqualsDeclaration */ || kind === 243 /* ImportSpecifier */ || kind === 231 /* InterfaceDeclaration */ || kind === 257 /* JsxAttribute */ || kind === 152 /* MethodDeclaration */ || kind === 151 /* MethodSignature */ || kind === 234 /* ModuleDeclaration */ || kind === 237 /* NamespaceExportDeclaration */ || kind === 241 /* NamespaceImport */ || kind === 147 /* Parameter */ || kind === 265 /* PropertyAssignment */ || kind === 150 /* PropertyDeclaration */ || kind === 149 /* PropertySignature */ || kind === 155 /* SetAccessor */ || kind === 266 /* ShorthandPropertyAssignment */ || kind === 232 /* TypeAliasDeclaration */ || kind === 146 /* TypeParameter */ || kind === 227 /* VariableDeclaration */ || kind === 288 /* JSDocTypedefTag */; } function isDeclarationStatementKind(kind) { return kind === 229 /* FunctionDeclaration */ || kind === 248 /* MissingDeclaration */ || kind === 230 /* ClassDeclaration */ || kind === 231 /* InterfaceDeclaration */ || kind === 232 /* TypeAliasDeclaration */ || kind === 233 /* EnumDeclaration */ || kind === 234 /* ModuleDeclaration */ || kind === 239 /* ImportDeclaration */ || kind === 238 /* ImportEqualsDeclaration */ || kind === 245 /* ExportDeclaration */ || kind === 244 /* ExportAssignment */ || kind === 237 /* NamespaceExportDeclaration */; } function isStatementKindButNotDeclarationKind(kind) { return kind === 219 /* BreakStatement */ || kind === 218 /* ContinueStatement */ || kind === 226 /* DebuggerStatement */ || kind === 213 /* DoStatement */ || kind === 211 /* ExpressionStatement */ || kind === 210 /* EmptyStatement */ || kind === 216 /* ForInStatement */ || kind === 217 /* ForOfStatement */ || kind === 215 /* ForStatement */ || kind === 212 /* IfStatement */ || kind === 223 /* LabeledStatement */ || kind === 220 /* ReturnStatement */ || kind === 222 /* SwitchStatement */ || kind === 224 /* ThrowStatement */ || kind === 225 /* TryStatement */ || kind === 209 /* VariableStatement */ || kind === 214 /* WhileStatement */ || kind === 221 /* WithStatement */ || kind === 291 /* NotEmittedStatement */ || kind === 295 /* EndOfDeclarationMarker */ || kind === 294 /* MergeDeclarationMarker */; } /* @internal */ function isDeclaration(node) { if (node.kind === 146 /* TypeParameter */) { return node.parent.kind !== 287 /* JSDocTemplateTag */ || ts.isInJavaScriptFile(node); } return isDeclarationKind(node.kind); } ts.isDeclaration = isDeclaration; /* @internal */ function isDeclarationStatement(node) { return isDeclarationStatementKind(node.kind); } ts.isDeclarationStatement = isDeclarationStatement; /** * Determines whether the node is a statement that is not also a declaration */ /* @internal */ function isStatementButNotDeclaration(node) { return isStatementKindButNotDeclarationKind(node.kind); } ts.isStatementButNotDeclaration = isStatementButNotDeclaration; /* @internal */ function isStatement(node) { var kind = node.kind; return isStatementKindButNotDeclarationKind(kind) || isDeclarationStatementKind(kind) || isBlockStatement(node); } ts.isStatement = isStatement; function isBlockStatement(node) { if (node.kind !== 208 /* Block */) return false; if (node.parent !== undefined) { if (node.parent.kind === 225 /* TryStatement */ || node.parent.kind === 264 /* CatchClause */) { return false; } } return !ts.isFunctionBlock(node); } // Module references /* @internal */ function isModuleReference(node) { var kind = node.kind; return kind === 249 /* ExternalModuleReference */ || kind === 144 /* QualifiedName */ || kind === 71 /* Identifier */; } ts.isModuleReference = isModuleReference; // JSX /* @internal */ function isJsxTagNameExpression(node) { var kind = node.kind; return kind === 99 /* ThisKeyword */ || kind === 71 /* Identifier */ || kind === 180 /* PropertyAccessExpression */; } ts.isJsxTagNameExpression = isJsxTagNameExpression; /* @internal */ function isJsxChild(node) { var kind = node.kind; return kind === 250 /* JsxElement */ || kind === 260 /* JsxExpression */ || kind === 251 /* JsxSelfClosingElement */ || kind === 10 /* JsxText */ || kind === 254 /* JsxFragment */; } ts.isJsxChild = isJsxChild; /* @internal */ function isJsxAttributeLike(node) { var kind = node.kind; return kind === 257 /* JsxAttribute */ || kind === 259 /* JsxSpreadAttribute */; } ts.isJsxAttributeLike = isJsxAttributeLike; /* @internal */ function isStringLiteralOrJsxExpression(node) { var kind = node.kind; return kind === 9 /* StringLiteral */ || kind === 260 /* JsxExpression */; } ts.isStringLiteralOrJsxExpression = isStringLiteralOrJsxExpression; function isJsxOpeningLikeElement(node) { var kind = node.kind; return kind === 252 /* JsxOpeningElement */ || kind === 251 /* JsxSelfClosingElement */; } ts.isJsxOpeningLikeElement = isJsxOpeningLikeElement; // Clauses function isCaseOrDefaultClause(node) { var kind = node.kind; return kind === 261 /* CaseClause */ || kind === 262 /* DefaultClause */; } ts.isCaseOrDefaultClause = isCaseOrDefaultClause; // JSDoc /** True if node is of some JSDoc syntax kind. */ /* @internal */ function isJSDocNode(node) { return node.kind >= 271 /* FirstJSDocNode */ && node.kind <= 289 /* LastJSDocNode */; } ts.isJSDocNode = isJSDocNode; /** True if node is of a kind that may contain comment text. */ function isJSDocCommentContainingNode(node) { return node.kind === 279 /* JSDocComment */ || isJSDocTag(node); } ts.isJSDocCommentContainingNode = isJSDocCommentContainingNode; // TODO: determine what this does before making it public. /* @internal */ function isJSDocTag(node) { return node.kind >= 281 /* FirstJSDocTagNode */ && node.kind <= 289 /* LastJSDocTagNode */; } ts.isJSDocTag = isJSDocTag; function isSetAccessor(node) { return node.kind === 155 /* SetAccessor */; } ts.isSetAccessor = isSetAccessor; function isGetAccessor(node) { return node.kind === 154 /* GetAccessor */; } ts.isGetAccessor = isGetAccessor; /** True if has jsdoc nodes attached to it. */ /* @internal */ function hasJSDocNodes(node) { return !!node.jsDoc && node.jsDoc.length > 0; } ts.hasJSDocNodes = hasJSDocNodes; })(ts || (ts = {})); /// /// var ts; (function (ts) { /* @internal */ function tokenIsIdentifierOrKeyword(token) { return token >= 71 /* Identifier */; } ts.tokenIsIdentifierOrKeyword = tokenIsIdentifierOrKeyword; /* @internal */ function tokenIsIdentifierOrKeywordOrGreaterThan(token) { return token === 29 /* GreaterThanToken */ || tokenIsIdentifierOrKeyword(token); } ts.tokenIsIdentifierOrKeywordOrGreaterThan = tokenIsIdentifierOrKeywordOrGreaterThan; var textToToken = ts.createMapFromTemplate({ "abstract": 117 /* AbstractKeyword */, "any": 119 /* AnyKeyword */, "as": 118 /* AsKeyword */, "boolean": 122 /* BooleanKeyword */, "break": 72 /* BreakKeyword */, "case": 73 /* CaseKeyword */, "catch": 74 /* CatchKeyword */, "class": 75 /* ClassKeyword */, "continue": 77 /* ContinueKeyword */, "const": 76 /* ConstKeyword */, "constructor": 123 /* ConstructorKeyword */, "debugger": 78 /* DebuggerKeyword */, "declare": 124 /* DeclareKeyword */, "default": 79 /* DefaultKeyword */, "delete": 80 /* DeleteKeyword */, "do": 81 /* DoKeyword */, "else": 82 /* ElseKeyword */, "enum": 83 /* EnumKeyword */, "export": 84 /* ExportKeyword */, "extends": 85 /* ExtendsKeyword */, "false": 86 /* FalseKeyword */, "finally": 87 /* FinallyKeyword */, "for": 88 /* ForKeyword */, "from": 141 /* FromKeyword */, "function": 89 /* FunctionKeyword */, "get": 125 /* GetKeyword */, "if": 90 /* IfKeyword */, "implements": 108 /* ImplementsKeyword */, "import": 91 /* ImportKeyword */, "in": 92 /* InKeyword */, "instanceof": 93 /* InstanceOfKeyword */, "interface": 109 /* InterfaceKeyword */, "is": 126 /* IsKeyword */, "keyof": 127 /* KeyOfKeyword */, "let": 110 /* LetKeyword */, "module": 128 /* ModuleKeyword */, "namespace": 129 /* NamespaceKeyword */, "never": 130 /* NeverKeyword */, "new": 94 /* NewKeyword */, "null": 95 /* NullKeyword */, "number": 133 /* NumberKeyword */, "object": 134 /* ObjectKeyword */, "package": 111 /* PackageKeyword */, "private": 112 /* PrivateKeyword */, "protected": 113 /* ProtectedKeyword */, "public": 114 /* PublicKeyword */, "readonly": 131 /* ReadonlyKeyword */, "require": 132 /* RequireKeyword */, "global": 142 /* GlobalKeyword */, "return": 96 /* ReturnKeyword */, "set": 135 /* SetKeyword */, "static": 115 /* StaticKeyword */, "string": 136 /* StringKeyword */, "super": 97 /* SuperKeyword */, "switch": 98 /* SwitchKeyword */, "symbol": 137 /* SymbolKeyword */, "this": 99 /* ThisKeyword */, "throw": 100 /* ThrowKeyword */, "true": 101 /* TrueKeyword */, "try": 102 /* TryKeyword */, "type": 138 /* TypeKeyword */, "typeof": 103 /* TypeOfKeyword */, "undefined": 139 /* UndefinedKeyword */, "unique": 140 /* UniqueKeyword */, "var": 104 /* VarKeyword */, "void": 105 /* VoidKeyword */, "while": 106 /* WhileKeyword */, "with": 107 /* WithKeyword */, "yield": 116 /* YieldKeyword */, "async": 120 /* AsyncKeyword */, "await": 121 /* AwaitKeyword */, "of": 143 /* OfKeyword */, "{": 17 /* OpenBraceToken */, "}": 18 /* CloseBraceToken */, "(": 19 /* OpenParenToken */, ")": 20 /* CloseParenToken */, "[": 21 /* OpenBracketToken */, "]": 22 /* CloseBracketToken */, ".": 23 /* DotToken */, "...": 24 /* DotDotDotToken */, ";": 25 /* SemicolonToken */, ",": 26 /* CommaToken */, "<": 27 /* LessThanToken */, ">": 29 /* GreaterThanToken */, "<=": 30 /* LessThanEqualsToken */, ">=": 31 /* GreaterThanEqualsToken */, "==": 32 /* EqualsEqualsToken */, "!=": 33 /* ExclamationEqualsToken */, "===": 34 /* EqualsEqualsEqualsToken */, "!==": 35 /* ExclamationEqualsEqualsToken */, "=>": 36 /* EqualsGreaterThanToken */, "+": 37 /* PlusToken */, "-": 38 /* MinusToken */, "**": 40 /* AsteriskAsteriskToken */, "*": 39 /* AsteriskToken */, "/": 41 /* SlashToken */, "%": 42 /* PercentToken */, "++": 43 /* PlusPlusToken */, "--": 44 /* MinusMinusToken */, "<<": 45 /* LessThanLessThanToken */, ">": 46 /* GreaterThanGreaterThanToken */, ">>>": 47 /* GreaterThanGreaterThanGreaterThanToken */, "&": 48 /* AmpersandToken */, "|": 49 /* BarToken */, "^": 50 /* CaretToken */, "!": 51 /* ExclamationToken */, "~": 52 /* TildeToken */, "&&": 53 /* AmpersandAmpersandToken */, "||": 54 /* BarBarToken */, "?": 55 /* QuestionToken */, ":": 56 /* ColonToken */, "=": 58 /* EqualsToken */, "+=": 59 /* PlusEqualsToken */, "-=": 60 /* MinusEqualsToken */, "*=": 61 /* AsteriskEqualsToken */, "**=": 62 /* AsteriskAsteriskEqualsToken */, "/=": 63 /* SlashEqualsToken */, "%=": 64 /* PercentEqualsToken */, "<<=": 65 /* LessThanLessThanEqualsToken */, ">>=": 66 /* GreaterThanGreaterThanEqualsToken */, ">>>=": 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */, "&=": 68 /* AmpersandEqualsToken */, "|=": 69 /* BarEqualsToken */, "^=": 70 /* CaretEqualsToken */, "@": 57 /* AtToken */, }); /* As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers IdentifierStart :: Can contain Unicode 3.0.0 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), Modifier letter (Lm), Other letter (Lo), or Letter number (Nl). IdentifierPart :: = Can contain IdentifierStart + Unicode 3.0.0 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), or Connector punctuation (Pc). Codepoint ranges for ES3 Identifiers are extracted from the Unicode 3.0.0 specification at: http://www.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.txt */ var unicodeES3IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1610, 1649, 1747, 1749, 1749, 1765, 1766, 1786, 1788, 1808, 1808, 1810, 1836, 1920, 1957, 2309, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2784, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3294, 3294, 3296, 3297, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3424, 3425, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3805, 3840, 3840, 3904, 3911, 3913, 3946, 3976, 3979, 4096, 4129, 4131, 4135, 4137, 4138, 4176, 4181, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6067, 6176, 6263, 6272, 6312, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8319, 8319, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12346, 12353, 12436, 12445, 12446, 12449, 12538, 12540, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65138, 65140, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,]; var unicodeES3IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 543, 546, 563, 592, 685, 688, 696, 699, 705, 720, 721, 736, 740, 750, 750, 768, 846, 864, 866, 890, 890, 902, 902, 904, 906, 908, 908, 910, 929, 931, 974, 976, 983, 986, 1011, 1024, 1153, 1155, 1158, 1164, 1220, 1223, 1224, 1227, 1228, 1232, 1269, 1272, 1273, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1441, 1443, 1465, 1467, 1469, 1471, 1471, 1473, 1474, 1476, 1476, 1488, 1514, 1520, 1522, 1569, 1594, 1600, 1621, 1632, 1641, 1648, 1747, 1749, 1756, 1759, 1768, 1770, 1773, 1776, 1788, 1808, 1836, 1840, 1866, 1920, 1968, 2305, 2307, 2309, 2361, 2364, 2381, 2384, 2388, 2392, 2403, 2406, 2415, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2492, 2494, 2500, 2503, 2504, 2507, 2509, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2562, 2562, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2649, 2652, 2654, 2654, 2662, 2676, 2689, 2691, 2693, 2699, 2701, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2784, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2870, 2873, 2876, 2883, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2913, 2918, 2927, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 2997, 2999, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3031, 3031, 3047, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3134, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3168, 3169, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3262, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3297, 3302, 3311, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3368, 3370, 3385, 3390, 3395, 3398, 3400, 3402, 3405, 3415, 3415, 3424, 3425, 3430, 3439, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3805, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3946, 3953, 3972, 3974, 3979, 3984, 3991, 3993, 4028, 4038, 4038, 4096, 4129, 4131, 4135, 4137, 4138, 4140, 4146, 4150, 4153, 4160, 4169, 4176, 4185, 4256, 4293, 4304, 4342, 4352, 4441, 4447, 4514, 4520, 4601, 4608, 4614, 4616, 4678, 4680, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4742, 4744, 4744, 4746, 4749, 4752, 4782, 4784, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4814, 4816, 4822, 4824, 4846, 4848, 4878, 4880, 4880, 4882, 4885, 4888, 4894, 4896, 4934, 4936, 4954, 4969, 4977, 5024, 5108, 5121, 5740, 5743, 5750, 5761, 5786, 5792, 5866, 6016, 6099, 6112, 6121, 6160, 6169, 6176, 6263, 6272, 6313, 7680, 7835, 7840, 7929, 7936, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8255, 8256, 8319, 8319, 8400, 8412, 8417, 8417, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8497, 8499, 8505, 8544, 8579, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12346, 12353, 12436, 12441, 12442, 12445, 12446, 12449, 12542, 12549, 12588, 12593, 12686, 12704, 12727, 13312, 19893, 19968, 40869, 40960, 42124, 44032, 55203, 63744, 64045, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65056, 65059, 65075, 65076, 65101, 65103, 65136, 65138, 65140, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65381, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,]; /* As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers IdentifierStart :: Can contain Unicode 6.2 categories: Uppercase letter (Lu), Lowercase letter (Ll), Titlecase letter (Lt), Modifier letter (Lm), Other letter (Lo), or Letter number (Nl). IdentifierPart :: Can contain IdentifierStart + Unicode 6.2 categories: Non-spacing mark (Mn), Combining spacing mark (Mc), Decimal number (Nd), Connector punctuation (Pc), , or . Codepoint ranges for ES5 Identifiers are extracted from the Unicode 6.2 specification at: http://www.unicode.org/Public/6.2.0/ucd/UnicodeData.txt */ var unicodeES5IdentifierStart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 880, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1488, 1514, 1520, 1522, 1568, 1610, 1646, 1647, 1649, 1747, 1749, 1749, 1765, 1766, 1774, 1775, 1786, 1788, 1791, 1791, 1808, 1808, 1810, 1839, 1869, 1957, 1969, 1969, 1994, 2026, 2036, 2037, 2042, 2042, 2048, 2069, 2074, 2074, 2084, 2084, 2088, 2088, 2112, 2136, 2208, 2208, 2210, 2220, 2308, 2361, 2365, 2365, 2384, 2384, 2392, 2401, 2417, 2423, 2425, 2431, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2493, 2493, 2510, 2510, 2524, 2525, 2527, 2529, 2544, 2545, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2649, 2652, 2654, 2654, 2674, 2676, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2749, 2749, 2768, 2768, 2784, 2785, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2877, 2877, 2908, 2909, 2911, 2913, 2929, 2929, 2947, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3024, 3024, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3133, 3160, 3161, 3168, 3169, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3261, 3261, 3294, 3294, 3296, 3297, 3313, 3314, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3389, 3406, 3406, 3424, 3425, 3450, 3455, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3585, 3632, 3634, 3635, 3648, 3654, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3760, 3762, 3763, 3773, 3773, 3776, 3780, 3782, 3782, 3804, 3807, 3840, 3840, 3904, 3911, 3913, 3948, 3976, 3980, 4096, 4138, 4159, 4159, 4176, 4181, 4186, 4189, 4193, 4193, 4197, 4198, 4206, 4208, 4213, 4225, 4238, 4238, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5905, 5920, 5937, 5952, 5969, 5984, 5996, 5998, 6000, 6016, 6067, 6103, 6103, 6108, 6108, 6176, 6263, 6272, 6312, 6314, 6314, 6320, 6389, 6400, 6428, 6480, 6509, 6512, 6516, 6528, 6571, 6593, 6599, 6656, 6678, 6688, 6740, 6823, 6823, 6917, 6963, 6981, 6987, 7043, 7072, 7086, 7087, 7098, 7141, 7168, 7203, 7245, 7247, 7258, 7293, 7401, 7404, 7406, 7409, 7413, 7414, 7424, 7615, 7680, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8305, 8305, 8319, 8319, 8336, 8348, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11502, 11506, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11648, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11823, 11823, 12293, 12295, 12321, 12329, 12337, 12341, 12344, 12348, 12353, 12438, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42527, 42538, 42539, 42560, 42606, 42623, 42647, 42656, 42735, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43009, 43011, 43013, 43015, 43018, 43020, 43042, 43072, 43123, 43138, 43187, 43250, 43255, 43259, 43259, 43274, 43301, 43312, 43334, 43360, 43388, 43396, 43442, 43471, 43471, 43520, 43560, 43584, 43586, 43588, 43595, 43616, 43638, 43642, 43642, 43648, 43695, 43697, 43697, 43701, 43702, 43705, 43709, 43712, 43712, 43714, 43714, 43739, 43741, 43744, 43754, 43762, 43764, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44002, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64285, 64287, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65136, 65140, 65142, 65276, 65313, 65338, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,]; var unicodeES5IdentifierPart = [170, 170, 181, 181, 186, 186, 192, 214, 216, 246, 248, 705, 710, 721, 736, 740, 748, 748, 750, 750, 768, 884, 886, 887, 890, 893, 902, 902, 904, 906, 908, 908, 910, 929, 931, 1013, 1015, 1153, 1155, 1159, 1162, 1319, 1329, 1366, 1369, 1369, 1377, 1415, 1425, 1469, 1471, 1471, 1473, 1474, 1476, 1477, 1479, 1479, 1488, 1514, 1520, 1522, 1552, 1562, 1568, 1641, 1646, 1747, 1749, 1756, 1759, 1768, 1770, 1788, 1791, 1791, 1808, 1866, 1869, 1969, 1984, 2037, 2042, 2042, 2048, 2093, 2112, 2139, 2208, 2208, 2210, 2220, 2276, 2302, 2304, 2403, 2406, 2415, 2417, 2423, 2425, 2431, 2433, 2435, 2437, 2444, 2447, 2448, 2451, 2472, 2474, 2480, 2482, 2482, 2486, 2489, 2492, 2500, 2503, 2504, 2507, 2510, 2519, 2519, 2524, 2525, 2527, 2531, 2534, 2545, 2561, 2563, 2565, 2570, 2575, 2576, 2579, 2600, 2602, 2608, 2610, 2611, 2613, 2614, 2616, 2617, 2620, 2620, 2622, 2626, 2631, 2632, 2635, 2637, 2641, 2641, 2649, 2652, 2654, 2654, 2662, 2677, 2689, 2691, 2693, 2701, 2703, 2705, 2707, 2728, 2730, 2736, 2738, 2739, 2741, 2745, 2748, 2757, 2759, 2761, 2763, 2765, 2768, 2768, 2784, 2787, 2790, 2799, 2817, 2819, 2821, 2828, 2831, 2832, 2835, 2856, 2858, 2864, 2866, 2867, 2869, 2873, 2876, 2884, 2887, 2888, 2891, 2893, 2902, 2903, 2908, 2909, 2911, 2915, 2918, 2927, 2929, 2929, 2946, 2947, 2949, 2954, 2958, 2960, 2962, 2965, 2969, 2970, 2972, 2972, 2974, 2975, 2979, 2980, 2984, 2986, 2990, 3001, 3006, 3010, 3014, 3016, 3018, 3021, 3024, 3024, 3031, 3031, 3046, 3055, 3073, 3075, 3077, 3084, 3086, 3088, 3090, 3112, 3114, 3123, 3125, 3129, 3133, 3140, 3142, 3144, 3146, 3149, 3157, 3158, 3160, 3161, 3168, 3171, 3174, 3183, 3202, 3203, 3205, 3212, 3214, 3216, 3218, 3240, 3242, 3251, 3253, 3257, 3260, 3268, 3270, 3272, 3274, 3277, 3285, 3286, 3294, 3294, 3296, 3299, 3302, 3311, 3313, 3314, 3330, 3331, 3333, 3340, 3342, 3344, 3346, 3386, 3389, 3396, 3398, 3400, 3402, 3406, 3415, 3415, 3424, 3427, 3430, 3439, 3450, 3455, 3458, 3459, 3461, 3478, 3482, 3505, 3507, 3515, 3517, 3517, 3520, 3526, 3530, 3530, 3535, 3540, 3542, 3542, 3544, 3551, 3570, 3571, 3585, 3642, 3648, 3662, 3664, 3673, 3713, 3714, 3716, 3716, 3719, 3720, 3722, 3722, 3725, 3725, 3732, 3735, 3737, 3743, 3745, 3747, 3749, 3749, 3751, 3751, 3754, 3755, 3757, 3769, 3771, 3773, 3776, 3780, 3782, 3782, 3784, 3789, 3792, 3801, 3804, 3807, 3840, 3840, 3864, 3865, 3872, 3881, 3893, 3893, 3895, 3895, 3897, 3897, 3902, 3911, 3913, 3948, 3953, 3972, 3974, 3991, 3993, 4028, 4038, 4038, 4096, 4169, 4176, 4253, 4256, 4293, 4295, 4295, 4301, 4301, 4304, 4346, 4348, 4680, 4682, 4685, 4688, 4694, 4696, 4696, 4698, 4701, 4704, 4744, 4746, 4749, 4752, 4784, 4786, 4789, 4792, 4798, 4800, 4800, 4802, 4805, 4808, 4822, 4824, 4880, 4882, 4885, 4888, 4954, 4957, 4959, 4992, 5007, 5024, 5108, 5121, 5740, 5743, 5759, 5761, 5786, 5792, 5866, 5870, 5872, 5888, 5900, 5902, 5908, 5920, 5940, 5952, 5971, 5984, 5996, 5998, 6000, 6002, 6003, 6016, 6099, 6103, 6103, 6108, 6109, 6112, 6121, 6155, 6157, 6160, 6169, 6176, 6263, 6272, 6314, 6320, 6389, 6400, 6428, 6432, 6443, 6448, 6459, 6470, 6509, 6512, 6516, 6528, 6571, 6576, 6601, 6608, 6617, 6656, 6683, 6688, 6750, 6752, 6780, 6783, 6793, 6800, 6809, 6823, 6823, 6912, 6987, 6992, 7001, 7019, 7027, 7040, 7155, 7168, 7223, 7232, 7241, 7245, 7293, 7376, 7378, 7380, 7414, 7424, 7654, 7676, 7957, 7960, 7965, 7968, 8005, 8008, 8013, 8016, 8023, 8025, 8025, 8027, 8027, 8029, 8029, 8031, 8061, 8064, 8116, 8118, 8124, 8126, 8126, 8130, 8132, 8134, 8140, 8144, 8147, 8150, 8155, 8160, 8172, 8178, 8180, 8182, 8188, 8204, 8205, 8255, 8256, 8276, 8276, 8305, 8305, 8319, 8319, 8336, 8348, 8400, 8412, 8417, 8417, 8421, 8432, 8450, 8450, 8455, 8455, 8458, 8467, 8469, 8469, 8473, 8477, 8484, 8484, 8486, 8486, 8488, 8488, 8490, 8493, 8495, 8505, 8508, 8511, 8517, 8521, 8526, 8526, 8544, 8584, 11264, 11310, 11312, 11358, 11360, 11492, 11499, 11507, 11520, 11557, 11559, 11559, 11565, 11565, 11568, 11623, 11631, 11631, 11647, 11670, 11680, 11686, 11688, 11694, 11696, 11702, 11704, 11710, 11712, 11718, 11720, 11726, 11728, 11734, 11736, 11742, 11744, 11775, 11823, 11823, 12293, 12295, 12321, 12335, 12337, 12341, 12344, 12348, 12353, 12438, 12441, 12442, 12445, 12447, 12449, 12538, 12540, 12543, 12549, 12589, 12593, 12686, 12704, 12730, 12784, 12799, 13312, 19893, 19968, 40908, 40960, 42124, 42192, 42237, 42240, 42508, 42512, 42539, 42560, 42607, 42612, 42621, 42623, 42647, 42655, 42737, 42775, 42783, 42786, 42888, 42891, 42894, 42896, 42899, 42912, 42922, 43000, 43047, 43072, 43123, 43136, 43204, 43216, 43225, 43232, 43255, 43259, 43259, 43264, 43309, 43312, 43347, 43360, 43388, 43392, 43456, 43471, 43481, 43520, 43574, 43584, 43597, 43600, 43609, 43616, 43638, 43642, 43643, 43648, 43714, 43739, 43741, 43744, 43759, 43762, 43766, 43777, 43782, 43785, 43790, 43793, 43798, 43808, 43814, 43816, 43822, 43968, 44010, 44012, 44013, 44016, 44025, 44032, 55203, 55216, 55238, 55243, 55291, 63744, 64109, 64112, 64217, 64256, 64262, 64275, 64279, 64285, 64296, 64298, 64310, 64312, 64316, 64318, 64318, 64320, 64321, 64323, 64324, 64326, 64433, 64467, 64829, 64848, 64911, 64914, 64967, 65008, 65019, 65024, 65039, 65056, 65062, 65075, 65076, 65101, 65103, 65136, 65140, 65142, 65276, 65296, 65305, 65313, 65338, 65343, 65343, 65345, 65370, 65382, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500,]; function lookupInUnicodeMap(code, map) { // Bail out quickly if it couldn't possibly be in the map. if (code < map[0]) { return false; } // Perform binary search in one of the Unicode range maps var lo = 0; var hi = map.length; var mid; while (lo + 1 < hi) { mid = lo + (hi - lo) / 2; // mid has to be even to catch a range's beginning mid -= mid % 2; if (map[mid] <= code && code <= map[mid + 1]) { return true; } if (code < map[mid]) { hi = mid; } else { lo = mid + 2; } } return false; } /* @internal */ function isUnicodeIdentifierStart(code, languageVersion) { return languageVersion >= 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierStart) : lookupInUnicodeMap(code, unicodeES3IdentifierStart); } ts.isUnicodeIdentifierStart = isUnicodeIdentifierStart; function isUnicodeIdentifierPart(code, languageVersion) { return languageVersion >= 1 /* ES5 */ ? lookupInUnicodeMap(code, unicodeES5IdentifierPart) : lookupInUnicodeMap(code, unicodeES3IdentifierPart); } function makeReverseMap(source) { var result = []; source.forEach(function (value, name) { result[value] = name; }); return result; } var tokenStrings = makeReverseMap(textToToken); function tokenToString(t) { return tokenStrings[t]; } ts.tokenToString = tokenToString; /* @internal */ function stringToToken(s) { return textToToken.get(s); } ts.stringToToken = stringToToken; /* @internal */ function computeLineStarts(text) { var result = new Array(); var pos = 0; var lineStart = 0; while (pos < text.length) { var ch = text.charCodeAt(pos); pos++; switch (ch) { case 13 /* carriageReturn */: if (text.charCodeAt(pos) === 10 /* lineFeed */) { pos++; } // falls through case 10 /* lineFeed */: result.push(lineStart); lineStart = pos; break; default: if (ch > 127 /* maxAsciiCharacter */ && isLineBreak(ch)) { result.push(lineStart); lineStart = pos; } break; } } result.push(lineStart); return result; } ts.computeLineStarts = computeLineStarts; function getPositionOfLineAndCharacter(sourceFile, line, character) { return computePositionOfLineAndCharacter(getLineStarts(sourceFile), line, character, sourceFile.text); } ts.getPositionOfLineAndCharacter = getPositionOfLineAndCharacter; /* @internal */ function computePositionOfLineAndCharacter(lineStarts, line, character, debugText) { ts.Debug.assert(line >= 0 && line < lineStarts.length); var res = lineStarts[line] + character; if (line < lineStarts.length - 1) { ts.Debug.assert(res < lineStarts[line + 1]); } else if (debugText !== undefined) { ts.Debug.assert(res <= debugText.length); // Allow single character overflow for trailing newline } return res; } ts.computePositionOfLineAndCharacter = computePositionOfLineAndCharacter; /* @internal */ function getLineStarts(sourceFile) { return sourceFile.lineMap || (sourceFile.lineMap = computeLineStarts(sourceFile.text)); } ts.getLineStarts = getLineStarts; /* @internal */ /** * We assume the first line starts at position 0 and 'position' is non-negative. */ function computeLineAndCharacterOfPosition(lineStarts, position) { var lineNumber = ts.binarySearch(lineStarts, position, ts.identity, ts.compareValues); if (lineNumber < 0) { // If the actual position was not found, // the binary search returns the 2's-complement of the next line start // e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20 // then the search will return -2. // // We want the index of the previous line start, so we subtract 1. // Review 2's-complement if this is confusing. lineNumber = ~lineNumber - 1; ts.Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file"); } return { line: lineNumber, character: position - lineStarts[lineNumber] }; } ts.computeLineAndCharacterOfPosition = computeLineAndCharacterOfPosition; function getLineAndCharacterOfPosition(sourceFile, position) { return computeLineAndCharacterOfPosition(getLineStarts(sourceFile), position); } ts.getLineAndCharacterOfPosition = getLineAndCharacterOfPosition; function isWhiteSpaceLike(ch) { return isWhiteSpaceSingleLine(ch) || isLineBreak(ch); } ts.isWhiteSpaceLike = isWhiteSpaceLike; /** Does not include line breaks. For that, see isWhiteSpaceLike. */ function isWhiteSpaceSingleLine(ch) { // Note: nextLine is in the Zs space, and should be considered to be a whitespace. // It is explicitly not a line-break as it isn't in the exact set specified by EcmaScript. return ch === 32 /* space */ || ch === 9 /* tab */ || ch === 11 /* verticalTab */ || ch === 12 /* formFeed */ || ch === 160 /* nonBreakingSpace */ || ch === 133 /* nextLine */ || ch === 5760 /* ogham */ || ch >= 8192 /* enQuad */ && ch <= 8203 /* zeroWidthSpace */ || ch === 8239 /* narrowNoBreakSpace */ || ch === 8287 /* mathematicalSpace */ || ch === 12288 /* ideographicSpace */ || ch === 65279 /* byteOrderMark */; } ts.isWhiteSpaceSingleLine = isWhiteSpaceSingleLine; function isLineBreak(ch) { // ES5 7.3: // The ECMAScript line terminator characters are listed in Table 3. // Table 3: Line Terminator Characters // Code Unit Value Name Formal Name // \u000A Line Feed // \u000D Carriage Return // \u2028 Line separator // \u2029 Paragraph separator // Only the characters in Table 3 are treated as line terminators. Other new line or line // breaking characters are treated as white space but not as line terminators. return ch === 10 /* lineFeed */ || ch === 13 /* carriageReturn */ || ch === 8232 /* lineSeparator */ || ch === 8233 /* paragraphSeparator */; } ts.isLineBreak = isLineBreak; function isDigit(ch) { return ch >= 48 /* _0 */ && ch <= 57 /* _9 */; } /* @internal */ function isOctalDigit(ch) { return ch >= 48 /* _0 */ && ch <= 55 /* _7 */; } ts.isOctalDigit = isOctalDigit; function couldStartTrivia(text, pos) { // Keep in sync with skipTrivia var ch = text.charCodeAt(pos); switch (ch) { case 13 /* carriageReturn */: case 10 /* lineFeed */: case 9 /* tab */: case 11 /* verticalTab */: case 12 /* formFeed */: case 32 /* space */: case 47 /* slash */: // starts of normal trivia case 60 /* lessThan */: case 124 /* bar */: case 61 /* equals */: case 62 /* greaterThan */: // Starts of conflict marker trivia return true; case 35 /* hash */: // Only if its the beginning can we have #! trivia return pos === 0; default: return ch > 127 /* maxAsciiCharacter */; } } ts.couldStartTrivia = couldStartTrivia; /* @internal */ function skipTrivia(text, pos, stopAfterLineBreak, stopAtComments) { if (stopAtComments === void 0) { stopAtComments = false; } if (ts.positionIsSynthesized(pos)) { return pos; } // Keep in sync with couldStartTrivia while (true) { var ch = text.charCodeAt(pos); switch (ch) { case 13 /* carriageReturn */: if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) { pos++; } // falls through case 10 /* lineFeed */: pos++; if (stopAfterLineBreak) { return pos; } continue; case 9 /* tab */: case 11 /* verticalTab */: case 12 /* formFeed */: case 32 /* space */: pos++; continue; case 47 /* slash */: if (stopAtComments) { break; } if (text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; while (pos < text.length) { if (isLineBreak(text.charCodeAt(pos))) { break; } pos++; } continue; } if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { pos += 2; while (pos < text.length) { if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; break; } pos++; } continue; } break; case 60 /* lessThan */: case 124 /* bar */: case 61 /* equals */: case 62 /* greaterThan */: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos); continue; } break; case 35 /* hash */: if (pos === 0 && isShebangTrivia(text, pos)) { pos = scanShebangTrivia(text, pos); continue; } break; default: if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) { pos++; continue; } break; } return pos; } } ts.skipTrivia = skipTrivia; // All conflict markers consist of the same character repeated seven times. If it is // a <<<<<<< or >>>>>>> marker then it is also followed by a space. var mergeConflictMarkerLength = "<<<<<<<".length; function isConflictMarkerTrivia(text, pos) { ts.Debug.assert(pos >= 0); // Conflict markers must be at the start of a line. if (pos === 0 || isLineBreak(text.charCodeAt(pos - 1))) { var ch = text.charCodeAt(pos); if ((pos + mergeConflictMarkerLength) < text.length) { for (var i = 0; i < mergeConflictMarkerLength; i++) { if (text.charCodeAt(pos + i) !== ch) { return false; } } return ch === 61 /* equals */ || text.charCodeAt(pos + mergeConflictMarkerLength) === 32 /* space */; } } return false; } function scanConflictMarkerTrivia(text, pos, error) { if (error) { error(ts.Diagnostics.Merge_conflict_marker_encountered, mergeConflictMarkerLength); } var ch = text.charCodeAt(pos); var len = text.length; if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) { while (pos < len && !isLineBreak(text.charCodeAt(pos))) { pos++; } } else { ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */); // Consume everything from the start of a ||||||| or ======= marker to the start // of the next ======= or >>>>>>> marker. while (pos < len) { var currentChar = text.charCodeAt(pos); if ((currentChar === 61 /* equals */ || currentChar === 62 /* greaterThan */) && currentChar !== ch && isConflictMarkerTrivia(text, pos)) { break; } pos++; } } return pos; } var shebangTriviaRegex = /^#!.*/; function isShebangTrivia(text, pos) { // Shebangs check must only be done at the start of the file ts.Debug.assert(pos === 0); return shebangTriviaRegex.test(text); } function scanShebangTrivia(text, pos) { var shebang = shebangTriviaRegex.exec(text)[0]; pos = pos + shebang.length; return pos; } /** * Invokes a callback for each comment range following the provided position. * * Single-line comment ranges include the leading double-slash characters but not the ending * line break. Multi-line comment ranges include the leading slash-asterisk and trailing * asterisk-slash characters. * * @param reduce If true, accumulates the result of calling the callback in a fashion similar * to reduceLeft. If false, iteration stops when the callback returns a truthy value. * @param text The source text to scan. * @param pos The position at which to start scanning. * @param trailing If false, whitespace is skipped until the first line break and comments * between that location and the next token are returned. If true, comments occurring * between the given position and the next line break are returned. * @param cb The callback to execute as each comment range is encountered. * @param state A state value to pass to each iteration of the callback. * @param initial An initial value to pass when accumulating results (when "reduce" is true). * @returns If "reduce" is true, the accumulated value. If "reduce" is false, the first truthy * return value of the callback. */ function iterateCommentRanges(reduce, text, pos, trailing, cb, state, initial) { var pendingPos; var pendingEnd; var pendingKind; var pendingHasTrailingNewLine; var hasPendingCommentRange = false; var collecting = trailing || pos === 0; var accumulator = initial; scan: while (pos >= 0 && pos < text.length) { var ch = text.charCodeAt(pos); switch (ch) { case 13 /* carriageReturn */: if (text.charCodeAt(pos + 1) === 10 /* lineFeed */) { pos++; } // falls through case 10 /* lineFeed */: pos++; if (trailing) { break scan; } collecting = true; if (hasPendingCommentRange) { pendingHasTrailingNewLine = true; } continue; case 9 /* tab */: case 11 /* verticalTab */: case 12 /* formFeed */: case 32 /* space */: pos++; continue; case 47 /* slash */: var nextChar = text.charCodeAt(pos + 1); var hasTrailingNewLine = false; if (nextChar === 47 /* slash */ || nextChar === 42 /* asterisk */) { var kind = nextChar === 47 /* slash */ ? 2 /* SingleLineCommentTrivia */ : 3 /* MultiLineCommentTrivia */; var startPos = pos; pos += 2; if (nextChar === 47 /* slash */) { while (pos < text.length) { if (isLineBreak(text.charCodeAt(pos))) { hasTrailingNewLine = true; break; } pos++; } } else { while (pos < text.length) { if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; break; } pos++; } } if (collecting) { if (hasPendingCommentRange) { accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator); if (!reduce && accumulator) { // If we are not reducing and we have a truthy result, return it. return accumulator; } hasPendingCommentRange = false; } pendingPos = startPos; pendingEnd = pos; pendingKind = kind; pendingHasTrailingNewLine = hasTrailingNewLine; hasPendingCommentRange = true; } continue; } break scan; default: if (ch > 127 /* maxAsciiCharacter */ && (isWhiteSpaceLike(ch))) { if (hasPendingCommentRange && isLineBreak(ch)) { pendingHasTrailingNewLine = true; } pos++; continue; } break scan; } } if (hasPendingCommentRange) { accumulator = cb(pendingPos, pendingEnd, pendingKind, pendingHasTrailingNewLine, state, accumulator); } return accumulator; } function forEachLeadingCommentRange(text, pos, cb, state) { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ false, cb, state); } ts.forEachLeadingCommentRange = forEachLeadingCommentRange; function forEachTrailingCommentRange(text, pos, cb, state) { return iterateCommentRanges(/*reduce*/ false, text, pos, /*trailing*/ true, cb, state); } ts.forEachTrailingCommentRange = forEachTrailingCommentRange; function reduceEachLeadingCommentRange(text, pos, cb, state, initial) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ false, cb, state, initial); } ts.reduceEachLeadingCommentRange = reduceEachLeadingCommentRange; function reduceEachTrailingCommentRange(text, pos, cb, state, initial) { return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial); } ts.reduceEachTrailingCommentRange = reduceEachTrailingCommentRange; function appendCommentRange(pos, end, kind, hasTrailingNewLine, _state, comments) { if (!comments) { comments = []; } comments.push({ kind: kind, pos: pos, end: end, hasTrailingNewLine: hasTrailingNewLine }); return comments; } function getLeadingCommentRanges(text, pos) { return reduceEachLeadingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } ts.getLeadingCommentRanges = getLeadingCommentRanges; function getTrailingCommentRanges(text, pos) { return reduceEachTrailingCommentRange(text, pos, appendCommentRange, /*state*/ undefined, /*initial*/ undefined); } ts.getTrailingCommentRanges = getTrailingCommentRanges; /** Optionally, get the shebang */ function getShebang(text) { var match = shebangTriviaRegex.exec(text); if (match) { return match[0]; } } ts.getShebang = getShebang; function isIdentifierStart(ch, languageVersion) { return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierStart(ch, languageVersion); } ts.isIdentifierStart = isIdentifierStart; function isIdentifierPart(ch, languageVersion) { return ch >= 65 /* A */ && ch <= 90 /* Z */ || ch >= 97 /* a */ && ch <= 122 /* z */ || ch >= 48 /* _0 */ && ch <= 57 /* _9 */ || ch === 36 /* $ */ || ch === 95 /* _ */ || ch > 127 /* maxAsciiCharacter */ && isUnicodeIdentifierPart(ch, languageVersion); } ts.isIdentifierPart = isIdentifierPart; /* @internal */ function isIdentifierText(name, languageVersion) { if (!isIdentifierStart(name.charCodeAt(0), languageVersion)) { return false; } for (var i = 1; i < name.length; i++) { if (!isIdentifierPart(name.charCodeAt(i), languageVersion)) { return false; } } return true; } ts.isIdentifierText = isIdentifierText; // Creates a scanner over a (possibly unspecified) range of a piece of text. function createScanner(languageVersion, skipTrivia, languageVariant, text, onError, start, length) { if (languageVariant === void 0) { languageVariant = 0 /* Standard */; } // Current position (end position of text of current token) var pos; // end of text var end; // Start position of whitespace before current token var startPos; // Start position of text of current token var tokenPos; var token; var tokenValue; var tokenFlags; 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 (tokenFlags & 8 /* ExtendedUnicodeEscape */) !== 0; }, hasPrecedingLineBreak: function () { return (tokenFlags & 1 /* PrecedingLineBreak */) !== 0; }, isIdentifier: function () { return token === 71 /* Identifier */ || token > 107 /* LastReservedWord */; }, isReservedWord: function () { return token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */; }, isUnterminated: function () { return (tokenFlags & 4 /* Unterminated */) !== 0; }, getTokenFlags: function () { return tokenFlags; }, reScanGreaterToken: reScanGreaterToken, reScanSlashToken: reScanSlashToken, reScanTemplateToken: reScanTemplateToken, scanJsxIdentifier: scanJsxIdentifier, scanJsxAttributeValue: scanJsxAttributeValue, reScanJsxToken: reScanJsxToken, scanJsxToken: scanJsxToken, scanJSDocToken: scanJSDocToken, scan: scan, getText: getText, setText: setText, setScriptTarget: setScriptTarget, setLanguageVariant: setLanguageVariant, setOnError: setOnError, setTextPos: setTextPos, tryScan: tryScan, lookAhead: lookAhead, scanRange: scanRange, }; function error(message, length) { if (onError) { onError(message, length || 0); } } function scanNumber() { var start = pos; while (isDigit(text.charCodeAt(pos))) pos++; if (text.charCodeAt(pos) === 46 /* dot */) { pos++; while (isDigit(text.charCodeAt(pos))) pos++; } var end = pos; if (text.charCodeAt(pos) === 69 /* E */ || text.charCodeAt(pos) === 101 /* e */) { pos++; tokenFlags |= 16 /* Scientific */; if (text.charCodeAt(pos) === 43 /* plus */ || text.charCodeAt(pos) === 45 /* minus */) pos++; if (isDigit(text.charCodeAt(pos))) { pos++; while (isDigit(text.charCodeAt(pos))) pos++; end = pos; } else { error(ts.Diagnostics.Digit_expected); } } return "" + +(text.substring(start, end)); } function scanOctalDigits() { var start = pos; while (isOctalDigit(text.charCodeAt(pos))) { pos++; } return +(text.substring(start, pos)); } /** * Scans the given number of hexadecimal digits in the text, * returning -1 if the given number is unavailable. */ function scanExactNumberOfHexDigits(count) { return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false); } /** * Scans as many hexadecimal digits as are available in the text, * returning -1 if the given number of digits was unavailable. */ function scanMinimumNumberOfHexDigits(count) { return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true); } function scanHexDigits(minCount, scanAsManyAsPossible) { var digits = 0; var value = 0; while (digits < minCount || scanAsManyAsPossible) { var ch = text.charCodeAt(pos); if (ch >= 48 /* _0 */ && ch <= 57 /* _9 */) { value = value * 16 + ch - 48 /* _0 */; } else if (ch >= 65 /* A */ && ch <= 70 /* F */) { value = value * 16 + ch - 65 /* A */ + 10; } else if (ch >= 97 /* a */ && ch <= 102 /* f */) { value = value * 16 + ch - 97 /* a */ + 10; } else { break; } pos++; digits++; } if (digits < minCount) { value = -1; } return value; } function scanString(jsxAttributeString) { if (jsxAttributeString === void 0) { jsxAttributeString = false; } var quote = text.charCodeAt(pos); pos++; var result = ""; var start = pos; while (true) { if (pos >= end) { result += text.substring(start, pos); tokenFlags |= 4 /* Unterminated */; 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 */ && !jsxAttributeString) { result += text.substring(start, pos); result += scanEscapeSequence(); start = pos; continue; } if (isLineBreak(ch) && !jsxAttributeString) { result += text.substring(start, pos); tokenFlags |= 4 /* Unterminated */; 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); tokenFlags |= 4 /* Unterminated */; error(ts.Diagnostics.Unterminated_template_literal); resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */; break; } var currChar = text.charCodeAt(pos); // '`' if (currChar === 96 /* backtick */) { contents += text.substring(start, pos); pos++; resultingToken = startedWithBacktick ? 13 /* NoSubstitutionTemplateLiteral */ : 16 /* TemplateTail */; break; } // '${' if (currChar === 36 /* $ */ && pos + 1 < end && text.charCodeAt(pos + 1) === 123 /* openBrace */) { contents += text.substring(start, pos); pos += 2; resultingToken = startedWithBacktick ? 14 /* TemplateHead */ : 15 /* TemplateMiddle */; break; } // Escape character if (currChar === 92 /* backslash */) { contents += text.substring(start, pos); contents += scanEscapeSequence(); start = pos; continue; } // Speculated ECMAScript 6 Spec 11.8.6.1: // and LineTerminatorSequences are normalized to 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 */) { tokenFlags |= 8 /* ExtendedUnicodeEscape */; pos++; return scanExtendedUnicodeEscape(); } // '\uDDDD' return scanHexadecimalEscape(/*numDigits*/ 4); case 120 /* x */: // '\xDD' return scanHexadecimalEscape(/*numDigits*/ 2); // when encountering a LineContinuation (i.e. a backslash and a line terminator sequence), // the line terminator is interpreted to be "the empty code unit sequence". case 13 /* carriageReturn */: if (pos < end && text.charCodeAt(pos) === 10 /* lineFeed */) { pos++; } // falls through case 10 /* lineFeed */: case 8232 /* lineSeparator */: case 8233 /* paragraphSeparator */: return ""; default: return String.fromCharCode(ch); } } function scanHexadecimalEscape(numDigits) { var escapedValue = scanExactNumberOfHexDigits(numDigits); if (escapedValue >= 0) { return String.fromCharCode(escapedValue); } else { error(ts.Diagnostics.Hexadecimal_digit_expected); return ""; } } function scanExtendedUnicodeEscape() { var escapedValue = scanMinimumNumberOfHexDigits(1); var isInvalidExtendedEscape = false; // Validate the value of the digit if (escapedValue < 0) { error(ts.Diagnostics.Hexadecimal_digit_expected); isInvalidExtendedEscape = true; } else if (escapedValue > 0x10FFFF) { error(ts.Diagnostics.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive); isInvalidExtendedEscape = true; } if (pos >= end) { error(ts.Diagnostics.Unexpected_end_of_text); isInvalidExtendedEscape = true; } else if (text.charCodeAt(pos) === 125 /* closeBrace */) { // Only swallow the following character up if it's a '}'. pos++; } else { error(ts.Diagnostics.Unterminated_Unicode_escape_sequence); isInvalidExtendedEscape = true; } if (isInvalidExtendedEscape) { return ""; } return utf16EncodeAsString(escapedValue); } // Derived from the 10.1.1 UTF16Encoding of the ES6 Spec. function utf16EncodeAsString(codePoint) { ts.Debug.assert(0x0 <= codePoint && codePoint <= 0x10FFFF); if (codePoint <= 65535) { return String.fromCharCode(codePoint); } var codeUnit1 = Math.floor((codePoint - 65536) / 1024) + 0xD800; var codeUnit2 = ((codePoint - 65536) % 1024) + 0xDC00; return String.fromCharCode(codeUnit1, codeUnit2); } // Current character is known to be a backslash. Check for Unicode escape of the form '\uXXXX' // and return code point value if valid Unicode escape is found. Otherwise return -1. function peekUnicodeEscape() { if (pos + 5 < end && text.charCodeAt(pos + 1) === 117 /* u */) { var start_1 = pos; pos += 2; var value = scanExactNumberOfHexDigits(4); pos = start_1; return value; } return -1; } function scanIdentifierParts() { var result = ""; var start = pos; while (pos < end) { var ch = text.charCodeAt(pos); if (isIdentifierPart(ch, languageVersion)) { pos++; } else if (ch === 92 /* backslash */) { ch = peekUnicodeEscape(); if (!(ch >= 0 && isIdentifierPart(ch, languageVersion))) { break; } result += text.substring(start, pos); result += String.fromCharCode(ch); // Valid Unicode escape is always six characters pos += 6; start = pos; } else { break; } } result += text.substring(start, pos); return result; } function getIdentifierToken() { // Reserved words are between 2 and 11 characters long and start with a lowercase letter var len = tokenValue.length; if (len >= 2 && len <= 11) { var ch = tokenValue.charCodeAt(0); if (ch >= 97 /* a */ && ch <= 122 /* z */) { token = textToToken.get(tokenValue); if (token !== undefined) { return token; } } } return token = 71 /* Identifier */; } function scanBinaryOrOctalDigits(base) { ts.Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8"); var value = 0; // For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b. // Similarly valid octalIntegerLiteral must have at least one octal digit following o or O. var numberOfDigits = 0; while (true) { var ch = text.charCodeAt(pos); var valueOfCh = ch - 48 /* _0 */; if (!isDigit(ch) || valueOfCh >= base) { break; } value = value * base + valueOfCh; pos++; numberOfDigits++; } // Invalid binaryIntegerLiteral or octalIntegerLiteral if (numberOfDigits === 0) { return -1; } return value; } function scan() { startPos = pos; tokenFlags = 0; while (true) { tokenPos = pos; if (pos >= end) { return token = 1 /* EndOfFileToken */; } var ch = text.charCodeAt(pos); // Special handling for shebang if (ch === 35 /* hash */ && pos === 0 && isShebangTrivia(text, pos)) { pos = scanShebangTrivia(text, pos); if (skipTrivia) { continue; } else { return token = 6 /* ShebangTrivia */; } } switch (ch) { case 10 /* lineFeed */: case 13 /* carriageReturn */: tokenFlags |= 1 /* PrecedingLineBreak */; if (skipTrivia) { pos++; continue; } else { if (ch === 13 /* carriageReturn */ && pos + 1 < end && text.charCodeAt(pos + 1) === 10 /* lineFeed */) { // consume both CR and LF pos += 2; } else { pos++; } return token = 4 /* NewLineTrivia */; } case 9 /* tab */: case 11 /* verticalTab */: case 12 /* formFeed */: case 32 /* space */: if (skipTrivia) { pos++; continue; } else { while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { pos++; } return token = 5 /* WhitespaceTrivia */; } case 33 /* exclamation */: if (text.charCodeAt(pos + 1) === 61 /* equals */) { if (text.charCodeAt(pos + 2) === 61 /* equals */) { return pos += 3, token = 35 /* ExclamationEqualsEqualsToken */; } return pos += 2, token = 33 /* ExclamationEqualsToken */; } pos++; return token = 51 /* ExclamationToken */; case 34 /* doubleQuote */: case 39 /* singleQuote */: tokenValue = scanString(); return token = 9 /* StringLiteral */; case 96 /* backtick */: return token = scanTemplateAndSetTokenValue(); case 37 /* percent */: if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 64 /* PercentEqualsToken */; } pos++; return token = 42 /* PercentToken */; case 38 /* ampersand */: if (text.charCodeAt(pos + 1) === 38 /* ampersand */) { return pos += 2, token = 53 /* AmpersandAmpersandToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 68 /* AmpersandEqualsToken */; } pos++; return token = 48 /* AmpersandToken */; case 40 /* openParen */: pos++; return token = 19 /* OpenParenToken */; case 41 /* closeParen */: pos++; return token = 20 /* CloseParenToken */; case 42 /* asterisk */: if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 61 /* AsteriskEqualsToken */; } if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { if (text.charCodeAt(pos + 2) === 61 /* equals */) { return pos += 3, token = 62 /* AsteriskAsteriskEqualsToken */; } return pos += 2, token = 40 /* AsteriskAsteriskToken */; } pos++; return token = 39 /* AsteriskToken */; case 43 /* plus */: if (text.charCodeAt(pos + 1) === 43 /* plus */) { return pos += 2, token = 43 /* PlusPlusToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 59 /* PlusEqualsToken */; } pos++; return token = 37 /* PlusToken */; case 44 /* comma */: pos++; return token = 26 /* CommaToken */; case 45 /* minus */: if (text.charCodeAt(pos + 1) === 45 /* minus */) { return pos += 2, token = 44 /* MinusMinusToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 60 /* MinusEqualsToken */; } pos++; return token = 38 /* MinusToken */; case 46 /* dot */: if (isDigit(text.charCodeAt(pos + 1))) { tokenValue = scanNumber(); return token = 8 /* NumericLiteral */; } if (text.charCodeAt(pos + 1) === 46 /* dot */ && text.charCodeAt(pos + 2) === 46 /* dot */) { return pos += 3, token = 24 /* DotDotDotToken */; } pos++; return token = 23 /* DotToken */; case 47 /* slash */: // Single-line comment if (text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; while (pos < end) { if (isLineBreak(text.charCodeAt(pos))) { break; } pos++; } if (skipTrivia) { continue; } else { return token = 2 /* SingleLineCommentTrivia */; } } // Multi-line comment if (text.charCodeAt(pos + 1) === 42 /* asterisk */) { pos += 2; if (text.charCodeAt(pos) === 42 /* asterisk */ && text.charCodeAt(pos + 1) !== 47 /* slash */) { tokenFlags |= 2 /* PrecedingJSDocComment */; } var commentClosed = false; while (pos < end) { var ch_1 = text.charCodeAt(pos); if (ch_1 === 42 /* asterisk */ && text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; commentClosed = true; break; } if (isLineBreak(ch_1)) { tokenFlags |= 1 /* PrecedingLineBreak */; } pos++; } if (!commentClosed) { error(ts.Diagnostics.Asterisk_Slash_expected); } if (skipTrivia) { continue; } else { if (!commentClosed) { tokenFlags |= 4 /* Unterminated */; } return token = 3 /* MultiLineCommentTrivia */; } } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 63 /* SlashEqualsToken */; } pos++; return token = 41 /* SlashToken */; case 48 /* _0 */: if (pos + 2 < end && (text.charCodeAt(pos + 1) === 88 /* X */ || text.charCodeAt(pos + 1) === 120 /* x */)) { pos += 2; var value = scanMinimumNumberOfHexDigits(1); if (value < 0) { error(ts.Diagnostics.Hexadecimal_digit_expected); value = 0; } tokenValue = "" + value; tokenFlags |= 64 /* HexSpecifier */; return token = 8 /* NumericLiteral */; } else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 66 /* B */ || text.charCodeAt(pos + 1) === 98 /* b */)) { pos += 2; var value = scanBinaryOrOctalDigits(/* base */ 2); if (value < 0) { error(ts.Diagnostics.Binary_digit_expected); value = 0; } tokenValue = "" + value; tokenFlags |= 128 /* BinarySpecifier */; return token = 8 /* NumericLiteral */; } else if (pos + 2 < end && (text.charCodeAt(pos + 1) === 79 /* O */ || text.charCodeAt(pos + 1) === 111 /* o */)) { pos += 2; var value = scanBinaryOrOctalDigits(/* base */ 8); if (value < 0) { error(ts.Diagnostics.Octal_digit_expected); value = 0; } tokenValue = "" + value; tokenFlags |= 256 /* OctalSpecifier */; return token = 8 /* NumericLiteral */; } // Try to parse as an octal if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) { tokenValue = "" + scanOctalDigits(); tokenFlags |= 32 /* Octal */; return token = 8 /* NumericLiteral */; } // This fall-through is a deviation from the EcmaScript grammar. The grammar says that a leading zero // can only be followed by an octal digit, a dot, or the end of the number literal. However, we are being // permissive and allowing decimal digits of the form 08* and 09* (which many browsers also do). // falls through case 49 /* _1 */: case 50 /* _2 */: case 51 /* _3 */: case 52 /* _4 */: case 53 /* _5 */: case 54 /* _6 */: case 55 /* _7 */: case 56 /* _8 */: case 57 /* _9 */: tokenValue = scanNumber(); return token = 8 /* NumericLiteral */; case 58 /* colon */: pos++; return token = 56 /* ColonToken */; case 59 /* semicolon */: pos++; return token = 25 /* SemicolonToken */; case 60 /* lessThan */: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { return token = 7 /* ConflictMarkerTrivia */; } } if (text.charCodeAt(pos + 1) === 60 /* lessThan */) { if (text.charCodeAt(pos + 2) === 61 /* equals */) { return pos += 3, token = 65 /* LessThanLessThanEqualsToken */; } return pos += 2, token = 45 /* LessThanLessThanToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 30 /* LessThanEqualsToken */; } if (languageVariant === 1 /* JSX */ && text.charCodeAt(pos + 1) === 47 /* slash */ && text.charCodeAt(pos + 2) !== 42 /* asterisk */) { return pos += 2, token = 28 /* LessThanSlashToken */; } pos++; return token = 27 /* LessThanToken */; case 61 /* equals */: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { return token = 7 /* ConflictMarkerTrivia */; } } if (text.charCodeAt(pos + 1) === 61 /* equals */) { if (text.charCodeAt(pos + 2) === 61 /* equals */) { return pos += 3, token = 34 /* EqualsEqualsEqualsToken */; } return pos += 2, token = 32 /* EqualsEqualsToken */; } if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) { return pos += 2, token = 36 /* EqualsGreaterThanToken */; } pos++; return token = 58 /* EqualsToken */; case 62 /* greaterThan */: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { return token = 7 /* ConflictMarkerTrivia */; } } pos++; return token = 29 /* GreaterThanToken */; case 63 /* question */: pos++; return token = 55 /* QuestionToken */; case 91 /* openBracket */: pos++; return token = 21 /* OpenBracketToken */; case 93 /* closeBracket */: pos++; return token = 22 /* CloseBracketToken */; case 94 /* caret */: if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 70 /* CaretEqualsToken */; } pos++; return token = 50 /* CaretToken */; case 123 /* openBrace */: pos++; return token = 17 /* OpenBraceToken */; case 124 /* bar */: if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); if (skipTrivia) { continue; } else { return token = 7 /* ConflictMarkerTrivia */; } } if (text.charCodeAt(pos + 1) === 124 /* bar */) { return pos += 2, token = 54 /* BarBarToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 69 /* BarEqualsToken */; } pos++; return token = 49 /* BarToken */; case 125 /* closeBrace */: pos++; return token = 18 /* CloseBraceToken */; case 126 /* tilde */: pos++; return token = 52 /* TildeToken */; case 64 /* at */: pos++; return token = 57 /* AtToken */; case 92 /* backslash */: var cookedChar = peekUnicodeEscape(); if (cookedChar >= 0 && isIdentifierStart(cookedChar, languageVersion)) { pos += 6; tokenValue = String.fromCharCode(cookedChar) + scanIdentifierParts(); return token = getIdentifierToken(); } error(ts.Diagnostics.Invalid_character); pos++; return token = 0 /* Unknown */; default: if (isIdentifierStart(ch, languageVersion)) { pos++; while (pos < end && isIdentifierPart(ch = text.charCodeAt(pos), languageVersion)) pos++; tokenValue = text.substring(tokenPos, pos); if (ch === 92 /* backslash */) { tokenValue += scanIdentifierParts(); } return token = getIdentifierToken(); } else if (isWhiteSpaceSingleLine(ch)) { pos++; continue; } else if (isLineBreak(ch)) { tokenFlags |= 1 /* PrecedingLineBreak */; pos++; continue; } error(ts.Diagnostics.Invalid_character); pos++; return token = 0 /* Unknown */; } } } function reScanGreaterToken() { if (token === 29 /* GreaterThanToken */) { if (text.charCodeAt(pos) === 62 /* greaterThan */) { if (text.charCodeAt(pos + 1) === 62 /* greaterThan */) { if (text.charCodeAt(pos + 2) === 61 /* equals */) { return pos += 3, token = 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */; } return pos += 2, token = 47 /* GreaterThanGreaterThanGreaterThanToken */; } if (text.charCodeAt(pos + 1) === 61 /* equals */) { return pos += 2, token = 66 /* GreaterThanGreaterThanEqualsToken */; } pos++; return token = 46 /* GreaterThanGreaterThanToken */; } if (text.charCodeAt(pos) === 61 /* equals */) { pos++; return token = 31 /* GreaterThanEqualsToken */; } } return token; } function reScanSlashToken() { if (token === 41 /* SlashToken */ || token === 63 /* SlashEqualsToken */) { var p = tokenPos + 1; var inEscape = false; var inCharacterClass = false; while (true) { // If we reach the end of a file, or hit a newline, then this is an unterminated // regex. Report error and return what we have so far. if (p >= end) { tokenFlags |= 4 /* Unterminated */; error(ts.Diagnostics.Unterminated_regular_expression_literal); break; } var ch = text.charCodeAt(p); if (isLineBreak(ch)) { tokenFlags |= 4 /* Unterminated */; error(ts.Diagnostics.Unterminated_regular_expression_literal); break; } if (inEscape) { // Parsing an escape character; // reset the flag and just advance to the next char. inEscape = false; } else if (ch === 47 /* slash */ && !inCharacterClass) { // A slash within a character class is permissible, // but in general it signals the end of the regexp literal. p++; break; } else if (ch === 91 /* openBracket */) { inCharacterClass = true; } else if (ch === 92 /* backslash */) { inEscape = true; } else if (ch === 93 /* closeBracket */) { inCharacterClass = false; } p++; } while (p < end && isIdentifierPart(text.charCodeAt(p), languageVersion)) { p++; } pos = p; tokenValue = text.substring(tokenPos, pos); token = 12 /* RegularExpressionLiteral */; } return token; } /** * Unconditionally back up and scan a template expression portion. */ function reScanTemplateToken() { ts.Debug.assert(token === 18 /* CloseBraceToken */, "'reScanTemplateToken' should only be called on a '}'"); pos = tokenPos; return token = scanTemplateAndSetTokenValue(); } function reScanJsxToken() { pos = tokenPos = startPos; return token = scanJsxToken(); } function scanJsxToken() { startPos = tokenPos = pos; if (pos >= end) { return token = 1 /* EndOfFileToken */; } var char = text.charCodeAt(pos); if (char === 60 /* lessThan */) { if (text.charCodeAt(pos + 1) === 47 /* slash */) { pos += 2; return token = 28 /* LessThanSlashToken */; } pos++; return token = 27 /* LessThanToken */; } if (char === 123 /* openBrace */) { pos++; return token = 17 /* OpenBraceToken */; } // First non-whitespace character on this line. var firstNonWhitespace = 0; // These initial values are special because the first line is: // firstNonWhitespace = 0 to indicate that we want leading whitspace, while (pos < end) { char = text.charCodeAt(pos); if (char === 123 /* openBrace */) { break; } if (char === 60 /* lessThan */) { if (isConflictMarkerTrivia(text, pos)) { pos = scanConflictMarkerTrivia(text, pos, error); return token = 7 /* ConflictMarkerTrivia */; } break; } // FirstNonWhitespace is 0, then we only see whitespaces so far. If we see a linebreak, we want to ignore that whitespaces. // i.e (- : whitespace) //
---- //
becomes
// //
----
becomes
----
if (isLineBreak(char) && firstNonWhitespace === 0) { firstNonWhitespace = -1; } else if (!isWhiteSpaceLike(char)) { firstNonWhitespace = pos; } pos++; } return firstNonWhitespace === -1 ? 11 /* JsxTextAllWhiteSpaces */ : 10 /* JsxText */; } // Scans a JSX identifier; these differ from normal identifiers in that // they allow dashes function scanJsxIdentifier() { if (tokenIsIdentifierOrKeyword(token)) { var firstCharPosition = pos; while (pos < end) { var ch = text.charCodeAt(pos); if (ch === 45 /* minus */ || ((firstCharPosition === pos) ? isIdentifierStart(ch, languageVersion) : isIdentifierPart(ch, languageVersion))) { pos++; } else { break; } } tokenValue += text.substr(firstCharPosition, pos - firstCharPosition); } return token; } function scanJsxAttributeValue() { startPos = pos; switch (text.charCodeAt(pos)) { case 34 /* doubleQuote */: case 39 /* singleQuote */: tokenValue = scanString(/*jsxAttributeString*/ true); return token = 9 /* StringLiteral */; default: // If this scans anything other than `{`, it's a parse error. return scan(); } } function scanJSDocToken() { if (pos >= end) { return token = 1 /* EndOfFileToken */; } startPos = pos; tokenPos = pos; var ch = text.charCodeAt(pos); switch (ch) { case 9 /* tab */: case 11 /* verticalTab */: case 12 /* formFeed */: case 32 /* space */: while (pos < end && isWhiteSpaceSingleLine(text.charCodeAt(pos))) { pos++; } return token = 5 /* WhitespaceTrivia */; case 64 /* at */: pos++; return token = 57 /* AtToken */; case 10 /* lineFeed */: case 13 /* carriageReturn */: pos++; return token = 4 /* NewLineTrivia */; case 42 /* asterisk */: pos++; return token = 39 /* AsteriskToken */; case 123 /* openBrace */: pos++; return token = 17 /* OpenBraceToken */; case 125 /* closeBrace */: pos++; return token = 18 /* CloseBraceToken */; case 91 /* openBracket */: pos++; return token = 21 /* OpenBracketToken */; case 93 /* closeBracket */: pos++; return token = 22 /* CloseBracketToken */; case 60 /* lessThan */: pos++; return token = 27 /* LessThanToken */; case 62 /* greaterThan */: pos++; return token = 29 /* GreaterThanToken */; case 61 /* equals */: pos++; return token = 58 /* EqualsToken */; case 44 /* comma */: pos++; return token = 26 /* CommaToken */; case 46 /* dot */: pos++; if (text.substr(tokenPos, pos + 2) === "...") { pos += 2; return token = 24 /* DotDotDotToken */; } return token = 23 /* DotToken */; case 33 /* exclamation */: pos++; return token = 51 /* ExclamationToken */; case 63 /* question */: pos++; return token = 55 /* QuestionToken */; } if (isIdentifierStart(ch, 6 /* Latest */)) { pos++; while (isIdentifierPart(text.charCodeAt(pos), 6 /* Latest */) && pos < end) { pos++; } tokenValue = text.substring(tokenPos, pos); return token = 71 /* Identifier */; } else { return pos += 1, token = 0 /* Unknown */; } } function speculationHelper(callback, isLookahead) { var savePos = pos; var saveStartPos = startPos; var saveTokenPos = tokenPos; var saveToken = token; var saveTokenValue = tokenValue; var saveTokenFlags = tokenFlags; 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; tokenFlags = saveTokenFlags; } return result; } function scanRange(start, length, callback) { var saveEnd = end; var savePos = pos; var saveStartPos = startPos; var saveTokenPos = tokenPos; var saveToken = token; var saveTokenValue = tokenValue; var saveTokenFlags = tokenFlags; setText(text, start, length); var result = callback(); end = saveEnd; pos = savePos; startPos = saveStartPos; tokenPos = saveTokenPos; token = saveToken; tokenValue = saveTokenValue; tokenFlags = saveTokenFlags; 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 */; tokenValue = undefined; tokenFlags = 0; } } ts.createScanner = createScanner; })(ts || (ts = {})); /// /// var ts; (function (ts) { var SignatureFlags; (function (SignatureFlags) { SignatureFlags[SignatureFlags["None"] = 0] = "None"; SignatureFlags[SignatureFlags["Yield"] = 1] = "Yield"; SignatureFlags[SignatureFlags["Await"] = 2] = "Await"; SignatureFlags[SignatureFlags["Type"] = 4] = "Type"; SignatureFlags[SignatureFlags["RequireCompleteParameterList"] = 8] = "RequireCompleteParameterList"; SignatureFlags[SignatureFlags["IgnoreMissingOpenBrace"] = 16] = "IgnoreMissingOpenBrace"; SignatureFlags[SignatureFlags["JSDoc"] = 32] = "JSDoc"; })(SignatureFlags || (SignatureFlags = {})); // tslint:disable variable-name var NodeConstructor; var TokenConstructor; var IdentifierConstructor; var SourceFileConstructor; // tslint:enable variable-name function createNode(kind, pos, end) { if (kind === 269 /* SourceFile */) { return new (SourceFileConstructor || (SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor()))(kind, pos, end); } else if (kind === 71 /* Identifier */) { return new (IdentifierConstructor || (IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor()))(kind, pos, end); } else if (!ts.isNodeKind(kind)) { return new (TokenConstructor || (TokenConstructor = ts.objectAllocator.getTokenConstructor()))(kind, pos, end); } else { return new (NodeConstructor || (NodeConstructor = ts.objectAllocator.getNodeConstructor()))(kind, pos, end); } } ts.createNode = createNode; function visitNode(cbNode, node) { return node && cbNode(node); } function visitNodes(cbNode, cbNodes, nodes) { if (nodes) { if (cbNodes) { return cbNodes(nodes); } for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) { var node = nodes_1[_i]; var result = cbNode(node); if (result) { return result; } } } } /** * Invokes a callback for each child of the given node. The 'cbNode' callback is invoked for all child nodes * stored in properties. If a 'cbNodes' callback is specified, it is invoked for embedded arrays; otherwise, * embedded arrays are flattened and the 'cbNode' callback is invoked for each element. If a callback returns * a truthy value, iteration stops and that value is returned. Otherwise, undefined is returned. * * @param node a given node to visit its children * @param cbNode a callback to be invoked for all child nodes * @param cbNodes a callback to be invoked for embedded array * * @remarks `forEachChild` must visit the children of a node in the order * that they appear in the source code. The language service depends on this property to locate nodes by position. */ function forEachChild(node, cbNode, cbNodes) { if (!node || node.kind <= 143 /* LastToken */) { return; } switch (node.kind) { case 144 /* QualifiedName */: return visitNode(cbNode, node.left) || visitNode(cbNode, node.right); case 146 /* TypeParameter */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.constraint) || visitNode(cbNode, node.default) || visitNode(cbNode, node.expression); case 266 /* ShorthandPropertyAssignment */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNode(cbNode, node.questionToken) || visitNode(cbNode, node.equalsToken) || visitNode(cbNode, node.objectAssignmentInitializer); case 267 /* SpreadAssignment */: return visitNode(cbNode, node.expression); case 147 /* Parameter */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 265 /* PropertyAssignment */: case 227 /* VariableDeclaration */: case 177 /* BindingElement */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.propertyName) || visitNode(cbNode, node.dotDotDotToken) || visitNode(cbNode, node.name) || visitNode(cbNode, node.questionToken) || visitNode(cbNode, node.exclamationToken) || visitNode(cbNode, node.type) || visitNode(cbNode, node.initializer); case 161 /* FunctionType */: case 162 /* ConstructorType */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNodes(cbNode, cbNodes, node.typeParameters) || visitNodes(cbNode, cbNodes, node.parameters) || visitNode(cbNode, node.type); case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.asteriskToken) || visitNode(cbNode, node.name) || visitNode(cbNode, node.questionToken) || visitNodes(cbNode, cbNodes, node.typeParameters) || visitNodes(cbNode, cbNodes, node.parameters) || visitNode(cbNode, node.type) || visitNode(cbNode, node.equalsGreaterThanToken) || visitNode(cbNode, node.body); case 160 /* TypeReference */: return visitNode(cbNode, node.typeName) || visitNodes(cbNode, cbNodes, node.typeArguments); case 159 /* TypePredicate */: return visitNode(cbNode, node.parameterName) || visitNode(cbNode, node.type); case 163 /* TypeQuery */: return visitNode(cbNode, node.exprName); case 164 /* TypeLiteral */: return visitNodes(cbNode, cbNodes, node.members); case 165 /* ArrayType */: return visitNode(cbNode, node.elementType); case 166 /* TupleType */: return visitNodes(cbNode, cbNodes, node.elementTypes); case 167 /* UnionType */: case 168 /* IntersectionType */: return visitNodes(cbNode, cbNodes, node.types); case 169 /* ParenthesizedType */: case 171 /* TypeOperator */: return visitNode(cbNode, node.type); case 172 /* IndexedAccessType */: return visitNode(cbNode, node.objectType) || visitNode(cbNode, node.indexType); case 173 /* MappedType */: return visitNode(cbNode, node.readonlyToken) || visitNode(cbNode, node.typeParameter) || visitNode(cbNode, node.questionToken) || visitNode(cbNode, node.type); case 174 /* LiteralType */: return visitNode(cbNode, node.literal); case 175 /* ObjectBindingPattern */: case 176 /* ArrayBindingPattern */: return visitNodes(cbNode, cbNodes, node.elements); case 178 /* ArrayLiteralExpression */: return visitNodes(cbNode, cbNodes, node.elements); case 179 /* ObjectLiteralExpression */: return visitNodes(cbNode, cbNodes, node.properties); case 180 /* PropertyAccessExpression */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.name); case 181 /* ElementAccessExpression */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.argumentExpression); case 182 /* CallExpression */: case 183 /* NewExpression */: return visitNode(cbNode, node.expression) || visitNodes(cbNode, cbNodes, node.typeArguments) || visitNodes(cbNode, cbNodes, node.arguments); case 184 /* TaggedTemplateExpression */: return visitNode(cbNode, node.tag) || visitNode(cbNode, node.template); case 185 /* TypeAssertionExpression */: return visitNode(cbNode, node.type) || visitNode(cbNode, node.expression); case 186 /* ParenthesizedExpression */: return visitNode(cbNode, node.expression); case 189 /* DeleteExpression */: return visitNode(cbNode, node.expression); case 190 /* TypeOfExpression */: return visitNode(cbNode, node.expression); case 191 /* VoidExpression */: return visitNode(cbNode, node.expression); case 193 /* PrefixUnaryExpression */: return visitNode(cbNode, node.operand); case 198 /* YieldExpression */: return visitNode(cbNode, node.asteriskToken) || visitNode(cbNode, node.expression); case 192 /* AwaitExpression */: return visitNode(cbNode, node.expression); case 194 /* PostfixUnaryExpression */: return visitNode(cbNode, node.operand); case 195 /* BinaryExpression */: return visitNode(cbNode, node.left) || visitNode(cbNode, node.operatorToken) || visitNode(cbNode, node.right); case 203 /* AsExpression */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.type); case 204 /* NonNullExpression */: return visitNode(cbNode, node.expression); case 205 /* MetaProperty */: return visitNode(cbNode, node.name); case 196 /* ConditionalExpression */: return visitNode(cbNode, node.condition) || visitNode(cbNode, node.questionToken) || visitNode(cbNode, node.whenTrue) || visitNode(cbNode, node.colonToken) || visitNode(cbNode, node.whenFalse); case 199 /* SpreadElement */: return visitNode(cbNode, node.expression); case 208 /* Block */: case 235 /* ModuleBlock */: return visitNodes(cbNode, cbNodes, node.statements); case 269 /* SourceFile */: return visitNodes(cbNode, cbNodes, node.statements) || visitNode(cbNode, node.endOfFileToken); case 209 /* VariableStatement */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.declarationList); case 228 /* VariableDeclarationList */: return visitNodes(cbNode, cbNodes, node.declarations); case 211 /* ExpressionStatement */: return visitNode(cbNode, node.expression); case 212 /* IfStatement */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.thenStatement) || visitNode(cbNode, node.elseStatement); case 213 /* DoStatement */: return visitNode(cbNode, node.statement) || visitNode(cbNode, node.expression); case 214 /* WhileStatement */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.statement); case 215 /* ForStatement */: return visitNode(cbNode, node.initializer) || visitNode(cbNode, node.condition) || visitNode(cbNode, node.incrementor) || visitNode(cbNode, node.statement); case 216 /* ForInStatement */: return visitNode(cbNode, node.initializer) || visitNode(cbNode, node.expression) || visitNode(cbNode, node.statement); case 217 /* ForOfStatement */: return visitNode(cbNode, node.awaitModifier) || visitNode(cbNode, node.initializer) || visitNode(cbNode, node.expression) || visitNode(cbNode, node.statement); case 218 /* ContinueStatement */: case 219 /* BreakStatement */: return visitNode(cbNode, node.label); case 220 /* ReturnStatement */: return visitNode(cbNode, node.expression); case 221 /* WithStatement */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.statement); case 222 /* SwitchStatement */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.caseBlock); case 236 /* CaseBlock */: return visitNodes(cbNode, cbNodes, node.clauses); case 261 /* CaseClause */: return visitNode(cbNode, node.expression) || visitNodes(cbNode, cbNodes, node.statements); case 262 /* DefaultClause */: return visitNodes(cbNode, cbNodes, node.statements); case 223 /* LabeledStatement */: return visitNode(cbNode, node.label) || visitNode(cbNode, node.statement); case 224 /* ThrowStatement */: return visitNode(cbNode, node.expression); case 225 /* TryStatement */: return visitNode(cbNode, node.tryBlock) || visitNode(cbNode, node.catchClause) || visitNode(cbNode, node.finallyBlock); case 264 /* CatchClause */: return visitNode(cbNode, node.variableDeclaration) || visitNode(cbNode, node.block); case 148 /* Decorator */: return visitNode(cbNode, node.expression); case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNodes(cbNode, cbNodes, node.typeParameters) || visitNodes(cbNode, cbNodes, node.heritageClauses) || visitNodes(cbNode, cbNodes, node.members); case 231 /* InterfaceDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNodes(cbNode, cbNodes, node.typeParameters) || visitNodes(cbNode, cbNodes, node.heritageClauses) || visitNodes(cbNode, cbNodes, node.members); case 232 /* TypeAliasDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNodes(cbNode, cbNodes, node.typeParameters) || visitNode(cbNode, node.type); case 233 /* EnumDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNodes(cbNode, cbNodes, node.members); case 268 /* EnumMember */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.initializer); case 234 /* ModuleDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNode(cbNode, node.body); case 238 /* ImportEqualsDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.name) || visitNode(cbNode, node.moduleReference); case 239 /* ImportDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.importClause) || visitNode(cbNode, node.moduleSpecifier); case 240 /* ImportClause */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.namedBindings); case 237 /* NamespaceExportDeclaration */: return visitNode(cbNode, node.name); case 241 /* NamespaceImport */: return visitNode(cbNode, node.name); case 242 /* NamedImports */: case 246 /* NamedExports */: return visitNodes(cbNode, cbNodes, node.elements); case 245 /* ExportDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.exportClause) || visitNode(cbNode, node.moduleSpecifier); case 243 /* ImportSpecifier */: case 247 /* ExportSpecifier */: return visitNode(cbNode, node.propertyName) || visitNode(cbNode, node.name); case 244 /* ExportAssignment */: return visitNodes(cbNode, cbNodes, node.decorators) || visitNodes(cbNode, cbNodes, node.modifiers) || visitNode(cbNode, node.expression); case 197 /* TemplateExpression */: return visitNode(cbNode, node.head) || visitNodes(cbNode, cbNodes, node.templateSpans); case 206 /* TemplateSpan */: return visitNode(cbNode, node.expression) || visitNode(cbNode, node.literal); case 145 /* ComputedPropertyName */: return visitNode(cbNode, node.expression); case 263 /* HeritageClause */: return visitNodes(cbNode, cbNodes, node.types); case 202 /* ExpressionWithTypeArguments */: return visitNode(cbNode, node.expression) || visitNodes(cbNode, cbNodes, node.typeArguments); case 249 /* ExternalModuleReference */: return visitNode(cbNode, node.expression); case 248 /* MissingDeclaration */: return visitNodes(cbNode, cbNodes, node.decorators); case 293 /* CommaListExpression */: return visitNodes(cbNode, cbNodes, node.elements); case 250 /* JsxElement */: return visitNode(cbNode, node.openingElement) || visitNodes(cbNode, cbNodes, node.children) || visitNode(cbNode, node.closingElement); case 254 /* JsxFragment */: return visitNode(cbNode, node.openingFragment) || visitNodes(cbNode, cbNodes, node.children) || visitNode(cbNode, node.closingFragment); case 251 /* JsxSelfClosingElement */: case 252 /* JsxOpeningElement */: return visitNode(cbNode, node.tagName) || visitNode(cbNode, node.attributes); case 258 /* JsxAttributes */: return visitNodes(cbNode, cbNodes, node.properties); case 257 /* JsxAttribute */: return visitNode(cbNode, node.name) || visitNode(cbNode, node.initializer); case 259 /* JsxSpreadAttribute */: return visitNode(cbNode, node.expression); case 260 /* JsxExpression */: return visitNode(cbNode, node.dotDotDotToken) || visitNode(cbNode, node.expression); case 253 /* JsxClosingElement */: return visitNode(cbNode, node.tagName); case 271 /* JSDocTypeExpression */: return visitNode(cbNode, node.type); case 275 /* JSDocNonNullableType */: return visitNode(cbNode, node.type); case 274 /* JSDocNullableType */: return visitNode(cbNode, node.type); case 276 /* JSDocOptionalType */: return visitNode(cbNode, node.type); case 277 /* JSDocFunctionType */: return visitNodes(cbNode, cbNodes, node.parameters) || visitNode(cbNode, node.type); case 278 /* JSDocVariadicType */: return visitNode(cbNode, node.type); case 279 /* JSDocComment */: return visitNodes(cbNode, cbNodes, node.tags); case 284 /* JSDocParameterTag */: case 289 /* JSDocPropertyTag */: if (node.isNameFirst) { return visitNode(cbNode, node.name) || visitNode(cbNode, node.typeExpression); } else { return visitNode(cbNode, node.typeExpression) || visitNode(cbNode, node.name); } case 285 /* JSDocReturnTag */: return visitNode(cbNode, node.typeExpression); case 286 /* JSDocTypeTag */: return visitNode(cbNode, node.typeExpression); case 282 /* JSDocAugmentsTag */: return visitNode(cbNode, node.class); case 287 /* JSDocTemplateTag */: return visitNodes(cbNode, cbNodes, node.typeParameters); case 288 /* JSDocTypedefTag */: if (node.typeExpression && node.typeExpression.kind === 271 /* JSDocTypeExpression */) { return visitNode(cbNode, node.typeExpression) || visitNode(cbNode, node.fullName); } else { return visitNode(cbNode, node.fullName) || visitNode(cbNode, node.typeExpression); } case 280 /* JSDocTypeLiteral */: if (node.jsDocPropertyTags) { for (var _i = 0, _a = node.jsDocPropertyTags; _i < _a.length; _i++) { var tag = _a[_i]; visitNode(cbNode, tag); } } return; case 292 /* PartiallyEmittedExpression */: return visitNode(cbNode, node.expression); } } ts.forEachChild = forEachChild; function createSourceFile(fileName, sourceText, languageVersion, setParentNodes, scriptKind) { if (setParentNodes === void 0) { setParentNodes = false; } ts.performance.mark("beforeParse"); var result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind); ts.performance.mark("afterParse"); ts.performance.measure("Parse", "beforeParse", "afterParse"); return result; } ts.createSourceFile = createSourceFile; function parseIsolatedEntityName(text, languageVersion) { return Parser.parseIsolatedEntityName(text, languageVersion); } ts.parseIsolatedEntityName = parseIsolatedEntityName; /** * Parse json text into SyntaxTree and return node and parse errors if any * @param fileName * @param sourceText */ function parseJsonText(fileName, sourceText) { return Parser.parseJsonText(fileName, sourceText); } ts.parseJsonText = parseJsonText; // See also `isExternalOrCommonJsModule` in utilities.ts function isExternalModule(file) { return file.externalModuleIndicator !== undefined; } ts.isExternalModule = isExternalModule; // Produces a new SourceFile for the 'newText' provided. The 'textChangeRange' parameter // indicates what changed between the 'text' that this SourceFile has and the 'newText'. // The SourceFile will be created with the compiler attempting to reuse as many nodes from // this file as possible. // // Note: this function mutates nodes from this SourceFile. That means any existing nodes // from this SourceFile that are being held onto may change as a result (including // becoming detached from any SourceFile). It is recommended that this SourceFile not // be used once 'update' is called on it. function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) { var newSourceFile = IncrementalParser.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); // Because new source file node is created, it may not have the flag PossiblyContainDynamicImport. This is the case if there is no new edit to add dynamic import. // We will manually port the flag to the new source file. newSourceFile.flags |= (sourceFile.flags & 524288 /* PossiblyContainsDynamicImport */); return newSourceFile; } ts.updateSourceFile = updateSourceFile; /* @internal */ function parseIsolatedJSDocComment(content, start, length) { var result = Parser.JSDocParser.parseIsolatedJSDocComment(content, start, length); if (result && result.jsDoc) { // because the jsDocComment was parsed out of the source file, it might // not be covered by the fixupParentReferences. Parser.fixupParentReferences(result.jsDoc); } return result; } ts.parseIsolatedJSDocComment = parseIsolatedJSDocComment; /* @internal */ // Exposed only for testing. function parseJSDocTypeExpressionForTests(content, start, length) { return Parser.JSDocParser.parseJSDocTypeExpressionForTests(content, start, length); } ts.parseJSDocTypeExpressionForTests = parseJSDocTypeExpressionForTests; // Implement the parser as a singleton module. We do this for perf reasons because creating // parser instances can actually be expensive enough to impact us on projects with many source // files. var Parser; (function (Parser) { // Share a single scanner across all calls to parse a source file. This helps speed things // up by avoiding the cost of creating/compiling scanners over and over again. var scanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ true); var disallowInAndDecoratorContext = 2048 /* DisallowInContext */ | 8192 /* DecoratorContext */; // capture constructors in 'initializeState' to avoid null checks // tslint:disable variable-name var NodeConstructor; var TokenConstructor; var IdentifierConstructor; var SourceFileConstructor; // tslint:enable variable-name var sourceFile; var parseDiagnostics; var syntaxCursor; var currentToken; var sourceText; var nodeCount; var identifiers; var identifierCount; var parsingContext; // Flags that dictate what parsing context we're in. For example: // Whether or not we are in strict parsing mode. All that changes in strict parsing mode is // that some tokens that would be considered identifiers may be considered keywords. // // When adding more parser context flags, consider which is the more common case that the // flag will be in. This should be the 'false' state for that flag. The reason for this is // that we don't store data in our nodes unless the value is in the *non-default* state. So, // for example, more often than code 'allows-in' (or doesn't 'disallow-in'). We opt for // 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost // all nodes would need extra state on them to store this info. // // Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6 // grammar specification. // // An important thing about these context concepts. By default they are effectively inherited // while parsing through every grammar production. i.e. if you don't change them, then when // you parse a sub-production, it will have the same context values as the parent production. // This is great most of the time. After all, consider all the 'expression' grammar productions // and how nearly all of them pass along the 'in' and 'yield' context values: // // EqualityExpression[In, Yield] : // RelationalExpression[?In, ?Yield] // EqualityExpression[?In, ?Yield] == RelationalExpression[?In, ?Yield] // EqualityExpression[?In, ?Yield] != RelationalExpression[?In, ?Yield] // EqualityExpression[?In, ?Yield] === RelationalExpression[?In, ?Yield] // EqualityExpression[?In, ?Yield] !== RelationalExpression[?In, ?Yield] // // Where you have to be careful is then understanding what the points are in the grammar // where the values are *not* passed along. For example: // // SingleNameBinding[Yield,GeneratorParameter] // [+GeneratorParameter]BindingIdentifier[Yield] Initializer[In]opt // [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt // // Here this is saying that if the GeneratorParameter context flag is set, that we should // explicitly set the 'yield' context flag to false before calling into the BindingIdentifier // and we should explicitly unset the 'yield' context flag before calling into the Initializer. // production. Conversely, if the GeneratorParameter context flag is not set, then we // should leave the 'yield' context flag alone. // // Getting this all correct is tricky and requires careful reading of the grammar to // understand when these values should be changed versus when they should be inherited. // // Note: it should not be necessary to save/restore these flags during speculative/lookahead // parsing. These context flags are naturally stored and restored through normal recursive // descent parsing and unwinding. var contextFlags; // Whether or not we've had a parse error since creating the last AST node. If we have // encountered an error, it will be stored on the next AST node we create. Parse errors // can be broken down into three categories: // // 1) An error that occurred during scanning. For example, an unterminated literal, or a // character that was completely not understood. // // 2) A token was expected, but was not present. This type of error is commonly produced // by the 'parseExpected' function. // // 3) A token was present that no parsing function was able to consume. This type of error // only occurs in the 'abortParsingListOrMoveToNextToken' function when the parser // decides to skip the token. // // In all of these cases, we want to mark the next node as having had an error before it. // With this mark, we can know in incremental settings if this node can be reused, or if // we have to reparse it. If we don't keep this information around, we may just reuse the // node. in that event we would then not produce the same errors as we did before, causing // significant confusion problems. // // Note: it is necessary that this value be saved/restored during speculative/lookahead // parsing. During lookahead parsing, we will often create a node. That node will have // this value attached, and then this value will be set back to 'false'. If we decide to // rewind, we must get back to the same value we had prior to the lookahead. // // Note: any errors at the end of the file that do not precede a regular node, should get // attached to the EOF token. var parseErrorBeforeNextFinishedNode = false; function parseSourceFile(fileName, sourceText, languageVersion, syntaxCursor, setParentNodes, scriptKind) { scriptKind = ts.ensureScriptKind(fileName, scriptKind); initializeState(sourceText, languageVersion, syntaxCursor, scriptKind); var result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind); clearState(); return result; } Parser.parseSourceFile = parseSourceFile; function parseIsolatedEntityName(content, languageVersion) { // Choice of `isDeclarationFile` should be arbitrary initializeState(content, languageVersion, /*syntaxCursor*/ undefined, 1 /* JS */); // Prime the scanner. nextToken(); var entityName = parseEntityName(/*allowReservedWords*/ true); var isInvalid = token() === 1 /* EndOfFileToken */ && !parseDiagnostics.length; clearState(); return isInvalid ? entityName : undefined; } Parser.parseIsolatedEntityName = parseIsolatedEntityName; function parseJsonText(fileName, sourceText) { initializeState(sourceText, 2 /* ES2015 */, /*syntaxCursor*/ undefined, 6 /* JSON */); // Set source file so that errors will be reported with this file name sourceFile = createSourceFile(fileName, 2 /* ES2015 */, 6 /* JSON */, /*isDeclaration*/ false); var result = sourceFile; // Prime the scanner. nextToken(); if (token() === 1 /* EndOfFileToken */) { sourceFile.endOfFileToken = parseTokenNode(); } else if (token() === 17 /* OpenBraceToken */ || lookAhead(function () { return token() === 9 /* StringLiteral */; })) { result.jsonObject = parseObjectLiteralExpression(); sourceFile.endOfFileToken = parseExpectedToken(1 /* EndOfFileToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.Unexpected_token); } else { parseExpected(17 /* OpenBraceToken */); } sourceFile.parseDiagnostics = parseDiagnostics; clearState(); return result; } Parser.parseJsonText = parseJsonText; function getLanguageVariant(scriptKind) { // .tsx and .jsx files are treated as jsx language variant. return scriptKind === 4 /* TSX */ || scriptKind === 2 /* JSX */ || scriptKind === 1 /* JS */ || scriptKind === 6 /* JSON */ ? 1 /* JSX */ : 0 /* Standard */; } function initializeState(_sourceText, languageVersion, _syntaxCursor, scriptKind) { NodeConstructor = ts.objectAllocator.getNodeConstructor(); TokenConstructor = ts.objectAllocator.getTokenConstructor(); IdentifierConstructor = ts.objectAllocator.getIdentifierConstructor(); SourceFileConstructor = ts.objectAllocator.getSourceFileConstructor(); sourceText = _sourceText; syntaxCursor = _syntaxCursor; parseDiagnostics = []; parsingContext = 0; identifiers = ts.createMap(); identifierCount = 0; nodeCount = 0; switch (scriptKind) { case 1 /* JS */: case 2 /* JSX */: case 6 /* JSON */: contextFlags = 65536 /* JavaScriptFile */; break; default: contextFlags = 0 /* None */; break; } 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) { var isDeclarationFile = isDeclarationFileName(fileName); if (isDeclarationFile) { contextFlags |= 2097152 /* Ambient */; } sourceFile = createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile); sourceFile.flags = contextFlags; // Prime the scanner. nextToken(); processReferenceComments(sourceFile); sourceFile.statements = parseList(0 /* SourceElements */, parseStatement); ts.Debug.assert(token() === 1 /* EndOfFileToken */); sourceFile.endOfFileToken = addJSDocComment(parseTokenNode()); setExternalModuleIndicator(sourceFile); sourceFile.nodeCount = nodeCount; sourceFile.identifierCount = identifierCount; sourceFile.identifiers = identifiers; sourceFile.parseDiagnostics = parseDiagnostics; if (setParentNodes) { fixupParentReferences(sourceFile); } return sourceFile; } function addJSDocComment(node) { var comments = ts.getJSDocCommentRanges(node, sourceFile.text); if (comments) { for (var _i = 0, comments_2 = comments; _i < comments_2.length; _i++) { var comment = comments_2[_i]; var jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos); if (jsDoc) { if (!node.jsDoc) { node.jsDoc = [jsDoc]; } else { node.jsDoc.push(jsDoc); } } } } return node; } function fixupParentReferences(rootNode) { // normally parent references are set during binding. However, for clients that only need // a syntax tree, and no semantic features, then the binding process is an unnecessary // overhead. This functions allows us to set all the parents, without all the expense of // binding. var parent = rootNode; forEachChild(rootNode, visitNode); return; function visitNode(n) { // walk down setting parents that differ from the parent we think it should be. This // allows us to quickly bail out of setting parents for subtrees during incremental // parsing if (n.parent !== parent) { n.parent = parent; var saveParent = parent; parent = n; forEachChild(n, visitNode); if (ts.hasJSDocNodes(n)) { for (var _i = 0, _a = n.jsDoc; _i < _a.length; _i++) { var jsDoc = _a[_i]; jsDoc.parent = n; parent = jsDoc; forEachChild(jsDoc, visitNode); } } parent = saveParent; } } } Parser.fixupParentReferences = fixupParentReferences; function createSourceFile(fileName, languageVersion, scriptKind, isDeclarationFile) { // 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(269 /* 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 = isDeclarationFile; sourceFile.scriptKind = scriptKind; return sourceFile; } function setContextFlag(val, flag) { if (val) { contextFlags |= flag; } else { contextFlags &= ~flag; } } function setDisallowInContext(val) { setContextFlag(val, 2048 /* DisallowInContext */); } function setYieldContext(val) { setContextFlag(val, 4096 /* YieldContext */); } function setDecoratorContext(val) { setContextFlag(val, 8192 /* DecoratorContext */); } function setAwaitContext(val) { setContextFlag(val, 16384 /* AwaitContext */); } function doOutsideOfContext(context, func) { // contextFlagsToClear will contain only the context flags that are // currently set that we need to temporarily clear // We don't just blindly reset to the previous flags to ensure // that we do not mutate cached flags for the incremental // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and // HasAggregatedChildData). var contextFlagsToClear = context & contextFlags; if (contextFlagsToClear) { // clear the requested context flags setContextFlag(/*val*/ false, contextFlagsToClear); var result = func(); // restore the context flags we just cleared setContextFlag(/*val*/ true, contextFlagsToClear); return result; } // no need to do anything special as we are not in any of the requested contexts return func(); } function doInsideOfContext(context, func) { // contextFlagsToSet will contain only the context flags that // are not currently set that we need to temporarily enable. // We don't just blindly reset to the previous flags to ensure // that we do not mutate cached flags for the incremental // parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and // HasAggregatedChildData). var contextFlagsToSet = context & ~contextFlags; if (contextFlagsToSet) { // set the requested context flags setContextFlag(/*val*/ true, contextFlagsToSet); var result = func(); // reset the context flags we just set setContextFlag(/*val*/ false, contextFlagsToSet); return result; } // no need to do anything special as we are already in all of the requested contexts return func(); } function allowInAnd(func) { return doOutsideOfContext(2048 /* DisallowInContext */, func); } function disallowInAnd(func) { return doInsideOfContext(2048 /* DisallowInContext */, func); } function doInYieldContext(func) { return doInsideOfContext(4096 /* YieldContext */, func); } function doInDecoratorContext(func) { return doInsideOfContext(8192 /* DecoratorContext */, func); } function doInAwaitContext(func) { return doInsideOfContext(16384 /* AwaitContext */, func); } function doOutsideOfAwaitContext(func) { return doOutsideOfContext(16384 /* AwaitContext */, func); } function doInYieldAndAwaitContext(func) { return doInsideOfContext(4096 /* YieldContext */ | 16384 /* AwaitContext */, func); } function inContext(flags) { return (contextFlags & flags) !== 0; } function inYieldContext() { return inContext(4096 /* YieldContext */); } function inDisallowInContext() { return inContext(2048 /* DisallowInContext */); } function inDecoratorContext() { return inContext(8192 /* DecoratorContext */); } function inAwaitContext() { return inContext(16384 /* AwaitContext */); } function parseErrorAtCurrentToken(message, arg0) { var start = scanner.getTokenPos(); var length = scanner.getTextPos() - start; parseErrorAtPosition(start, length, message, arg0); } function parseErrorAtPosition(start, length, message, arg0) { // Don't report another error if it would just be at the same position as the last error. var lastError = ts.lastOrUndefined(parseDiagnostics); if (!lastError || start !== lastError.start) { parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, start, length, message, arg0)); } // Mark that we've encountered an error. We'll set an appropriate bit on the next // node we finish so that it can't be reused incrementally. parseErrorBeforeNextFinishedNode = true; } function scanError(message, length) { var pos = scanner.getTextPos(); parseErrorAtPosition(pos, length || 0, message); } function getNodePos() { return scanner.getStartPos(); } // Use this function to access the current token instead of reading the currentToken // variable. Since function results aren't narrowed in control flow analysis, this ensures // that the type checker doesn't make wrong assumptions about the type of the current // token (e.g. a call to nextToken() changes the current token but the checker doesn't // reason about this side effect). Mainstream VMs inline simple functions like this, so // there is no performance penalty. function token() { return currentToken; } function nextToken() { return currentToken = scanner.scan(); } function reScanGreaterToken() { return currentToken = scanner.reScanGreaterToken(); } function reScanSlashToken() { return currentToken = scanner.reScanSlashToken(); } function reScanTemplateToken() { return currentToken = scanner.reScanTemplateToken(); } function scanJsxIdentifier() { return currentToken = scanner.scanJsxIdentifier(); } function scanJsxText() { return currentToken = scanner.scanJsxToken(); } function scanJsxAttributeValue() { return currentToken = scanner.scanJsxAttributeValue(); } function speculationHelper(callback, isLookAhead) { // Keep track of the state we'll need to rollback to if lookahead fails (or if the // caller asked us to always reset our state). var saveToken = currentToken; var saveParseDiagnosticsLength = parseDiagnostics.length; var saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode; // Note: it is not actually necessary to save/restore the context flags here. That's // because the saving/restoring of these flags happens naturally through the recursive // descent nature of our parser. However, we still store this here just so we can // assert that invariant holds. var saveContextFlags = contextFlags; // If we're only looking ahead, then tell the scanner to only lookahead as well. // Otherwise, if we're actually speculatively parsing, then tell the scanner to do the // same. var result = isLookAhead ? scanner.lookAhead(callback) : scanner.tryScan(callback); ts.Debug.assert(saveContextFlags === contextFlags); // If our callback returned something 'falsy' or we're just looking ahead, // then unconditionally restore us to where we were. if (!result || isLookAhead) { currentToken = saveToken; parseDiagnostics.length = saveParseDiagnosticsLength; parseErrorBeforeNextFinishedNode = saveParseErrorBeforeNextFinishedNode; } return result; } /** Invokes the provided callback then unconditionally restores the parser to the state it * was in immediately prior to invoking the callback. The result of invoking the callback * is returned from this function. */ function lookAhead(callback) { return speculationHelper(callback, /*isLookAhead*/ true); } /** Invokes the provided callback. If the callback returns something falsy, then it restores * the parser to the state it was in immediately prior to invoking the callback. If the * callback returns something truthy, then the parser state is not rolled back. The result * of invoking the callback is returned from this function. */ function tryParse(callback) { return speculationHelper(callback, /*isLookAhead*/ false); } // Ignore strict mode flag because we will report an error in type checker instead. function isIdentifier() { if (token() === 71 /* Identifier */) { return true; } // If we have a 'yield' keyword, and we're in the [yield] context, then 'yield' is // considered a keyword and is not an identifier. if (token() === 116 /* YieldKeyword */ && inYieldContext()) { return false; } // If we have a 'await' keyword, and we're in the [Await] context, then 'await' is // considered a keyword and is not an identifier. if (token() === 121 /* AwaitKeyword */ && inAwaitContext()) { return false; } return token() > 107 /* LastReservedWord */; } function parseExpected(kind, diagnosticMessage, shouldAdvance) { if (shouldAdvance === void 0) { shouldAdvance = true; } if (token() === kind) { if (shouldAdvance) { nextToken(); } return true; } // Report specific message if provided with one. Otherwise, report generic fallback message. if (diagnosticMessage) { parseErrorAtCurrentToken(diagnosticMessage); } else { parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(kind)); } return false; } function parseOptional(t) { if (token() === t) { nextToken(); return true; } return false; } function parseOptionalToken(t) { if (token() === t) { return parseTokenNode(); } return undefined; } function parseExpectedToken(t, reportAtCurrentPosition, diagnosticMessage, arg0) { return parseOptionalToken(t) || createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0); } function parseTokenNode() { var node = createNode(token()); nextToken(); return finishNode(node); } function canParseSemicolon() { // If there's a real semicolon, then we can always parse it out. if (token() === 25 /* SemicolonToken */) { return true; } // We can parse out an optional semicolon in ASI cases in the following cases. return token() === 18 /* CloseBraceToken */ || token() === 1 /* EndOfFileToken */ || scanner.hasPrecedingLineBreak(); } function parseSemicolon() { if (canParseSemicolon()) { if (token() === 25 /* SemicolonToken */) { // consume the semicolon if it was explicitly provided. nextToken(); } return true; } else { return parseExpected(25 /* SemicolonToken */); } } function createNode(kind, pos) { nodeCount++; var p = pos >= 0 ? pos : scanner.getStartPos(); return ts.isNodeKind(kind) || kind === 0 /* Unknown */ ? new NodeConstructor(kind, p, p) : kind === 71 /* Identifier */ ? new IdentifierConstructor(kind, p, p) : new TokenConstructor(kind, p, p); } function createNodeWithJSDoc(kind) { var node = createNode(kind); if (scanner.getTokenFlags() & 2 /* PrecedingJSDocComment */) { addJSDocComment(node); } return node; } function createNodeArray(elements, pos, end) { // Since the element list of a node array is typically created by starting with an empty array and // repeatedly calling push(), the list may not have the optimal memory layout. We invoke slice() for // small arrays (1 to 4 elements) to give the VM a chance to allocate an optimal representation. var length = elements.length; var array = (length >= 1 && length <= 4 ? elements.slice() : elements); array.pos = pos; array.end = end === undefined ? scanner.getStartPos() : end; return array; } function finishNode(node, end) { node.end = end === undefined ? scanner.getStartPos() : end; if (contextFlags) { node.flags |= contextFlags; } // Keep track on the node if we encountered an error while parsing it. If we did, then // we cannot reuse the node incrementally. Once we've marked this node, clear out the // flag so that we don't mark any subsequent nodes. if (parseErrorBeforeNextFinishedNode) { parseErrorBeforeNextFinishedNode = false; node.flags |= 32768 /* ThisNodeHasError */; } return node; } function createMissingNode(kind, reportAtCurrentPosition, diagnosticMessage, arg0) { if (reportAtCurrentPosition) { parseErrorAtPosition(scanner.getStartPos(), 0, diagnosticMessage, arg0); } else { parseErrorAtCurrentToken(diagnosticMessage, arg0); } var result = createNode(kind); if (kind === 71 /* Identifier */) { result.escapedText = ""; } else if (ts.isLiteralKind(kind) || ts.isTemplateLiteralKind(kind)) { result.text = ""; } return finishNode(result); } function internIdentifier(text) { var identifier = identifiers.get(text); if (identifier === undefined) { identifiers.set(text, identifier = text); } return identifier; } // An identifier that starts with two underscores has an extra underscore character prepended to it to avoid issues // with magic property names like '__proto__'. The 'identifiers' object is used to share a single string instance for // each identifier in order to reduce memory consumption. function createIdentifier(isIdentifier, diagnosticMessage) { identifierCount++; if (isIdentifier) { var node = createNode(71 /* Identifier */); // Store original token kind if it is not just an Identifier so we can report appropriate error later in type checker if (token() !== 71 /* Identifier */) { node.originalKeywordKind = token(); } node.escapedText = ts.escapeLeadingUnderscores(internIdentifier(scanner.getTokenValue())); nextToken(); return finishNode(node); } // Only for end of file because the error gets reported incorrectly on embedded script tags. var reportAtCurrentPosition = token() === 1 /* EndOfFileToken */; return createMissingNode(71 /* Identifier */, reportAtCurrentPosition, diagnosticMessage || ts.Diagnostics.Identifier_expected); } function parseIdentifier(diagnosticMessage) { return createIdentifier(isIdentifier(), diagnosticMessage); } function parseIdentifierName(diagnosticMessage) { return createIdentifier(ts.tokenIsIdentifierOrKeyword(token()), diagnosticMessage); } function isLiteralPropertyName() { return ts.tokenIsIdentifierOrKeyword(token()) || token() === 9 /* StringLiteral */ || token() === 8 /* NumericLiteral */; } function parsePropertyNameWorker(allowComputedPropertyNames) { if (token() === 9 /* StringLiteral */ || token() === 8 /* NumericLiteral */) { var node = parseLiteralNode(); node.text = internIdentifier(node.text); return node; } if (allowComputedPropertyNames && token() === 21 /* OpenBracketToken */) { return parseComputedPropertyName(); } return parseIdentifierName(); } function parsePropertyName() { return parsePropertyNameWorker(/*allowComputedPropertyNames*/ true); } function parseComputedPropertyName() { // PropertyName [Yield]: // LiteralPropertyName // ComputedPropertyName[?Yield] var node = createNode(145 /* ComputedPropertyName */); parseExpected(21 /* OpenBracketToken */); // We parse any expression (including a comma expression). But the grammar // says that only an assignment expression is allowed, so the grammar checker // will error if it sees a comma expression. node.expression = allowInAnd(parseExpression); parseExpected(22 /* CloseBracketToken */); return finishNode(node); } function parseContextualModifier(t) { return token() === t && tryParse(nextTokenCanFollowModifier); } function nextTokenIsOnSameLineAndCanFollowModifier() { nextToken(); if (scanner.hasPrecedingLineBreak()) { return false; } return canFollowModifier(); } function nextTokenCanFollowModifier() { if (token() === 76 /* ConstKeyword */) { // 'const' is only a modifier if followed by 'enum'. return nextToken() === 83 /* EnumKeyword */; } if (token() === 84 /* ExportKeyword */) { nextToken(); if (token() === 79 /* DefaultKeyword */) { return lookAhead(nextTokenCanFollowDefaultKeyword); } return token() !== 39 /* AsteriskToken */ && token() !== 118 /* AsKeyword */ && token() !== 17 /* OpenBraceToken */ && canFollowModifier(); } if (token() === 79 /* DefaultKeyword */) { return nextTokenCanFollowDefaultKeyword(); } if (token() === 115 /* StaticKeyword */) { nextToken(); return canFollowModifier(); } return nextTokenIsOnSameLineAndCanFollowModifier(); } function parseAnyContextualModifier() { return ts.isModifierKind(token()) && tryParse(nextTokenCanFollowModifier); } function canFollowModifier() { return token() === 21 /* OpenBracketToken */ || token() === 17 /* OpenBraceToken */ || token() === 39 /* AsteriskToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName(); } function nextTokenCanFollowDefaultKeyword() { nextToken(); return token() === 75 /* ClassKeyword */ || token() === 89 /* FunctionKeyword */ || token() === 109 /* InterfaceKeyword */ || (token() === 117 /* AbstractKeyword */ && lookAhead(nextTokenIsClassKeywordOnSameLine)) || (token() === 120 /* AsyncKeyword */ && lookAhead(nextTokenIsFunctionKeywordOnSameLine)); } // True if positioned at the start of a list element function isListElement(parsingContext, inErrorRecovery) { var node = currentNode(parsingContext); if (node) { return true; } switch (parsingContext) { case 0 /* SourceElements */: case 1 /* BlockStatements */: case 3 /* SwitchClauseStatements */: // If we're in error recovery, then we don't want to treat ';' as an empty statement. // The problem is that ';' can show up in far too many contexts, and if we see one // and assume it's a statement, then we may bail out inappropriately from whatever // we're parsing. For example, if we have a semicolon in the middle of a class, then // we really don't want to assume the class is over and we're on a statement in the // outer module. We just want to consume and move on. return !(token() === 25 /* SemicolonToken */ && inErrorRecovery) && isStartOfStatement(); case 2 /* SwitchClauses */: return token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */; case 4 /* TypeMembers */: return lookAhead(isTypeMemberStart); case 5 /* ClassMembers */: // We allow semicolons as class elements (as specified by ES6) as long as we're // not in error recovery. If we're in error recovery, we don't want an errant // semicolon to be treated as a class member (since they're almost always used // for statements. return lookAhead(isClassMemberStart) || (token() === 25 /* SemicolonToken */ && !inErrorRecovery); case 6 /* EnumMembers */: // Include open bracket computed properties. This technically also lets in indexers, // which would be a candidate for improved error reporting. return token() === 21 /* OpenBracketToken */ || isLiteralPropertyName(); case 12 /* ObjectLiteralMembers */: return token() === 21 /* OpenBracketToken */ || token() === 39 /* AsteriskToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName(); case 17 /* RestProperties */: return isLiteralPropertyName(); case 9 /* ObjectBindingElements */: return token() === 21 /* OpenBracketToken */ || token() === 24 /* DotDotDotToken */ || isLiteralPropertyName(); case 7 /* HeritageClauseElement */: // If we see `{ ... }` then only consume it as an expression if it is followed by `,` or `{` // That way we won't consume the body of a class in its heritage clause. if (token() === 17 /* OpenBraceToken */) { return lookAhead(isValidHeritageClauseObjectLiteral); } if (!inErrorRecovery) { return isStartOfLeftHandSideExpression() && !isHeritageClauseExtendsOrImplementsKeyword(); } else { // If we're in error recovery we tighten up what we're willing to match. // That way we don't treat something like "this" as a valid heritage clause // element during recovery. return isIdentifier() && !isHeritageClauseExtendsOrImplementsKeyword(); } case 8 /* VariableDeclarations */: return isIdentifierOrPattern(); case 10 /* ArrayBindingElements */: return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern(); case 18 /* TypeParameters */: return isIdentifier(); case 11 /* ArgumentExpressions */: case 15 /* ArrayLiteralMembers */: return token() === 26 /* CommaToken */ || token() === 24 /* DotDotDotToken */ || isStartOfExpression(); case 16 /* Parameters */: return isStartOfParameter(); case 19 /* TypeArguments */: case 20 /* TupleElementTypes */: return token() === 26 /* CommaToken */ || isStartOfType(); case 21 /* HeritageClauses */: return isHeritageClause(); case 22 /* ImportOrExportSpecifiers */: return ts.tokenIsIdentifierOrKeyword(token()); case 13 /* JsxAttributes */: return ts.tokenIsIdentifierOrKeyword(token()) || token() === 17 /* OpenBraceToken */; case 14 /* JsxChildren */: return true; } ts.Debug.fail("Non-exhaustive case in 'isListElement'."); } function isValidHeritageClauseObjectLiteral() { ts.Debug.assert(token() === 17 /* OpenBraceToken */); if (nextToken() === 18 /* CloseBraceToken */) { // if we see "extends {}" then only treat the {} as what we're extending (and not // the class body) if we have: // // extends {} { // extends {}, // extends {} extends // extends {} implements var next = nextToken(); return next === 26 /* CommaToken */ || next === 17 /* OpenBraceToken */ || next === 85 /* ExtendsKeyword */ || next === 108 /* ImplementsKeyword */; } return true; } function nextTokenIsIdentifier() { nextToken(); return isIdentifier(); } function nextTokenIsIdentifierOrKeyword() { nextToken(); return ts.tokenIsIdentifierOrKeyword(token()); } function nextTokenIsIdentifierOrKeywordOrGreaterThan() { nextToken(); return ts.tokenIsIdentifierOrKeywordOrGreaterThan(token()); } function isHeritageClauseExtendsOrImplementsKeyword() { if (token() === 108 /* ImplementsKeyword */ || token() === 85 /* ExtendsKeyword */) { return lookAhead(nextTokenIsStartOfExpression); } return false; } function nextTokenIsStartOfExpression() { nextToken(); return isStartOfExpression(); } // True if positioned at a list terminator function isListTerminator(kind) { if (token() === 1 /* EndOfFileToken */) { // Being at the end of the file ends all lists. return true; } switch (kind) { case 1 /* BlockStatements */: case 2 /* SwitchClauses */: case 4 /* TypeMembers */: case 5 /* ClassMembers */: case 6 /* EnumMembers */: case 12 /* ObjectLiteralMembers */: case 9 /* ObjectBindingElements */: case 22 /* ImportOrExportSpecifiers */: return token() === 18 /* CloseBraceToken */; case 3 /* SwitchClauseStatements */: return token() === 18 /* CloseBraceToken */ || token() === 73 /* CaseKeyword */ || token() === 79 /* DefaultKeyword */; case 7 /* HeritageClauseElement */: return token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */; case 8 /* VariableDeclarations */: return isVariableDeclaratorListTerminator(); case 18 /* TypeParameters */: // Tokens other than '>' are here for better error recovery return token() === 29 /* GreaterThanToken */ || token() === 19 /* OpenParenToken */ || token() === 17 /* OpenBraceToken */ || token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */; case 11 /* ArgumentExpressions */: // Tokens other than ')' are here for better error recovery return token() === 20 /* CloseParenToken */ || token() === 25 /* SemicolonToken */; case 15 /* ArrayLiteralMembers */: case 20 /* TupleElementTypes */: case 10 /* ArrayBindingElements */: return token() === 22 /* CloseBracketToken */; case 16 /* Parameters */: case 17 /* RestProperties */: // Tokens other than ')' and ']' (the latter for index signatures) are here for better error recovery return token() === 20 /* CloseParenToken */ || token() === 22 /* CloseBracketToken */ /*|| token === SyntaxKind.OpenBraceToken*/; case 19 /* TypeArguments */: // All other tokens should cause the type-argument to terminate except comma token return token() !== 26 /* CommaToken */; case 21 /* HeritageClauses */: return token() === 17 /* OpenBraceToken */ || token() === 18 /* CloseBraceToken */; case 13 /* JsxAttributes */: return token() === 29 /* GreaterThanToken */ || token() === 41 /* SlashToken */; case 14 /* JsxChildren */: return token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsSlash); } } function isVariableDeclaratorListTerminator() { // If we can consume a semicolon (either explicitly, or with ASI), then consider us done // with parsing the list of variable declarators. if (canParseSemicolon()) { return true; } // in the case where we're parsing the variable declarator of a 'for-in' statement, we // are done if we see an 'in' keyword in front of us. Same with for-of if (isInOrOfKeyword(token())) { return true; } // ERROR RECOVERY TWEAK: // For better error recovery, if we see an '=>' then we just stop immediately. We've got an // arrow function here and it's going to be very unlikely that we'll resynchronize and get // another variable declaration. if (token() === 36 /* EqualsGreaterThanToken */) { return true; } // Keep trying to parse out variable declarators. return false; } // True if positioned at element or terminator of the current list or any enclosing list function isInSomeParsingContext() { for (var kind = 0; kind < 23 /* Count */; kind++) { if (parsingContext & (1 << kind)) { if (isListElement(kind, /*inErrorRecovery*/ true) || isListTerminator(kind)) { return true; } } } return false; } // Parses a list of elements function parseList(kind, parseElement) { var saveParsingContext = parsingContext; parsingContext |= 1 << kind; var list = []; var listPos = getNodePos(); while (!isListTerminator(kind)) { if (isListElement(kind, /*inErrorRecovery*/ false)) { var element = parseListElement(kind, parseElement); list.push(element); continue; } if (abortParsingListOrMoveToNextToken(kind)) { break; } } parsingContext = saveParsingContext; return createNodeArray(list, listPos); } function parseListElement(parsingContext, parseElement) { var node = currentNode(parsingContext); if (node) { return consumeNode(node); } return parseElement(); } function currentNode(parsingContext) { // If there is an outstanding parse error that we've encountered, but not attached to // some node, then we cannot get a node from the old source tree. This is because we // want to mark the next node we encounter as being unusable. // // Note: This may be too conservative. Perhaps we could reuse the node and set the bit // on it (or its leftmost child) as having the error. For now though, being conservative // is nice and likely won't ever affect perf. if (parseErrorBeforeNextFinishedNode) { return undefined; } if (!syntaxCursor) { // if we don't have a cursor, we could never return a node from the old tree. return undefined; } var node = syntaxCursor.currentNode(scanner.getStartPos()); // Can't reuse a missing node. if (ts.nodeIsMissing(node)) { return undefined; } // Can't reuse a node that intersected the change range. if (node.intersectsChange) { return undefined; } // Can't reuse a node that contains a parse error. This is necessary so that we // produce the same set of errors again. if (ts.containsParseError(node)) { return undefined; } // We can only reuse a node if it was parsed under the same strict mode that we're // currently in. i.e. if we originally parsed a node in non-strict mode, but then // the user added 'using strict' at the top of the file, then we can't use that node // again as the presence of strict mode may cause us to parse the tokens in the file // differently. // // Note: we *can* reuse tokens when the strict mode changes. That's because tokens // are unaffected by strict mode. It's just the parser will decide what to do with it // differently depending on what mode it is in. // // This also applies to all our other context flags as well. var nodeContextFlags = node.flags & 6387712 /* ContextFlags */; if (nodeContextFlags !== contextFlags) { return undefined; } // Ok, we have a node that looks like it could be reused. Now verify that it is valid // in the current list parsing context that we're currently at. if (!canReuseNode(node, parsingContext)) { return undefined; } return node; } function consumeNode(node) { // Move the scanner so it is after the node we just consumed. scanner.setTextPos(node.end); nextToken(); return node; } function canReuseNode(node, parsingContext) { switch (parsingContext) { case 5 /* ClassMembers */: return isReusableClassMember(node); case 2 /* SwitchClauses */: return isReusableSwitchClause(node); case 0 /* SourceElements */: case 1 /* BlockStatements */: case 3 /* SwitchClauseStatements */: return isReusableStatement(node); case 6 /* EnumMembers */: return isReusableEnumMember(node); case 4 /* TypeMembers */: return isReusableTypeMember(node); case 8 /* VariableDeclarations */: return isReusableVariableDeclaration(node); case 16 /* Parameters */: return isReusableParameter(node); case 17 /* RestProperties */: return false; // Any other lists we do not care about reusing nodes in. But feel free to add if // you can do so safely. Danger areas involve nodes that may involve speculative // parsing. If speculative parsing is involved with the node, then the range the // parser reached while looking ahead might be in the edited range (see the example // in canReuseVariableDeclaratorNode for a good case of this). case 21 /* HeritageClauses */: // This would probably be safe to reuse. There is no speculative parsing with // heritage clauses. case 18 /* TypeParameters */: // This would probably be safe to reuse. There is no speculative parsing with // type parameters. Note that that's because type *parameters* only occur in // unambiguous *type* contexts. While type *arguments* occur in very ambiguous // *expression* contexts. case 20 /* TupleElementTypes */: // This would probably be safe to reuse. There is no speculative parsing with // tuple types. // Technically, type argument list types are probably safe to reuse. While // speculative parsing is involved with them (since type argument lists are only // produced from speculative parsing a < as a type argument list), we only have // the types because speculative parsing succeeded. Thus, the lookahead never // went past the end of the list and rewound. case 19 /* TypeArguments */: // Note: these are almost certainly not safe to ever reuse. Expressions commonly // need a large amount of lookahead, and we should not reuse them as they may // have actually intersected the edit. case 11 /* ArgumentExpressions */: // This is not safe to reuse for the same reason as the 'AssignmentExpression' // cases. i.e. a property assignment may end with an expression, and thus might // have lookahead far beyond it's old node. case 12 /* ObjectLiteralMembers */: // This is probably not safe to reuse. There can be speculative parsing with // type names in a heritage clause. There can be generic names in the type // name list, and there can be left hand side expressions (which can have type // arguments.) case 7 /* HeritageClauseElement */: // Perhaps safe to reuse, but it's unlikely we'd see more than a dozen attributes // on any given element. Same for children. case 13 /* JsxAttributes */: case 14 /* JsxChildren */: } return false; } function isReusableClassMember(node) { if (node) { switch (node.kind) { case 153 /* Constructor */: case 158 /* IndexSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 150 /* PropertyDeclaration */: case 207 /* SemicolonClassElement */: return true; case 152 /* MethodDeclaration */: // Method declarations are not necessarily reusable. An object-literal // may have a method calls "constructor(...)" and we must reparse that // into an actual .ConstructorDeclaration. var methodDeclaration = node; var nameIsConstructor = methodDeclaration.name.kind === 71 /* Identifier */ && methodDeclaration.name.originalKeywordKind === 123 /* ConstructorKeyword */; return !nameIsConstructor; } } return false; } function isReusableSwitchClause(node) { if (node) { switch (node.kind) { case 261 /* CaseClause */: case 262 /* DefaultClause */: return true; } } return false; } function isReusableStatement(node) { if (node) { switch (node.kind) { case 229 /* FunctionDeclaration */: case 209 /* VariableStatement */: case 208 /* Block */: case 212 /* IfStatement */: case 211 /* ExpressionStatement */: case 224 /* ThrowStatement */: case 220 /* ReturnStatement */: case 222 /* SwitchStatement */: case 219 /* BreakStatement */: case 218 /* ContinueStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 215 /* ForStatement */: case 214 /* WhileStatement */: case 221 /* WithStatement */: case 210 /* EmptyStatement */: case 225 /* TryStatement */: case 223 /* LabeledStatement */: case 213 /* DoStatement */: case 226 /* DebuggerStatement */: case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: case 245 /* ExportDeclaration */: case 244 /* ExportAssignment */: case 234 /* ModuleDeclaration */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 232 /* TypeAliasDeclaration */: return true; } } return false; } function isReusableEnumMember(node) { return node.kind === 268 /* EnumMember */; } function isReusableTypeMember(node) { if (node) { switch (node.kind) { case 157 /* ConstructSignature */: case 151 /* MethodSignature */: case 158 /* IndexSignature */: case 149 /* PropertySignature */: case 156 /* CallSignature */: return true; } } return false; } function isReusableVariableDeclaration(node) { if (node.kind !== 227 /* 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() // // then we have a problem. "v = new List= 0) { // Always preserve a trailing comma by marking it on the NodeArray result.hasTrailingComma = true; } return result; } function createMissingList() { return createNodeArray([], getNodePos()); } function parseBracketedList(kind, parseElement, open, close) { if (parseExpected(open)) { var result = parseDelimitedList(kind, parseElement); parseExpected(close); return result; } return createMissingList(); } function parseEntityName(allowReservedWords, diagnosticMessage) { var entity = allowReservedWords ? parseIdentifierName(diagnosticMessage) : parseIdentifier(diagnosticMessage); var dotPos = scanner.getStartPos(); while (parseOptional(23 /* DotToken */)) { if (token() === 27 /* LessThanToken */) { // the entity is part of a JSDoc-style generic, so record the trailing dot for later error reporting entity.jsdocDotPos = dotPos; break; } dotPos = scanner.getStartPos(); entity = createQualifiedName(entity, parseRightSideOfDot(allowReservedWords)); } return entity; } function createQualifiedName(entity, name) { var node = createNode(144 /* QualifiedName */, entity.pos); node.left = entity; node.right = name; return finishNode(node); } function parseRightSideOfDot(allowIdentifierNames) { // Technically a keyword is valid here as all identifiers and keywords are identifier names. // However, often we'll encounter this in error situations when the identifier or keyword // is actually starting another valid construct. // // So, we check for the following specific case: // // name. // identifierOrKeyword identifierNameOrKeyword // // Note: the newlines are important here. For example, if that above code // were rewritten into: // // name.identifierOrKeyword // identifierNameOrKeyword // // Then we would consider it valid. That's because ASI would take effect and // the code would be implicitly: "name.identifierOrKeyword; identifierNameOrKeyword". // In the first case though, ASI will not take effect because there is not a // line terminator after the identifier or keyword. if (scanner.hasPrecedingLineBreak() && ts.tokenIsIdentifierOrKeyword(token())) { var matchesPattern = lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); if (matchesPattern) { // Report that we need an identifier. However, report it right after the dot, // and not on the next token. This is because the next token might actually // be an identifier and the error would be quite confusing. return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected); } } return allowIdentifierNames ? parseIdentifierName() : parseIdentifier(); } function parseTemplateExpression() { var template = createNode(197 /* TemplateExpression */); template.head = parseTemplateHead(); ts.Debug.assert(template.head.kind === 14 /* TemplateHead */, "Template head has wrong token kind"); var list = []; var listPos = getNodePos(); do { list.push(parseTemplateSpan()); } while (ts.lastOrUndefined(list).literal.kind === 15 /* TemplateMiddle */); template.templateSpans = createNodeArray(list, listPos); return finishNode(template); } function parseTemplateSpan() { var span = createNode(206 /* TemplateSpan */); span.expression = allowInAnd(parseExpression); var literal; if (token() === 18 /* CloseBraceToken */) { reScanTemplateToken(); literal = parseTemplateMiddleOrTemplateTail(); } else { literal = parseExpectedToken(16 /* TemplateTail */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(18 /* CloseBraceToken */)); } span.literal = literal; return finishNode(span); } function parseLiteralNode() { return parseLiteralLikeNode(token()); } function parseTemplateHead() { var fragment = parseLiteralLikeNode(token()); ts.Debug.assert(fragment.kind === 14 /* TemplateHead */, "Template head has wrong token kind"); return fragment; } function parseTemplateMiddleOrTemplateTail() { var fragment = parseLiteralLikeNode(token()); ts.Debug.assert(fragment.kind === 15 /* TemplateMiddle */ || fragment.kind === 16 /* TemplateTail */, "Template fragment has wrong token kind"); return fragment; } function parseLiteralLikeNode(kind) { var node = createNode(kind); var text = scanner.getTokenValue(); node.text = text; if (scanner.hasExtendedUnicodeEscape()) { node.hasExtendedUnicodeEscape = true; } if (scanner.isUnterminated()) { node.isUnterminated = true; } // Octal literals are not allowed in strict mode or ES5 // Note that theoretically the following condition would hold true literals like 009, // which is not octal.But because of how the scanner separates the tokens, we would // never get a token like this. Instead, we would get 00 and 9 as two separate tokens. // We also do not need to check for negatives because any prefix operator would be part of a // parent unary expression. if (node.kind === 8 /* NumericLiteral */) { node.numericLiteralFlags = scanner.getTokenFlags() & 496 /* NumericLiteralFlags */; } nextToken(); finishNode(node); return node; } // TYPES function parseTypeReference() { var node = createNode(160 /* TypeReference */); node.typeName = parseEntityName(/*allowReservedWords*/ true, ts.Diagnostics.Type_expected); if (!scanner.hasPrecedingLineBreak() && token() === 27 /* LessThanToken */) { node.typeArguments = parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */); } return finishNode(node); } function parseThisTypePredicate(lhs) { nextToken(); var node = createNode(159 /* TypePredicate */, lhs.pos); node.parameterName = lhs; node.type = parseType(); return finishNode(node); } function parseThisTypeNode() { var node = createNode(170 /* ThisType */); nextToken(); return finishNode(node); } function parseJSDocAllType() { var result = createNode(272 /* JSDocAllType */); nextToken(); return finishNode(result); } function parseJSDocUnknownOrNullableType() { var pos = scanner.getStartPos(); // skip the ? nextToken(); // Need to lookahead to decide if this is a nullable or unknown type. // Here are cases where we'll pick the unknown type: // // Foo(?, // { a: ? } // Foo(?) // Foo // Foo(?= // (?| if (token() === 26 /* CommaToken */ || token() === 18 /* CloseBraceToken */ || token() === 20 /* CloseParenToken */ || token() === 29 /* GreaterThanToken */ || token() === 58 /* EqualsToken */ || token() === 49 /* BarToken */) { var result = createNode(273 /* JSDocUnknownType */, pos); return finishNode(result); } else { var result = createNode(274 /* JSDocNullableType */, pos); result.type = parseType(); return finishNode(result); } } function parseJSDocFunctionType() { if (lookAhead(nextTokenIsOpenParen)) { var result = createNodeWithJSDoc(277 /* JSDocFunctionType */); nextToken(); fillSignature(56 /* ColonToken */, 4 /* Type */ | 32 /* JSDoc */, result); return finishNode(result); } var node = createNode(160 /* TypeReference */); node.typeName = parseIdentifierName(); return finishNode(node); } function parseJSDocParameter() { var parameter = createNode(147 /* Parameter */); if (token() === 99 /* ThisKeyword */ || token() === 94 /* NewKeyword */) { parameter.name = parseIdentifierName(); parseExpected(56 /* ColonToken */); } parameter.type = parseType(); return finishNode(parameter); } function parseJSDocNodeWithType(kind) { var result = createNode(kind); nextToken(); result.type = parseNonArrayType(); return finishNode(result); } function parseTypeQuery() { var node = createNode(163 /* TypeQuery */); parseExpected(103 /* TypeOfKeyword */); node.exprName = parseEntityName(/*allowReservedWords*/ true); return finishNode(node); } function parseTypeParameter() { var node = createNode(146 /* TypeParameter */); node.name = parseIdentifier(); if (parseOptional(85 /* ExtendsKeyword */)) { // It's not uncommon for people to write improper constraints to a generic. If the // user writes a constraint that is an expression and not an actual type, then parse // it out as an expression (so we can recover well), but report that a type is needed // instead. if (isStartOfType() || !isStartOfExpression()) { node.constraint = parseType(); } else { // It was not a type, and it looked like an expression. Parse out an expression // here so we recover well. Note: it is important that we call parseUnaryExpression // and not parseExpression here. If the user has: // // // // We do *not* want to consume the > as we're consuming the expression for "". node.expression = parseUnaryExpressionOrHigher(); } } if (parseOptional(58 /* EqualsToken */)) { node.default = parseType(); } return finishNode(node); } function parseTypeParameters() { if (token() === 27 /* LessThanToken */) { return parseBracketedList(18 /* TypeParameters */, parseTypeParameter, 27 /* LessThanToken */, 29 /* GreaterThanToken */); } } function parseParameterType() { if (parseOptional(56 /* ColonToken */)) { return parseType(); } return undefined; } function isStartOfParameter() { return token() === 24 /* DotDotDotToken */ || isIdentifierOrPattern() || ts.isModifierKind(token()) || token() === 57 /* AtToken */ || isStartOfType(/*inStartOfParameter*/ true); } function parseParameter() { var node = createNodeWithJSDoc(147 /* Parameter */); if (token() === 99 /* ThisKeyword */) { node.name = createIdentifier(/*isIdentifier*/ true); node.type = parseParameterType(); return finishNode(node); } node.decorators = parseDecorators(); node.modifiers = parseModifiers(); node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */); // FormalParameter [Yield,Await]: // BindingElement[?Yield,?Await] node.name = parseIdentifierOrPattern(); if (ts.getFullWidth(node.name) === 0 && !ts.hasModifiers(node) && ts.isModifierKind(token())) { // in cases like // 'use strict' // function foo(static) // isParameter('static') === true, because of isModifier('static') // however 'static' is not a legal identifier in a strict mode. // so result of this function will be ParameterDeclaration (flags = 0, name = missing, type = undefined, initializer = undefined) // and current token will not change => parsing of the enclosing parameter list will last till the end of time (or OOM) // to avoid this we'll advance cursor to the next token. nextToken(); } node.questionToken = parseOptionalToken(55 /* QuestionToken */); node.type = parseParameterType(); node.initializer = parseInitializer(); return finishNode(node); } function fillSignature(returnToken, flags, signature) { if (!(flags & 32 /* JSDoc */)) { signature.typeParameters = parseTypeParameters(); } signature.parameters = parseParameterList(flags); signature.type = parseReturnType(returnToken, !!(flags & 4 /* Type */)); } function parseReturnType(returnToken, isType) { return shouldParseReturnType(returnToken, isType) ? parseTypeOrTypePredicate() : undefined; } function shouldParseReturnType(returnToken, isType) { if (returnToken === 36 /* EqualsGreaterThanToken */) { parseExpected(returnToken); return true; } else if (parseOptional(56 /* ColonToken */)) { return true; } else if (isType && token() === 36 /* EqualsGreaterThanToken */) { // This is easy to get backward, especially in type contexts, so parse the type anyway parseErrorAtCurrentToken(ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */)); nextToken(); return true; } return false; } function parseParameterList(flags) { // FormalParameters [Yield,Await]: (modified) // [empty] // FormalParameterList[?Yield,Await] // // FormalParameter[Yield,Await]: (modified) // BindingElement[?Yield,Await] // // BindingElement [Yield,Await]: (modified) // SingleNameBinding[?Yield,?Await] // BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt // // SingleNameBinding [Yield,Await]: // BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt if (parseExpected(19 /* OpenParenToken */)) { var savedYieldContext = inYieldContext(); var savedAwaitContext = inAwaitContext(); setYieldContext(!!(flags & 1 /* Yield */)); setAwaitContext(!!(flags & 2 /* Await */)); var result = parseDelimitedList(16 /* Parameters */, flags & 32 /* JSDoc */ ? parseJSDocParameter : parseParameter); setYieldContext(savedYieldContext); setAwaitContext(savedAwaitContext); if (!parseExpected(20 /* CloseParenToken */) && (flags & 8 /* RequireCompleteParameterList */)) { // Caller insisted that we had to end with a ) We didn't. So just return // undefined here. return undefined; } return result; } // We didn't even have an open paren. If the caller requires a complete parameter list, // we definitely can't provide that. However, if they're ok with an incomplete one, // then just return an empty set of parameters. return (flags & 8 /* RequireCompleteParameterList */) ? undefined : createMissingList(); } function parseTypeMemberSemicolon() { // We allow type members to be separated by commas or (possibly ASI) semicolons. // First check if it was a comma. If so, we're done with the member. if (parseOptional(26 /* CommaToken */)) { return; } // Didn't have a comma. We must have a (possible ASI) semicolon. parseSemicolon(); } function parseSignatureMember(kind) { var node = createNodeWithJSDoc(kind); if (kind === 157 /* ConstructSignature */) { parseExpected(94 /* NewKeyword */); } fillSignature(56 /* ColonToken */, 4 /* Type */, node); parseTypeMemberSemicolon(); return finishNode(node); } function isIndexSignature() { return token() === 21 /* OpenBracketToken */ && lookAhead(isUnambiguouslyIndexSignature); } function isUnambiguouslyIndexSignature() { // The only allowed sequence is: // // [id: // // However, for error recovery, we also check the following cases: // // [... // [id, // [id?, // [id?: // [id?] // [public id // [private id // [protected id // [] // nextToken(); if (token() === 24 /* DotDotDotToken */ || token() === 22 /* CloseBracketToken */) { return true; } if (ts.isModifierKind(token())) { nextToken(); if (isIdentifier()) { return true; } } else if (!isIdentifier()) { return false; } else { // Skip the identifier nextToken(); } // A colon signifies a well formed indexer // A comma should be a badly formed indexer because comma expressions are not allowed // in computed properties. if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */) { return true; } // Question mark could be an indexer with an optional property, // or it could be a conditional expression in a computed property. if (token() !== 55 /* QuestionToken */) { return false; } // If any of the following tokens are after the question mark, it cannot // be a conditional expression, so treat it as an indexer. nextToken(); return token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || token() === 22 /* CloseBracketToken */; } function parseIndexSignatureDeclaration(node) { node.kind = 158 /* IndexSignature */; node.parameters = parseBracketedList(16 /* Parameters */, parseParameter, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */); node.type = parseTypeAnnotation(); parseTypeMemberSemicolon(); return finishNode(node); } function parsePropertyOrMethodSignature(node) { node.name = parsePropertyName(); node.questionToken = parseOptionalToken(55 /* QuestionToken */); if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) { node.kind = 151 /* MethodSignature */; // Method signatures don't exist in expression contexts. So they have neither // [Yield] nor [Await] fillSignature(56 /* ColonToken */, 4 /* Type */, node); } else { node.kind = 149 /* PropertySignature */; node.type = parseTypeAnnotation(); if (token() === 58 /* EqualsToken */) { // Although type literal properties cannot not have initializers, we attempt // to parse an initializer so we can report in the checker that an interface // property or type literal property cannot have an initializer. node.initializer = parseInitializer(); } } parseTypeMemberSemicolon(); return finishNode(node); } function isTypeMemberStart() { // Return true if we have the start of a signature member if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) { return true; } var idToken; // Eat up all modifiers, but hold on to the last one in case it is actually an identifier while (ts.isModifierKind(token())) { idToken = true; nextToken(); } // Index signatures and computed property names are type members if (token() === 21 /* OpenBracketToken */) { return true; } // Try to get the first property-like token following all modifiers if (isLiteralPropertyName()) { idToken = true; nextToken(); } // If we were able to get any potential identifier, check that it is // the start of a member declaration if (idToken) { return token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */ || token() === 55 /* QuestionToken */ || token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || canParseSemicolon(); } return false; } function parseTypeMember() { if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) { return parseSignatureMember(156 /* CallSignature */); } if (token() === 94 /* NewKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) { return parseSignatureMember(157 /* ConstructSignature */); } var node = createNodeWithJSDoc(0 /* Unknown */); node.modifiers = parseModifiers(); if (isIndexSignature()) { return parseIndexSignatureDeclaration(node); } return parsePropertyOrMethodSignature(node); } function nextTokenIsOpenParenOrLessThan() { nextToken(); return token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */; } function parseTypeLiteral() { var node = createNode(164 /* TypeLiteral */); node.members = parseObjectTypeMembers(); return finishNode(node); } function parseObjectTypeMembers() { var members; if (parseExpected(17 /* OpenBraceToken */)) { members = parseList(4 /* TypeMembers */, parseTypeMember); parseExpected(18 /* CloseBraceToken */); } else { members = createMissingList(); } return members; } function isStartOfMappedType() { nextToken(); if (token() === 131 /* ReadonlyKeyword */) { nextToken(); } return token() === 21 /* OpenBracketToken */ && nextTokenIsIdentifier() && nextToken() === 92 /* InKeyword */; } function parseMappedTypeParameter() { var node = createNode(146 /* TypeParameter */); node.name = parseIdentifier(); parseExpected(92 /* InKeyword */); node.constraint = parseType(); return finishNode(node); } function parseMappedType() { var node = createNode(173 /* MappedType */); parseExpected(17 /* OpenBraceToken */); node.readonlyToken = parseOptionalToken(131 /* ReadonlyKeyword */); parseExpected(21 /* OpenBracketToken */); node.typeParameter = parseMappedTypeParameter(); parseExpected(22 /* CloseBracketToken */); node.questionToken = parseOptionalToken(55 /* QuestionToken */); node.type = parseTypeAnnotation(); parseSemicolon(); parseExpected(18 /* CloseBraceToken */); return finishNode(node); } function parseTupleType() { var node = createNode(166 /* TupleType */); node.elementTypes = parseBracketedList(20 /* TupleElementTypes */, parseType, 21 /* OpenBracketToken */, 22 /* CloseBracketToken */); return finishNode(node); } function parseParenthesizedType() { var node = createNode(169 /* ParenthesizedType */); parseExpected(19 /* OpenParenToken */); node.type = parseType(); parseExpected(20 /* CloseParenToken */); return finishNode(node); } function parseFunctionOrConstructorType(kind) { var node = createNodeWithJSDoc(kind); if (kind === 162 /* ConstructorType */) { parseExpected(94 /* NewKeyword */); } fillSignature(36 /* EqualsGreaterThanToken */, 4 /* Type */, node); return finishNode(node); } function parseKeywordAndNoDot() { var node = parseTokenNode(); return token() === 23 /* DotToken */ ? undefined : node; } function parseLiteralTypeNode(negative) { var node = createNode(174 /* LiteralType */); var unaryMinusExpression; if (negative) { unaryMinusExpression = createNode(193 /* PrefixUnaryExpression */); unaryMinusExpression.operator = 38 /* MinusToken */; nextToken(); } var expression = token() === 101 /* TrueKeyword */ || token() === 86 /* FalseKeyword */ ? parseTokenNode() : parseLiteralLikeNode(token()); if (negative) { unaryMinusExpression.operand = expression; finishNode(unaryMinusExpression); expression = unaryMinusExpression; } node.literal = expression; return finishNode(node); } function nextTokenIsNumericLiteral() { return nextToken() === 8 /* NumericLiteral */; } function parseNonArrayType() { switch (token()) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 137 /* SymbolKeyword */: case 122 /* BooleanKeyword */: case 139 /* UndefinedKeyword */: case 130 /* NeverKeyword */: case 134 /* ObjectKeyword */: // If these are followed by a dot, then parse these out as a dotted type reference instead. return tryParse(parseKeywordAndNoDot) || parseTypeReference(); case 39 /* AsteriskToken */: return parseJSDocAllType(); case 55 /* QuestionToken */: return parseJSDocUnknownOrNullableType(); case 89 /* FunctionKeyword */: return parseJSDocFunctionType(); case 51 /* ExclamationToken */: return parseJSDocNodeWithType(275 /* JSDocNonNullableType */); case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: return parseLiteralTypeNode(); case 38 /* MinusToken */: return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference(); case 105 /* VoidKeyword */: case 95 /* NullKeyword */: return parseTokenNode(); case 99 /* ThisKeyword */: { var thisKeyword = parseThisTypeNode(); if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) { return parseThisTypePredicate(thisKeyword); } else { return thisKeyword; } } case 103 /* TypeOfKeyword */: return parseTypeQuery(); case 17 /* OpenBraceToken */: return lookAhead(isStartOfMappedType) ? parseMappedType() : parseTypeLiteral(); case 21 /* OpenBracketToken */: return parseTupleType(); case 19 /* OpenParenToken */: return parseParenthesizedType(); default: return parseTypeReference(); } } function isStartOfType(inStartOfParameter) { switch (token()) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: case 140 /* UniqueKeyword */: case 105 /* VoidKeyword */: case 139 /* UndefinedKeyword */: case 95 /* NullKeyword */: case 99 /* ThisKeyword */: case 103 /* TypeOfKeyword */: case 130 /* NeverKeyword */: case 17 /* OpenBraceToken */: case 21 /* OpenBracketToken */: case 27 /* LessThanToken */: case 49 /* BarToken */: case 48 /* AmpersandToken */: case 94 /* NewKeyword */: case 9 /* StringLiteral */: case 8 /* NumericLiteral */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 134 /* ObjectKeyword */: case 39 /* AsteriskToken */: case 55 /* QuestionToken */: case 51 /* ExclamationToken */: case 24 /* DotDotDotToken */: return true; case 38 /* MinusToken */: return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral); case 19 /* OpenParenToken */: // Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier, // or something that starts a type. We don't want to consider things like '(1)' a type. return !inStartOfParameter && lookAhead(isStartOfParenthesizedOrFunctionType); default: return isIdentifier(); } } function isStartOfParenthesizedOrFunctionType() { nextToken(); return token() === 20 /* CloseParenToken */ || isStartOfParameter() || isStartOfType(); } function parsePostfixTypeOrHigher() { var type = parseNonArrayType(); while (!scanner.hasPrecedingLineBreak()) { switch (token()) { case 58 /* EqualsToken */: // only parse postfix = inside jsdoc, because it's ambiguous elsewhere if (!(contextFlags & 1048576 /* JSDoc */)) { return type; } type = createJSDocPostfixType(276 /* JSDocOptionalType */, type); break; case 51 /* ExclamationToken */: type = createJSDocPostfixType(275 /* JSDocNonNullableType */, type); break; case 55 /* QuestionToken */: type = createJSDocPostfixType(274 /* JSDocNullableType */, type); break; case 21 /* OpenBracketToken */: parseExpected(21 /* OpenBracketToken */); if (isStartOfType()) { var node = createNode(172 /* IndexedAccessType */, type.pos); node.objectType = type; node.indexType = parseType(); parseExpected(22 /* CloseBracketToken */); type = finishNode(node); } else { var node = createNode(165 /* ArrayType */, type.pos); node.elementType = type; parseExpected(22 /* CloseBracketToken */); type = finishNode(node); } break; default: return type; } } return type; } function createJSDocPostfixType(kind, type) { nextToken(); var postfix = createNode(kind, type.pos); postfix.type = type; return finishNode(postfix); } function parseTypeOperator(operator) { var node = createNode(171 /* TypeOperator */); parseExpected(operator); node.operator = operator; node.type = parseTypeOperatorOrHigher(); return finishNode(node); } function parseTypeOperatorOrHigher() { var operator = token(); switch (operator) { case 127 /* KeyOfKeyword */: case 140 /* UniqueKeyword */: return parseTypeOperator(operator); case 24 /* DotDotDotToken */: { var result = createNode(278 /* JSDocVariadicType */); nextToken(); result.type = parsePostfixTypeOrHigher(); return finishNode(result); } } return parsePostfixTypeOrHigher(); } function parseUnionOrIntersectionType(kind, parseConstituentType, operator) { parseOptional(operator); var type = parseConstituentType(); if (token() === operator) { var types = [type]; while (parseOptional(operator)) { types.push(parseConstituentType()); } var node = createNode(kind, type.pos); node.types = createNodeArray(types, type.pos); type = finishNode(node); } return type; } function parseIntersectionTypeOrHigher() { return parseUnionOrIntersectionType(168 /* IntersectionType */, parseTypeOperatorOrHigher, 48 /* AmpersandToken */); } function parseUnionTypeOrHigher() { return parseUnionOrIntersectionType(167 /* UnionType */, parseIntersectionTypeOrHigher, 49 /* BarToken */); } function isStartOfFunctionType() { if (token() === 27 /* LessThanToken */) { return true; } return token() === 19 /* OpenParenToken */ && lookAhead(isUnambiguouslyStartOfFunctionType); } function skipParameterStart() { if (ts.isModifierKind(token())) { // Skip modifiers parseModifiers(); } if (isIdentifier() || token() === 99 /* ThisKeyword */) { nextToken(); return true; } if (token() === 21 /* OpenBracketToken */ || token() === 17 /* OpenBraceToken */) { // Return true if we can parse an array or object binding pattern with no errors var previousErrorCount = parseDiagnostics.length; parseIdentifierOrPattern(); return previousErrorCount === parseDiagnostics.length; } return false; } function isUnambiguouslyStartOfFunctionType() { nextToken(); if (token() === 20 /* CloseParenToken */ || token() === 24 /* DotDotDotToken */) { // ( ) // ( ... return true; } if (skipParameterStart()) { // We successfully skipped modifiers (if any) and an identifier or binding pattern, // now see if we have something that indicates a parameter declaration if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || token() === 55 /* QuestionToken */ || token() === 58 /* EqualsToken */) { // ( xxx : // ( xxx , // ( xxx ? // ( xxx = return true; } if (token() === 20 /* CloseParenToken */) { nextToken(); if (token() === 36 /* EqualsGreaterThanToken */) { // ( xxx ) => return true; } } } return false; } function parseTypeOrTypePredicate() { var typePredicateVariable = isIdentifier() && tryParse(parseTypePredicatePrefix); var type = parseType(); if (typePredicateVariable) { var node = createNode(159 /* TypePredicate */, typePredicateVariable.pos); node.parameterName = typePredicateVariable; node.type = type; return finishNode(node); } else { return type; } } function parseTypePredicatePrefix() { var id = parseIdentifier(); if (token() === 126 /* IsKeyword */ && !scanner.hasPrecedingLineBreak()) { nextToken(); return id; } } function parseType() { // The rules about 'yield' only apply to actual code/expression contexts. They don't // apply to 'type' contexts. So we disable these parameters here before moving on. return doOutsideOfContext(20480 /* TypeExcludesFlags */, parseTypeWorker); } function parseTypeWorker() { if (isStartOfFunctionType()) { return parseFunctionOrConstructorType(161 /* FunctionType */); } if (token() === 94 /* NewKeyword */) { return parseFunctionOrConstructorType(162 /* ConstructorType */); } return parseUnionTypeOrHigher(); } function parseTypeAnnotation() { return parseOptional(56 /* ColonToken */) ? parseType() : undefined; } // EXPRESSIONS function isStartOfLeftHandSideExpression() { switch (token()) { case 99 /* ThisKeyword */: case 97 /* SuperKeyword */: case 95 /* NullKeyword */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 8 /* NumericLiteral */: case 9 /* StringLiteral */: case 13 /* NoSubstitutionTemplateLiteral */: case 14 /* TemplateHead */: case 19 /* OpenParenToken */: case 21 /* OpenBracketToken */: case 17 /* OpenBraceToken */: case 89 /* FunctionKeyword */: case 75 /* ClassKeyword */: case 94 /* NewKeyword */: case 41 /* SlashToken */: case 63 /* SlashEqualsToken */: case 71 /* Identifier */: return true; case 91 /* ImportKeyword */: return lookAhead(nextTokenIsOpenParenOrLessThan); default: return isIdentifier(); } } function isStartOfExpression() { if (isStartOfLeftHandSideExpression()) { return true; } switch (token()) { case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: case 51 /* ExclamationToken */: case 80 /* DeleteKeyword */: case 103 /* TypeOfKeyword */: case 105 /* VoidKeyword */: case 43 /* PlusPlusToken */: case 44 /* MinusMinusToken */: case 27 /* LessThanToken */: case 121 /* AwaitKeyword */: case 116 /* YieldKeyword */: // Yield/await always starts an expression. Either it is an identifier (in which case // it is definitely an expression). Or it's a keyword (either because we're in // a generator or async function, or in strict mode (or both)) and it started a yield or await expression. return true; default: // Error tolerance. If we see the start of some binary operator, we consider // that the start of an expression. That way we'll parse out a missing identifier, // give a good message about an identifier being missing, and then consume the // rest of the binary expression. if (isBinaryOperator()) { return true; } return isIdentifier(); } } function isStartOfExpressionStatement() { // As per the grammar, none of '{' or 'function' or 'class' can start an expression statement. return token() !== 17 /* OpenBraceToken */ && token() !== 89 /* FunctionKeyword */ && token() !== 75 /* ClassKeyword */ && token() !== 57 /* AtToken */ && isStartOfExpression(); } function parseExpression() { // Expression[in]: // AssignmentExpression[in] // Expression[in] , AssignmentExpression[in] // clear the decorator context when parsing Expression, as it should be unambiguous when parsing a decorator var saveDecoratorContext = inDecoratorContext(); if (saveDecoratorContext) { setDecoratorContext(/*val*/ false); } var expr = parseAssignmentExpressionOrHigher(); var operatorToken; while ((operatorToken = parseOptionalToken(26 /* CommaToken */))) { expr = makeBinaryExpression(expr, operatorToken, parseAssignmentExpressionOrHigher()); } if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } return expr; } function parseInitializer() { return parseOptional(58 /* EqualsToken */) ? parseAssignmentExpressionOrHigher() : undefined; } function parseAssignmentExpressionOrHigher() { // AssignmentExpression[in,yield]: // 1) ConditionalExpression[?in,?yield] // 2) LeftHandSideExpression = AssignmentExpression[?in,?yield] // 3) LeftHandSideExpression AssignmentOperator AssignmentExpression[?in,?yield] // 4) ArrowFunctionExpression[?in,?yield] // 5) AsyncArrowFunctionExpression[in,yield,await] // 6) [+Yield] YieldExpression[?In] // // Note: for ease of implementation we treat productions '2' and '3' as the same thing. // (i.e. they're both BinaryExpressions with an assignment operator in it). // First, do the simple check if we have a YieldExpression (production '6'). if (isYieldExpression()) { return parseYieldExpression(); } // Then, check if we have an arrow function (production '4' and '5') that starts with a parenthesized // parameter list or is an async arrow function. // AsyncArrowFunctionExpression: // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] // Production (1) of AsyncArrowFunctionExpression is parsed in "tryParseAsyncSimpleArrowFunctionExpression". // And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression". // // If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is // not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done // with AssignmentExpression if we see one. var arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression(); if (arrowExpression) { return arrowExpression; } // Now try to see if we're in production '1', '2' or '3'. A conditional expression can // start with a LogicalOrExpression, while the assignment productions can only start with // LeftHandSideExpressions. // // So, first, we try to just parse out a BinaryExpression. If we get something that is a // LeftHandSide or higher, then we can try to parse out the assignment expression part. // Otherwise, we try to parse out the conditional expression bit. We want to allow any // binary expression here, so we pass in the 'lowest' precedence here so that it matches // and consumes anything. var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); // To avoid a look-ahead, we did not handle the case of an arrow function with a single un-parenthesized // parameter ('x => ...') above. We handle it here by checking if the parsed expression was a single // identifier and the current token is an arrow. if (expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) { return parseSimpleArrowFunctionExpression(expr); } // Now see if we might be in cases '2' or '3'. // If the expression was a LHS expression, and we have an assignment operator, then // we're in '2' or '3'. Consume the assignment and return. // // Note: we call reScanGreaterToken so that we get an appropriately merged token // for cases like > > = becoming >>= if (ts.isLeftHandSideExpression(expr) && ts.isAssignmentOperator(reScanGreaterToken())) { return makeBinaryExpression(expr, parseTokenNode(), parseAssignmentExpressionOrHigher()); } // It wasn't an assignment or a lambda. This is a conditional expression: return parseConditionalExpressionRest(expr); } function isYieldExpression() { if (token() === 116 /* YieldKeyword */) { // If we have a 'yield' keyword, and this is a context where yield expressions are // allowed, then definitely parse out a yield expression. if (inYieldContext()) { return true; } // We're in a context where 'yield expr' is not allowed. However, if we can // definitely tell that the user was trying to parse a 'yield expr' and not // just a normal expr that start with a 'yield' identifier, then parse out // a 'yield expr'. We can then report an error later that they are only // allowed in generator expressions. // // for example, if we see 'yield(foo)', then we'll have to treat that as an // invocation expression of something called 'yield'. However, if we have // 'yield foo' then that is not legal as a normal expression, so we can // definitely recognize this as a yield expression. // // for now we just check if the next token is an identifier. More heuristics // can be added here later as necessary. We just need to make sure that we // don't accidentally consume something legal. return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); } return false; } function nextTokenIsIdentifierOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && isIdentifier(); } function parseYieldExpression() { var node = createNode(198 /* YieldExpression */); // YieldExpression[In] : // yield // yield [no LineTerminator here] [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] // yield [no LineTerminator here] * [Lexical goal InputElementRegExp]AssignmentExpression[?In, Yield] nextToken(); if (!scanner.hasPrecedingLineBreak() && (token() === 39 /* AsteriskToken */ || isStartOfExpression())) { node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */); node.expression = parseAssignmentExpressionOrHigher(); return finishNode(node); } else { // if the next token is not on the same line as yield. or we don't have an '*' or // the start of an expression, then this is just a simple "yield" expression. return finishNode(node); } } function parseSimpleArrowFunctionExpression(identifier, asyncModifier) { ts.Debug.assert(token() === 36 /* EqualsGreaterThanToken */, "parseSimpleArrowFunctionExpression should only have been called if we had a =>"); var node; if (asyncModifier) { node = createNode(188 /* ArrowFunction */, asyncModifier.pos); node.modifiers = asyncModifier; } else { node = createNode(188 /* ArrowFunction */, identifier.pos); } var parameter = createNode(147 /* Parameter */, identifier.pos); parameter.name = identifier; finishNode(parameter); node.parameters = createNodeArray([parameter], parameter.pos, parameter.end); node.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>"); node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); return addJSDocComment(finishNode(node)); } function tryParseParenthesizedArrowFunctionExpression() { var triState = isParenthesizedArrowFunctionExpression(); if (triState === 0 /* False */) { // It's definitely not a parenthesized arrow function expression. return undefined; } // If we definitely have an arrow function, then we can just parse one, not requiring a // following => or { token. Otherwise, we *might* have an arrow function. Try to parse // it out, but don't allow any ambiguity, and return 'undefined' if this could be an // expression instead. var arrowFunction = triState === 1 /* True */ ? parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ true) : tryParse(parsePossibleParenthesizedArrowFunctionExpressionHead); if (!arrowFunction) { // Didn't appear to actually be a parenthesized arrow function. Just bail out. return undefined; } var isAsync = ts.hasModifier(arrowFunction, 256 /* Async */); // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. var lastToken = token(); arrowFunction.equalsGreaterThanToken = parseExpectedToken(36 /* EqualsGreaterThanToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, "=>"); arrowFunction.body = (lastToken === 36 /* EqualsGreaterThanToken */ || lastToken === 17 /* OpenBraceToken */) ? parseArrowFunctionExpressionBody(isAsync) : parseIdentifier(); return finishNode(arrowFunction); } // True -> We definitely expect a parenthesized arrow function here. // False -> There *cannot* be a parenthesized arrow function here. // Unknown -> There *might* be a parenthesized arrow function here. // Speculatively look ahead to be sure, and rollback if not. function isParenthesizedArrowFunctionExpression() { if (token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */ || token() === 120 /* AsyncKeyword */) { return lookAhead(isParenthesizedArrowFunctionExpressionWorker); } if (token() === 36 /* EqualsGreaterThanToken */) { // ERROR RECOVERY TWEAK: // If we see a standalone => try to parse it as an arrow function expression as that's // likely what the user intended to write. return 1 /* True */; } // Definitely not a parenthesized arrow function. return 0 /* False */; } function isParenthesizedArrowFunctionExpressionWorker() { if (token() === 120 /* AsyncKeyword */) { nextToken(); if (scanner.hasPrecedingLineBreak()) { return 0 /* False */; } if (token() !== 19 /* OpenParenToken */ && token() !== 27 /* LessThanToken */) { return 0 /* False */; } } var first = token(); var second = nextToken(); if (first === 19 /* OpenParenToken */) { if (second === 20 /* CloseParenToken */) { // Simple cases: "() =>", "(): ", and "() {". // This is an arrow function with no parameters. // The last one is not actually an arrow function, // but this is probably what the user intended. var third = nextToken(); switch (third) { case 36 /* EqualsGreaterThanToken */: case 56 /* ColonToken */: case 17 /* OpenBraceToken */: return 1 /* True */; default: return 0 /* False */; } } // If encounter "([" or "({", this could be the start of a binding pattern. // Examples: // ([ x ]) => { } // ({ x }) => { } // ([ x ]) // ({ x }) if (second === 21 /* OpenBracketToken */ || second === 17 /* OpenBraceToken */) { return 2 /* Unknown */; } // Simple case: "(..." // This is an arrow function with a rest parameter. if (second === 24 /* DotDotDotToken */) { return 1 /* True */; } // Check for "(xxx yyy", where xxx is a modifier and yyy is an identifier. This // isn't actually allowed, but we want to treat it as a lambda so we can provide // a good error message. if (ts.isModifierKind(second) && second !== 120 /* AsyncKeyword */ && lookAhead(nextTokenIsIdentifier)) { return 1 /* True */; } // If we had "(" followed by something that's not an identifier, // then this definitely doesn't look like a lambda. if (!isIdentifier()) { return 0 /* False */; } switch (nextToken()) { case 56 /* ColonToken */: // If we have something like "(a:", then we must have a // type-annotated parameter in an arrow function expression. return 1 /* True */; case 55 /* QuestionToken */: nextToken(); // If we have "(a?:" or "(a?," or "(a?=" or "(a?)" then it is definitely a lambda. if (token() === 56 /* ColonToken */ || token() === 26 /* CommaToken */ || token() === 58 /* EqualsToken */ || token() === 20 /* CloseParenToken */) { return 1 /* True */; } // Otherwise it is definitely not a lambda. return 0 /* False */; case 26 /* CommaToken */: case 58 /* EqualsToken */: case 20 /* CloseParenToken */: // If we have "(a," or "(a=" or "(a)" this *could* be an arrow function return 2 /* Unknown */; } // It is definitely not an arrow function return 0 /* False */; } else { ts.Debug.assert(first === 27 /* LessThanToken */); // If we have "<" not followed by an identifier, // then this definitely is not an arrow function. if (!isIdentifier()) { return 0 /* False */; } // JSX overrides if (sourceFile.languageVariant === 1 /* JSX */) { var isArrowFunctionInJsx = lookAhead(function () { var third = nextToken(); if (third === 85 /* ExtendsKeyword */) { var fourth = nextToken(); switch (fourth) { case 58 /* EqualsToken */: case 29 /* GreaterThanToken */: return false; default: return true; } } else if (third === 26 /* CommaToken */) { return true; } return false; }); if (isArrowFunctionInJsx) { return 1 /* True */; } return 0 /* False */; } // This *could* be a parenthesized arrow function. return 2 /* Unknown */; } } function parsePossibleParenthesizedArrowFunctionExpressionHead() { return parseParenthesizedArrowFunctionExpressionHead(/*allowAmbiguity*/ false); } function tryParseAsyncSimpleArrowFunctionExpression() { // We do a check here so that we won't be doing unnecessarily call to "lookAhead" if (token() === 120 /* AsyncKeyword */) { if (lookAhead(isUnParenthesizedAsyncArrowFunctionWorker) === 1 /* True */) { var asyncModifier = parseModifiersForArrowFunction(); var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); return parseSimpleArrowFunctionExpression(expr, asyncModifier); } } return undefined; } function isUnParenthesizedAsyncArrowFunctionWorker() { // AsyncArrowFunctionExpression: // 1) async[no LineTerminator here]AsyncArrowBindingIdentifier[?Yield][no LineTerminator here]=>AsyncConciseBody[?In] // 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In] if (token() === 120 /* AsyncKeyword */) { nextToken(); // If the "async" is followed by "=>" token then it is not a begining of an async arrow-function // but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher" if (scanner.hasPrecedingLineBreak() || token() === 36 /* EqualsGreaterThanToken */) { return 0 /* False */; } // Check for un-parenthesized AsyncArrowFunction var expr = parseBinaryExpressionOrHigher(/*precedence*/ 0); if (!scanner.hasPrecedingLineBreak() && expr.kind === 71 /* Identifier */ && token() === 36 /* EqualsGreaterThanToken */) { return 1 /* True */; } } return 0 /* False */; } function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity) { var node = createNodeWithJSDoc(188 /* ArrowFunction */); node.modifiers = parseModifiersForArrowFunction(); var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; // Arrow functions are never generators. // // If we're speculatively parsing a signature for a parenthesized arrow function, then // we have to have a complete parameter list. Otherwise we might see something like // a => (b => c) // And think that "(b =>" was actually a parenthesized arrow function with a missing // close paren. fillSignature(56 /* ColonToken */, isAsync | (allowAmbiguity ? 0 /* None */ : 8 /* RequireCompleteParameterList */), node); // If we couldn't get parameters, we definitely could not parse out an arrow function. if (!node.parameters) { return undefined; } // Parsing a signature isn't enough. // Parenthesized arrow signatures often look like other valid expressions. // For instance: // - "(x = 10)" is an assignment expression parsed as a signature with a default parameter value. // - "(x,y)" is a comma expression parsed as a signature with two parameters. // - "a ? (b): c" will have "(b):" parsed as a signature with a return type annotation. // // So we need just a bit of lookahead to ensure that it can only be a signature. if (!allowAmbiguity && token() !== 36 /* EqualsGreaterThanToken */ && token() !== 17 /* OpenBraceToken */) { // Returning undefined here will cause our caller to rewind to where we started from. return undefined; } return node; } function parseArrowFunctionExpressionBody(isAsync) { if (token() === 17 /* OpenBraceToken */) { return parseFunctionBlock(isAsync ? 2 /* Await */ : 0 /* None */); } if (token() !== 25 /* SemicolonToken */ && token() !== 89 /* FunctionKeyword */ && token() !== 75 /* ClassKeyword */ && isStartOfStatement() && !isStartOfExpressionStatement()) { // Check if we got a plain statement (i.e. no expression-statements, no function/class expressions/declarations) // // Here we try to recover from a potential error situation in the case where the // user meant to supply a block. For example, if the user wrote: // // a => // let v = 0; // } // // they may be missing an open brace. Check to see if that's the case so we can // try to recover better. If we don't do this, then the next close curly we see may end // up preemptively closing the containing construct. // // Note: even when 'IgnoreMissingOpenBrace' is passed, parseBody will still error. return parseFunctionBlock(16 /* IgnoreMissingOpenBrace */ | (isAsync ? 2 /* Await */ : 0 /* None */)); } return isAsync ? doInAwaitContext(parseAssignmentExpressionOrHigher) : doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher); } function parseConditionalExpressionRest(leftOperand) { // Note: we are passed in an expression which was produced from parseBinaryExpressionOrHigher. var questionToken = parseOptionalToken(55 /* QuestionToken */); if (!questionToken) { return leftOperand; } // Note: we explicitly 'allowIn' in the whenTrue part of the condition expression, and // we do not that for the 'whenFalse' part. var node = createNode(196 /* ConditionalExpression */, leftOperand.pos); node.condition = leftOperand; node.questionToken = questionToken; node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); node.colonToken = parseExpectedToken(56 /* ColonToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics._0_expected, ts.tokenToString(56 /* ColonToken */)); node.whenFalse = parseAssignmentExpressionOrHigher(); return finishNode(node); } function parseBinaryExpressionOrHigher(precedence) { var leftOperand = parseUnaryExpressionOrHigher(); return parseBinaryExpressionRest(precedence, leftOperand); } function isInOrOfKeyword(t) { return t === 92 /* InKeyword */ || t === 143 /* OfKeyword */; } function parseBinaryExpressionRest(precedence, leftOperand) { while (true) { // We either have a binary operator here, or we're finished. We call // reScanGreaterToken so that we merge token sequences like > and = into >= reScanGreaterToken(); var newPrecedence = getBinaryOperatorPrecedence(); // Check the precedence to see if we should "take" this operator // - For left associative operator (all operator but **), consume the operator, // recursively call the function below, and parse binaryExpression as a rightOperand // of the caller if the new precedence of the operator is greater then or equal to the current precedence. // For example: // a - b - c; // ^token; leftOperand = b. Return b to the caller as a rightOperand // a * b - c // ^token; leftOperand = b. Return b to the caller as a rightOperand // a - b * c; // ^token; leftOperand = b. Return b * c to the caller as a rightOperand // - For right associative operator (**), consume the operator, recursively call the function // and parse binaryExpression as a rightOperand of the caller if the new precedence of // the operator is strictly grater than the current precedence // For example: // a ** b ** c; // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand // a - b ** c; // ^^token; leftOperand = b. Return b ** c to the caller as a rightOperand // a ** b - c // ^token; leftOperand = b. Return b to the caller as a rightOperand var consumeCurrentOperator = token() === 40 /* AsteriskAsteriskToken */ ? newPrecedence >= precedence : newPrecedence > precedence; if (!consumeCurrentOperator) { break; } if (token() === 92 /* InKeyword */ && inDisallowInContext()) { break; } if (token() === 118 /* AsKeyword */) { // Make sure we *do* perform ASI for constructs like this: // var x = foo // as (Bar) // This should be parsed as an initialized variable, followed // by a function call to 'as' with the argument 'Bar' if (scanner.hasPrecedingLineBreak()) { break; } else { nextToken(); leftOperand = makeAsExpression(leftOperand, parseType()); } } else { leftOperand = makeBinaryExpression(leftOperand, parseTokenNode(), parseBinaryExpressionOrHigher(newPrecedence)); } } return leftOperand; } function isBinaryOperator() { if (inDisallowInContext() && token() === 92 /* InKeyword */) { return false; } return getBinaryOperatorPrecedence() > 0; } function getBinaryOperatorPrecedence() { switch (token()) { case 54 /* BarBarToken */: return 1; case 53 /* AmpersandAmpersandToken */: return 2; case 49 /* BarToken */: return 3; case 50 /* CaretToken */: return 4; case 48 /* AmpersandToken */: return 5; case 32 /* EqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: return 6; case 27 /* LessThanToken */: case 29 /* GreaterThanToken */: case 30 /* LessThanEqualsToken */: case 31 /* GreaterThanEqualsToken */: case 93 /* InstanceOfKeyword */: case 92 /* InKeyword */: case 118 /* AsKeyword */: return 7; case 45 /* LessThanLessThanToken */: case 46 /* GreaterThanGreaterThanToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: return 8; case 37 /* PlusToken */: case 38 /* MinusToken */: return 9; case 39 /* AsteriskToken */: case 41 /* SlashToken */: case 42 /* PercentToken */: return 10; case 40 /* AsteriskAsteriskToken */: return 11; } // -1 is lower than all other precedences. Returning it will cause binary expression // parsing to stop. return -1; } function makeBinaryExpression(left, operatorToken, right) { var node = createNode(195 /* BinaryExpression */, left.pos); node.left = left; node.operatorToken = operatorToken; node.right = right; return finishNode(node); } function makeAsExpression(left, right) { var node = createNode(203 /* AsExpression */, left.pos); node.expression = left; node.type = right; return finishNode(node); } function parsePrefixUnaryExpression() { var node = createNode(193 /* PrefixUnaryExpression */); node.operator = token(); nextToken(); node.operand = parseSimpleUnaryExpression(); return finishNode(node); } function parseDeleteExpression() { var node = createNode(189 /* DeleteExpression */); nextToken(); node.expression = parseSimpleUnaryExpression(); return finishNode(node); } function parseTypeOfExpression() { var node = createNode(190 /* TypeOfExpression */); nextToken(); node.expression = parseSimpleUnaryExpression(); return finishNode(node); } function parseVoidExpression() { var node = createNode(191 /* VoidExpression */); nextToken(); node.expression = parseSimpleUnaryExpression(); return finishNode(node); } function isAwaitExpression() { if (token() === 121 /* AwaitKeyword */) { if (inAwaitContext()) { return true; } // here we are using similar heuristics as 'isYieldExpression' return lookAhead(nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine); } return false; } function parseAwaitExpression() { var node = createNode(192 /* AwaitExpression */); nextToken(); node.expression = parseSimpleUnaryExpression(); return finishNode(node); } /** * Parse ES7 exponential expression and await expression * * ES7 ExponentiationExpression: * 1) UnaryExpression[?Yield] * 2) UpdateExpression[?Yield] ** ExponentiationExpression[?Yield] * */ function parseUnaryExpressionOrHigher() { /** * ES7 UpdateExpression: * 1) LeftHandSideExpression[?Yield] * 2) LeftHandSideExpression[?Yield][no LineTerminator here]++ * 3) LeftHandSideExpression[?Yield][no LineTerminator here]-- * 4) ++UnaryExpression[?Yield] * 5) --UnaryExpression[?Yield] */ if (isUpdateExpression()) { var updateExpression = parseUpdateExpression(); return token() === 40 /* AsteriskAsteriskToken */ ? parseBinaryExpressionRest(getBinaryOperatorPrecedence(), updateExpression) : updateExpression; } /** * ES7 UnaryExpression: * 1) UpdateExpression[?yield] * 2) delete UpdateExpression[?yield] * 3) void UpdateExpression[?yield] * 4) typeof UpdateExpression[?yield] * 5) + UpdateExpression[?yield] * 6) - UpdateExpression[?yield] * 7) ~ UpdateExpression[?yield] * 8) ! UpdateExpression[?yield] */ var unaryOperator = token(); var simpleUnaryExpression = parseSimpleUnaryExpression(); if (token() === 40 /* AsteriskAsteriskToken */) { var start = ts.skipTrivia(sourceText, simpleUnaryExpression.pos); if (simpleUnaryExpression.kind === 185 /* TypeAssertionExpression */) { parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); } else { parseErrorAtPosition(start, simpleUnaryExpression.end - start, ts.Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, ts.tokenToString(unaryOperator)); } } return simpleUnaryExpression; } /** * Parse ES7 simple-unary expression or higher: * * ES7 UnaryExpression: * 1) UpdateExpression[?yield] * 2) delete UnaryExpression[?yield] * 3) void UnaryExpression[?yield] * 4) typeof UnaryExpression[?yield] * 5) + UnaryExpression[?yield] * 6) - UnaryExpression[?yield] * 7) ~ UnaryExpression[?yield] * 8) ! UnaryExpression[?yield] * 9) [+Await] await UnaryExpression[?yield] */ function parseSimpleUnaryExpression() { switch (token()) { case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: case 51 /* ExclamationToken */: return parsePrefixUnaryExpression(); case 80 /* DeleteKeyword */: return parseDeleteExpression(); case 103 /* TypeOfKeyword */: return parseTypeOfExpression(); case 105 /* VoidKeyword */: return parseVoidExpression(); case 27 /* LessThanToken */: // This is modified UnaryExpression grammar in TypeScript // UnaryExpression (modified): // < type > UnaryExpression return parseTypeAssertion(); case 121 /* AwaitKeyword */: if (isAwaitExpression()) { return parseAwaitExpression(); } // falls through default: return parseUpdateExpression(); } } /** * Check if the current token can possibly be an ES7 increment expression. * * ES7 UpdateExpression: * LeftHandSideExpression[?Yield] * LeftHandSideExpression[?Yield][no LineTerminator here]++ * LeftHandSideExpression[?Yield][no LineTerminator here]-- * ++LeftHandSideExpression[?Yield] * --LeftHandSideExpression[?Yield] */ function isUpdateExpression() { // This function is called inside parseUnaryExpression to decide // whether to call parseSimpleUnaryExpression or call parseUpdateExpression directly switch (token()) { case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: case 51 /* ExclamationToken */: case 80 /* DeleteKeyword */: case 103 /* TypeOfKeyword */: case 105 /* VoidKeyword */: case 121 /* AwaitKeyword */: return false; case 27 /* LessThanToken */: // If we are not in JSX context, we are parsing TypeAssertion which is an UnaryExpression if (sourceFile.languageVariant !== 1 /* JSX */) { return false; } // We are in JSX context and the token is part of JSXElement. // falls through default: return true; } } /** * Parse ES7 UpdateExpression. UpdateExpression is used instead of ES6's PostFixExpression. * * ES7 UpdateExpression[yield]: * 1) LeftHandSideExpression[?yield] * 2) LeftHandSideExpression[?yield] [[no LineTerminator here]]++ * 3) LeftHandSideExpression[?yield] [[no LineTerminator here]]-- * 4) ++LeftHandSideExpression[?yield] * 5) --LeftHandSideExpression[?yield] * In TypeScript (2), (3) are parsed as PostfixUnaryExpression. (4), (5) are parsed as PrefixUnaryExpression */ function parseUpdateExpression() { if (token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) { var node = createNode(193 /* PrefixUnaryExpression */); node.operator = token(); nextToken(); node.operand = parseLeftHandSideExpressionOrHigher(); return finishNode(node); } else if (sourceFile.languageVariant === 1 /* JSX */ && token() === 27 /* LessThanToken */ && lookAhead(nextTokenIsIdentifierOrKeywordOrGreaterThan)) { // JSXElement is part of primaryExpression return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); } var expression = parseLeftHandSideExpressionOrHigher(); ts.Debug.assert(ts.isLeftHandSideExpression(expression)); if ((token() === 43 /* PlusPlusToken */ || token() === 44 /* MinusMinusToken */) && !scanner.hasPrecedingLineBreak()) { var node = createNode(194 /* PostfixUnaryExpression */, expression.pos); node.operand = expression; node.operator = token(); nextToken(); return finishNode(node); } return expression; } function parseLeftHandSideExpressionOrHigher() { // Original Ecma: // LeftHandSideExpression: See 11.2 // NewExpression // CallExpression // // Our simplification: // // LeftHandSideExpression: See 11.2 // MemberExpression // CallExpression // // See comment in parseMemberExpressionOrHigher on how we replaced NewExpression with // MemberExpression to make our lives easier. // // to best understand the below code, it's important to see how CallExpression expands // out into its own productions: // // CallExpression: // MemberExpression Arguments // CallExpression Arguments // CallExpression[Expression] // CallExpression.IdentifierName // import (AssignmentExpression) // super Arguments // super.IdentifierName // // Because of the recursion in these calls, we need to bottom out first. There are three // bottom out states we can run into: 1) We see 'super' which must start either of // the last two CallExpression productions. 2) We see 'import' which must start import call. // 3)we have a MemberExpression which either completes the LeftHandSideExpression, // or starts the beginning of the first four CallExpression productions. var expression; if (token() === 91 /* ImportKeyword */ && lookAhead(nextTokenIsOpenParenOrLessThan)) { // We don't want to eagerly consume all import keyword as import call expression so we look a head to find "(" // For example: // var foo3 = require("subfolder // import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression sourceFile.flags |= 524288 /* PossiblyContainsDynamicImport */; expression = parseTokenNode(); } else { expression = token() === 97 /* SuperKeyword */ ? parseSuperExpression() : parseMemberExpressionOrHigher(); } // Now, we *may* be complete. However, we might have consumed the start of a // CallExpression. As such, we need to consume the rest of it here to be complete. return parseCallExpressionRest(expression); } function parseMemberExpressionOrHigher() { // Note: to make our lives simpler, we decompose the NewExpression productions and // place ObjectCreationExpression and FunctionExpression into PrimaryExpression. // like so: // // PrimaryExpression : See 11.1 // this // Identifier // Literal // ArrayLiteral // ObjectLiteral // (Expression) // FunctionExpression // new MemberExpression Arguments? // // MemberExpression : See 11.2 // PrimaryExpression // MemberExpression[Expression] // MemberExpression.IdentifierName // // CallExpression : See 11.2 // MemberExpression // CallExpression Arguments // CallExpression[Expression] // CallExpression.IdentifierName // // Technically this is ambiguous. i.e. CallExpression defines: // // CallExpression: // CallExpression Arguments // // If you see: "new Foo()" // // Then that could be treated as a single ObjectCreationExpression, or it could be // treated as the invocation of "new Foo". We disambiguate that in code (to match // the original grammar) by making sure that if we see an ObjectCreationExpression // we always consume arguments if they are there. So we treat "new Foo()" as an // object creation only, and not at all as an invocation) Another way to think // about this is that for every "new" that we see, we will consume an argument list if // it is there as part of the *associated* object creation node. Any additional // argument lists we see, will become invocation expressions. // // Because there are no other places in the grammar now that refer to FunctionExpression // or ObjectCreationExpression, it is safe to push down into the PrimaryExpression // production. // // Because CallExpression and MemberExpression are left recursive, we need to bottom out // of the recursion immediately. So we parse out a primary expression to start with. var expression = parsePrimaryExpression(); return parseMemberExpressionRest(expression); } function parseSuperExpression() { var expression = parseTokenNode(); if (token() === 19 /* OpenParenToken */ || token() === 23 /* DotToken */ || token() === 21 /* OpenBracketToken */) { return expression; } // If we have seen "super" it must be followed by '(' or '.'. // If it wasn't then just try to parse out a '.' and report an error. var node = createNode(180 /* PropertyAccessExpression */, expression.pos); node.expression = expression; parseExpectedToken(23 /* DotToken */, /*reportAtCurrentPosition*/ false, ts.Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); return finishNode(node); } function tagNamesAreEquivalent(lhs, rhs) { if (lhs.kind !== rhs.kind) { return false; } if (lhs.kind === 71 /* Identifier */) { return lhs.escapedText === rhs.escapedText; } if (lhs.kind === 99 /* ThisKeyword */) { return true; } // If we are at this statement then we must have PropertyAccessExpression and because tag name in Jsx element can only // take forms of JsxTagNameExpression which includes an identifier, "this" expression, or another propertyAccessExpression // it is safe to case the expression property as such. See parseJsxElementName for how we parse tag name in Jsx element return lhs.name.escapedText === rhs.name.escapedText && tagNamesAreEquivalent(lhs.expression, rhs.expression); } function parseJsxElementOrSelfClosingElementOrFragment(inExpressionContext) { var opening = parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext); var result; if (opening.kind === 252 /* JsxOpeningElement */) { var node = createNode(250 /* JsxElement */, opening.pos); node.openingElement = opening; node.children = parseJsxChildren(node.openingElement); 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 if (opening.kind === 255 /* JsxOpeningFragment */) { var node = createNode(254 /* JsxFragment */, opening.pos); node.openingFragment = opening; node.children = parseJsxChildren(node.openingFragment); node.closingFragment = parseJsxClosingFragment(inExpressionContext); result = finishNode(node); } else { ts.Debug.assert(opening.kind === 251 /* JsxSelfClosingElement */); // Nothing else to do for self-closing elements result = opening; } // If the user writes the invalid code '
' in an expression context (i.e. not wrapped in // an enclosing tag), we'll naively try to parse ^ this as a 'less than' operator and the remainder of the tag // as garbage, which will cause the formatter to badly mangle the JSX. Perform a speculative parse of a JSX // element if we see a < token so that we can wrap it in a synthetic binary expression so the formatter // does less damage and we can report a better error. // Since JSX elements are invalid < operands anyway, this lookahead parse will only occur in error scenarios // of one sort or another. if (inExpressionContext && token() === 27 /* LessThanToken */) { var invalidElement = tryParse(function () { return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ true); }); if (invalidElement) { parseErrorAtCurrentToken(ts.Diagnostics.JSX_expressions_must_have_one_parent_element); var badNode = createNode(195 /* BinaryExpression */, result.pos); badNode.end = invalidElement.end; badNode.left = result; badNode.right = invalidElement; badNode.operatorToken = createMissingNode(26 /* CommaToken */, /*reportAtCurrentPosition*/ false, /*diagnosticMessage*/ undefined); badNode.operatorToken.pos = badNode.operatorToken.end = badNode.right.pos; return badNode; } } return result; } function parseJsxText() { var node = createNode(10 /* JsxText */); node.containsOnlyWhiteSpaces = currentToken === 11 /* JsxTextAllWhiteSpaces */; currentToken = scanner.scanJsxToken(); return finishNode(node); } function parseJsxChild() { switch (token()) { case 10 /* JsxText */: case 11 /* JsxTextAllWhiteSpaces */: return parseJsxText(); case 17 /* OpenBraceToken */: return parseJsxExpression(/*inExpressionContext*/ false); case 27 /* LessThanToken */: return parseJsxElementOrSelfClosingElementOrFragment(/*inExpressionContext*/ false); } ts.Debug.fail("Unknown JSX child kind " + token()); } function parseJsxChildren(openingTag) { var list = []; var listPos = getNodePos(); var saveParsingContext = parsingContext; parsingContext |= 1 << 14 /* JsxChildren */; while (true) { currentToken = scanner.reScanJsxToken(); if (token() === 28 /* LessThanSlashToken */) { // Closing tag break; } else if (token() === 1 /* EndOfFileToken */) { // If we hit EOF, issue the error at the tag that lacks the closing element // rather than at the end of the file (which is useless) if (ts.isJsxOpeningFragment(openingTag)) { parseErrorAtPosition(openingTag.pos, openingTag.end - openingTag.pos, ts.Diagnostics.JSX_fragment_has_no_corresponding_closing_tag); } else { var openingTagName = openingTag.tagName; parseErrorAtPosition(openingTagName.pos, openingTagName.end - openingTagName.pos, ts.Diagnostics.JSX_element_0_has_no_corresponding_closing_tag, ts.getTextOfNodeFromSourceText(sourceText, openingTagName)); } break; } else if (token() === 7 /* ConflictMarkerTrivia */) { break; } var child = parseJsxChild(); if (child) { list.push(child); } } parsingContext = saveParsingContext; return createNodeArray(list, listPos); } function parseJsxAttributes() { var jsxAttributes = createNode(258 /* JsxAttributes */); jsxAttributes.properties = parseList(13 /* JsxAttributes */, parseJsxAttribute); return finishNode(jsxAttributes); } function parseJsxOpeningOrSelfClosingElementOrOpeningFragment(inExpressionContext) { var fullStart = scanner.getStartPos(); parseExpected(27 /* LessThanToken */); if (token() === 29 /* GreaterThanToken */) { parseExpected(29 /* GreaterThanToken */); var node_1 = createNode(255 /* JsxOpeningFragment */, fullStart); return finishNode(node_1); } var tagName = parseJsxElementName(); var attributes = parseJsxAttributes(); var node; if (token() === 29 /* GreaterThanToken */) { // Closing tag, so scan the immediately-following text with the JSX scanning instead // of regular scanning to avoid treating illegal characters (e.g. '#') as immediate // scanning errors node = createNode(252 /* JsxOpeningElement */, fullStart); scanJsxText(); } else { parseExpected(41 /* SlashToken */); if (inExpressionContext) { parseExpected(29 /* GreaterThanToken */); } else { parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } node = createNode(251 /* JsxSelfClosingElement */, fullStart); } node.tagName = tagName; node.attributes = attributes; return finishNode(node); } function parseJsxElementName() { scanJsxIdentifier(); // JsxElement can have name in the form of // propertyAccessExpression // primaryExpression in the form of an identifier and "this" keyword // We can't just simply use parseLeftHandSideExpressionOrHigher because then we will start consider class,function etc as a keyword // We only want to consider "this" as a primaryExpression var expression = token() === 99 /* ThisKeyword */ ? parseTokenNode() : parseIdentifierName(); while (parseOptional(23 /* DotToken */)) { var propertyAccess = createNode(180 /* PropertyAccessExpression */, expression.pos); propertyAccess.expression = expression; propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); expression = finishNode(propertyAccess); } return expression; } function parseJsxExpression(inExpressionContext) { var node = createNode(260 /* JsxExpression */); parseExpected(17 /* OpenBraceToken */); if (token() !== 18 /* CloseBraceToken */) { node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */); node.expression = parseAssignmentExpressionOrHigher(); } if (inExpressionContext) { parseExpected(18 /* CloseBraceToken */); } else { parseExpected(18 /* CloseBraceToken */, /*message*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } return finishNode(node); } function parseJsxAttribute() { if (token() === 17 /* OpenBraceToken */) { return parseJsxSpreadAttribute(); } scanJsxIdentifier(); var node = createNode(257 /* JsxAttribute */); node.name = parseIdentifierName(); if (token() === 58 /* EqualsToken */) { switch (scanJsxAttributeValue()) { case 9 /* StringLiteral */: node.initializer = parseLiteralNode(); break; default: node.initializer = parseJsxExpression(/*inExpressionContext*/ true); break; } } return finishNode(node); } function parseJsxSpreadAttribute() { var node = createNode(259 /* JsxSpreadAttribute */); parseExpected(17 /* OpenBraceToken */); parseExpected(24 /* DotDotDotToken */); node.expression = parseExpression(); parseExpected(18 /* CloseBraceToken */); return finishNode(node); } function parseJsxClosingElement(inExpressionContext) { var node = createNode(253 /* JsxClosingElement */); parseExpected(28 /* LessThanSlashToken */); node.tagName = parseJsxElementName(); if (inExpressionContext) { parseExpected(29 /* GreaterThanToken */); } else { parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } return finishNode(node); } function parseJsxClosingFragment(inExpressionContext) { var node = createNode(256 /* JsxClosingFragment */); parseExpected(28 /* LessThanSlashToken */); if (ts.tokenIsIdentifierOrKeyword(token())) { var unexpectedTagName = parseJsxElementName(); parseErrorAtPosition(unexpectedTagName.pos, unexpectedTagName.end - unexpectedTagName.pos, ts.Diagnostics.Expected_corresponding_closing_tag_for_JSX_fragment); } if (inExpressionContext) { parseExpected(29 /* GreaterThanToken */); } else { parseExpected(29 /* GreaterThanToken */, /*diagnostic*/ undefined, /*shouldAdvance*/ false); scanJsxText(); } return finishNode(node); } function parseTypeAssertion() { var node = createNode(185 /* TypeAssertionExpression */); parseExpected(27 /* LessThanToken */); node.type = parseType(); parseExpected(29 /* GreaterThanToken */); node.expression = parseSimpleUnaryExpression(); return finishNode(node); } function parseMemberExpressionRest(expression) { while (true) { var dotToken = parseOptionalToken(23 /* DotToken */); if (dotToken) { var propertyAccess = createNode(180 /* PropertyAccessExpression */, expression.pos); propertyAccess.expression = expression; propertyAccess.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); expression = finishNode(propertyAccess); continue; } if (token() === 51 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) { nextToken(); var nonNullExpression = createNode(204 /* NonNullExpression */, expression.pos); nonNullExpression.expression = expression; expression = finishNode(nonNullExpression); continue; } // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName if (!inDecoratorContext() && parseOptional(21 /* OpenBracketToken */)) { var indexedAccess = createNode(181 /* ElementAccessExpression */, expression.pos); indexedAccess.expression = expression; // It's not uncommon for a user to write: "new Type[]". // Check for that common pattern and report a better error message. if (token() !== 22 /* CloseBracketToken */) { indexedAccess.argumentExpression = allowInAnd(parseExpression); if (indexedAccess.argumentExpression.kind === 9 /* StringLiteral */ || indexedAccess.argumentExpression.kind === 8 /* NumericLiteral */) { var literal = indexedAccess.argumentExpression; literal.text = internIdentifier(literal.text); } } parseExpected(22 /* CloseBracketToken */); expression = finishNode(indexedAccess); continue; } if (token() === 13 /* NoSubstitutionTemplateLiteral */ || token() === 14 /* TemplateHead */) { var tagExpression = createNode(184 /* TaggedTemplateExpression */, expression.pos); tagExpression.tag = expression; tagExpression.template = token() === 13 /* NoSubstitutionTemplateLiteral */ ? parseLiteralNode() : parseTemplateExpression(); expression = finishNode(tagExpression); continue; } return expression; } } function parseCallExpressionRest(expression) { while (true) { expression = parseMemberExpressionRest(expression); if (token() === 27 /* LessThanToken */) { // See if this is the start of a generic invocation. If so, consume it and // keep checking for postfix expressions. Otherwise, it's just a '<' that's // part of an arithmetic expression. Break out so we consume it higher in the // stack. var typeArguments = tryParse(parseTypeArgumentsInExpression); if (!typeArguments) { return expression; } var callExpr = createNode(182 /* CallExpression */, expression.pos); callExpr.expression = expression; callExpr.typeArguments = typeArguments; callExpr.arguments = parseArgumentList(); expression = finishNode(callExpr); continue; } else if (token() === 19 /* OpenParenToken */) { var callExpr = createNode(182 /* CallExpression */, expression.pos); callExpr.expression = expression; callExpr.arguments = parseArgumentList(); expression = finishNode(callExpr); continue; } return expression; } } function parseArgumentList() { parseExpected(19 /* OpenParenToken */); var result = parseDelimitedList(11 /* ArgumentExpressions */, parseArgumentExpression); parseExpected(20 /* CloseParenToken */); return result; } function parseTypeArgumentsInExpression() { if (!parseOptional(27 /* LessThanToken */)) { return undefined; } var typeArguments = parseDelimitedList(19 /* TypeArguments */, parseType); if (!parseExpected(29 /* GreaterThanToken */)) { // If it doesn't have the closing > then it's definitely not an type argument list. return undefined; } // If we have a '<', then only parse this as a argument list if the type arguments // are complete and we have an open paren. if we don't, rewind and return nothing. return typeArguments && canFollowTypeArgumentsInExpression() ? typeArguments : undefined; } function canFollowTypeArgumentsInExpression() { switch (token()) { case 19 /* OpenParenToken */: // foo( // this case are the only case where this token can legally follow a type argument // list. So we definitely want to treat this as a type arg list. case 23 /* DotToken */: // foo. case 20 /* CloseParenToken */: // foo) case 22 /* CloseBracketToken */: // foo] case 56 /* ColonToken */: // foo: case 25 /* SemicolonToken */: // foo; case 55 /* QuestionToken */: // foo? case 32 /* EqualsEqualsToken */: // foo == case 34 /* EqualsEqualsEqualsToken */: // foo === case 33 /* ExclamationEqualsToken */: // foo != case 35 /* ExclamationEqualsEqualsToken */: // foo !== case 53 /* AmpersandAmpersandToken */: // foo && case 54 /* BarBarToken */: // foo || case 50 /* CaretToken */: // foo ^ case 48 /* AmpersandToken */: // foo & case 49 /* BarToken */: // foo | case 18 /* CloseBraceToken */: // foo } case 1 /* EndOfFileToken */:// foo // these cases can't legally follow a type arg list. However, they're not legal // expressions either. The user is probably in the middle of a generic type. So // treat it as such. return true; case 26 /* CommaToken */: // foo, case 17 /* OpenBraceToken */: // foo { // We don't want to treat these as type arguments. Otherwise we'll parse this // as an invocation expression. Instead, we want to parse out the expression // in isolation from the type arguments. default: // Anything else treat as an expression. return false; } } function parsePrimaryExpression() { switch (token()) { case 8 /* NumericLiteral */: case 9 /* StringLiteral */: case 13 /* NoSubstitutionTemplateLiteral */: return parseLiteralNode(); case 99 /* ThisKeyword */: case 97 /* SuperKeyword */: case 95 /* NullKeyword */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: return parseTokenNode(); case 19 /* OpenParenToken */: return parseParenthesizedExpression(); case 21 /* OpenBracketToken */: return parseArrayLiteralExpression(); case 17 /* OpenBraceToken */: return parseObjectLiteralExpression(); case 120 /* AsyncKeyword */: // Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher. // If we encounter `async [no LineTerminator here] function` then this is an async // function; otherwise, its an identifier. if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) { break; } return parseFunctionExpression(); case 75 /* ClassKeyword */: return parseClassExpression(); case 89 /* FunctionKeyword */: return parseFunctionExpression(); case 94 /* NewKeyword */: return parseNewExpression(); case 41 /* SlashToken */: case 63 /* SlashEqualsToken */: if (reScanSlashToken() === 12 /* RegularExpressionLiteral */) { return parseLiteralNode(); } break; case 14 /* TemplateHead */: return parseTemplateExpression(); } return parseIdentifier(ts.Diagnostics.Expression_expected); } function parseParenthesizedExpression() { var node = createNodeWithJSDoc(186 /* ParenthesizedExpression */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); return finishNode(node); } function parseSpreadElement() { var node = createNode(199 /* SpreadElement */); parseExpected(24 /* DotDotDotToken */); node.expression = parseAssignmentExpressionOrHigher(); return finishNode(node); } function parseArgumentOrArrayLiteralElement() { return token() === 24 /* DotDotDotToken */ ? parseSpreadElement() : token() === 26 /* CommaToken */ ? createNode(201 /* OmittedExpression */) : parseAssignmentExpressionOrHigher(); } function parseArgumentExpression() { return doOutsideOfContext(disallowInAndDecoratorContext, parseArgumentOrArrayLiteralElement); } function parseArrayLiteralExpression() { var node = createNode(178 /* ArrayLiteralExpression */); parseExpected(21 /* OpenBracketToken */); if (scanner.hasPrecedingLineBreak()) { node.multiLine = true; } node.elements = parseDelimitedList(15 /* ArrayLiteralMembers */, parseArgumentOrArrayLiteralElement); parseExpected(22 /* CloseBracketToken */); return finishNode(node); } function parseObjectLiteralElement() { var node = createNodeWithJSDoc(0 /* Unknown */); if (parseOptionalToken(24 /* DotDotDotToken */)) { node.kind = 267 /* SpreadAssignment */; node.expression = parseAssignmentExpressionOrHigher(); return finishNode(node); } node.decorators = parseDecorators(); node.modifiers = parseModifiers(); if (parseContextualModifier(125 /* GetKeyword */)) { return parseAccessorDeclaration(node, 154 /* GetAccessor */); } if (parseContextualModifier(135 /* SetKeyword */)) { return parseAccessorDeclaration(node, 155 /* SetAccessor */); } var asteriskToken = parseOptionalToken(39 /* AsteriskToken */); var tokenIsIdentifier = isIdentifier(); node.name = parsePropertyName(); // Disallowing of optional property assignments happens in the grammar checker. node.questionToken = parseOptionalToken(55 /* QuestionToken */); if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) { return parseMethodDeclaration(node, asteriskToken); } // check if it is short-hand property assignment or normal property assignment // NOTE: if token is EqualsToken it is interpreted as CoverInitializedName production // CoverInitializedName[Yield] : // IdentifierReference[?Yield] Initializer[In, ?Yield] // this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern var isShorthandPropertyAssignment = tokenIsIdentifier && (token() === 26 /* CommaToken */ || token() === 18 /* CloseBraceToken */ || token() === 58 /* EqualsToken */); if (isShorthandPropertyAssignment) { node.kind = 266 /* ShorthandPropertyAssignment */; var equalsToken = parseOptionalToken(58 /* EqualsToken */); if (equalsToken) { node.equalsToken = equalsToken; node.objectAssignmentInitializer = allowInAnd(parseAssignmentExpressionOrHigher); } } else { node.kind = 265 /* PropertyAssignment */; parseExpected(56 /* ColonToken */); node.initializer = allowInAnd(parseAssignmentExpressionOrHigher); } return finishNode(node); } function parseObjectLiteralExpression() { var node = createNode(179 /* ObjectLiteralExpression */); parseExpected(17 /* OpenBraceToken */); if (scanner.hasPrecedingLineBreak()) { node.multiLine = true; } node.properties = parseDelimitedList(12 /* ObjectLiteralMembers */, parseObjectLiteralElement, /*considerSemicolonAsDelimiter*/ true); parseExpected(18 /* CloseBraceToken */); return finishNode(node); } function parseFunctionExpression() { // GeneratorExpression: // function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody } // // FunctionExpression: // function BindingIdentifier[opt](FormalParameters){ FunctionBody } var saveDecoratorContext = inDecoratorContext(); if (saveDecoratorContext) { setDecoratorContext(/*val*/ false); } var node = createNodeWithJSDoc(187 /* FunctionExpression */); node.modifiers = parseModifiers(); parseExpected(89 /* FunctionKeyword */); node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */); var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */; var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; node.name = isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) : isGenerator ? doInYieldContext(parseOptionalIdentifier) : isAsync ? doInAwaitContext(parseOptionalIdentifier) : parseOptionalIdentifier(); fillSignature(56 /* ColonToken */, isGenerator | isAsync, node); node.body = parseFunctionBlock(isGenerator | isAsync); if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } return finishNode(node); } function parseOptionalIdentifier() { return isIdentifier() ? parseIdentifier() : undefined; } function parseNewExpression() { var fullStart = scanner.getStartPos(); parseExpected(94 /* NewKeyword */); if (parseOptional(23 /* DotToken */)) { var node_2 = createNode(205 /* MetaProperty */, fullStart); node_2.keywordToken = 94 /* NewKeyword */; node_2.name = parseIdentifierName(); return finishNode(node_2); } var node = createNode(183 /* NewExpression */, fullStart); node.expression = parseMemberExpressionOrHigher(); node.typeArguments = tryParse(parseTypeArgumentsInExpression); if (node.typeArguments || token() === 19 /* OpenParenToken */) { node.arguments = parseArgumentList(); } return finishNode(node); } // STATEMENTS function parseBlock(ignoreMissingOpenBrace, diagnosticMessage) { var node = createNode(208 /* Block */); if (parseExpected(17 /* OpenBraceToken */, diagnosticMessage) || ignoreMissingOpenBrace) { if (scanner.hasPrecedingLineBreak()) { node.multiLine = true; } node.statements = parseList(1 /* BlockStatements */, parseStatement); parseExpected(18 /* CloseBraceToken */); } else { node.statements = createMissingList(); } return finishNode(node); } function parseFunctionBlock(flags, diagnosticMessage) { var savedYieldContext = inYieldContext(); setYieldContext(!!(flags & 1 /* Yield */)); var savedAwaitContext = inAwaitContext(); setAwaitContext(!!(flags & 2 /* Await */)); // We may be in a [Decorator] context when parsing a function expression or // arrow function. The body of the function is not in [Decorator] context. var saveDecoratorContext = inDecoratorContext(); if (saveDecoratorContext) { setDecoratorContext(/*val*/ false); } var block = parseBlock(!!(flags & 16 /* IgnoreMissingOpenBrace */), diagnosticMessage); if (saveDecoratorContext) { setDecoratorContext(/*val*/ true); } setYieldContext(savedYieldContext); setAwaitContext(savedAwaitContext); return block; } function parseEmptyStatement() { var node = createNode(210 /* EmptyStatement */); parseExpected(25 /* SemicolonToken */); return finishNode(node); } function parseIfStatement() { var node = createNode(212 /* IfStatement */); parseExpected(90 /* IfKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); node.thenStatement = parseStatement(); node.elseStatement = parseOptional(82 /* ElseKeyword */) ? parseStatement() : undefined; return finishNode(node); } function parseDoStatement() { var node = createNode(213 /* DoStatement */); parseExpected(81 /* DoKeyword */); node.statement = parseStatement(); parseExpected(106 /* WhileKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); // From: https://mail.mozilla.org/pipermail/es-discuss/2011-August/016188.html // 157 min --- All allen at wirfs-brock.com CONF --- "do{;}while(false)false" prohibited in // spec but allowed in consensus reality. Approved -- this is the de-facto standard whereby // do;while(0)x will have a semicolon inserted before x. parseOptional(25 /* SemicolonToken */); return finishNode(node); } function parseWhileStatement() { var node = createNode(214 /* WhileStatement */); parseExpected(106 /* WhileKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); node.statement = parseStatement(); return finishNode(node); } function parseForOrForInOrForOfStatement() { var pos = getNodePos(); parseExpected(88 /* ForKeyword */); var awaitToken = parseOptionalToken(121 /* AwaitKeyword */); parseExpected(19 /* OpenParenToken */); var initializer = undefined; if (token() !== 25 /* SemicolonToken */) { if (token() === 104 /* VarKeyword */ || token() === 110 /* LetKeyword */ || token() === 76 /* ConstKeyword */) { initializer = parseVariableDeclarationList(/*inForStatementInitializer*/ true); } else { initializer = disallowInAnd(parseExpression); } } var forOrForInOrForOfStatement; if (awaitToken ? parseExpected(143 /* OfKeyword */) : parseOptional(143 /* OfKeyword */)) { var forOfStatement = createNode(217 /* ForOfStatement */, pos); forOfStatement.awaitModifier = awaitToken; forOfStatement.initializer = initializer; forOfStatement.expression = allowInAnd(parseAssignmentExpressionOrHigher); parseExpected(20 /* CloseParenToken */); forOrForInOrForOfStatement = forOfStatement; } else if (parseOptional(92 /* InKeyword */)) { var forInStatement = createNode(216 /* ForInStatement */, pos); forInStatement.initializer = initializer; forInStatement.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); forOrForInOrForOfStatement = forInStatement; } else { var forStatement = createNode(215 /* ForStatement */, pos); forStatement.initializer = initializer; parseExpected(25 /* SemicolonToken */); if (token() !== 25 /* SemicolonToken */ && token() !== 20 /* CloseParenToken */) { forStatement.condition = allowInAnd(parseExpression); } parseExpected(25 /* SemicolonToken */); if (token() !== 20 /* CloseParenToken */) { forStatement.incrementor = allowInAnd(parseExpression); } parseExpected(20 /* CloseParenToken */); forOrForInOrForOfStatement = forStatement; } forOrForInOrForOfStatement.statement = parseStatement(); return finishNode(forOrForInOrForOfStatement); } function parseBreakOrContinueStatement(kind) { var node = createNode(kind); parseExpected(kind === 219 /* BreakStatement */ ? 72 /* BreakKeyword */ : 77 /* ContinueKeyword */); if (!canParseSemicolon()) { node.label = parseIdentifier(); } parseSemicolon(); return finishNode(node); } function parseReturnStatement() { var node = createNode(220 /* ReturnStatement */); parseExpected(96 /* ReturnKeyword */); if (!canParseSemicolon()) { node.expression = allowInAnd(parseExpression); } parseSemicolon(); return finishNode(node); } function parseWithStatement() { var node = createNode(221 /* WithStatement */); parseExpected(107 /* WithKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); node.statement = doInsideOfContext(4194304 /* InWithStatement */, parseStatement); return finishNode(node); } function parseCaseClause() { var node = createNode(261 /* CaseClause */); parseExpected(73 /* CaseKeyword */); node.expression = allowInAnd(parseExpression); parseExpected(56 /* ColonToken */); node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement); return finishNode(node); } function parseDefaultClause() { var node = createNode(262 /* DefaultClause */); parseExpected(79 /* DefaultKeyword */); parseExpected(56 /* ColonToken */); node.statements = parseList(3 /* SwitchClauseStatements */, parseStatement); return finishNode(node); } function parseCaseOrDefaultClause() { return token() === 73 /* CaseKeyword */ ? parseCaseClause() : parseDefaultClause(); } function parseSwitchStatement() { var node = createNode(222 /* SwitchStatement */); parseExpected(98 /* SwitchKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = allowInAnd(parseExpression); parseExpected(20 /* CloseParenToken */); var caseBlock = createNode(236 /* CaseBlock */); parseExpected(17 /* OpenBraceToken */); caseBlock.clauses = parseList(2 /* SwitchClauses */, parseCaseOrDefaultClause); parseExpected(18 /* CloseBraceToken */); node.caseBlock = finishNode(caseBlock); return finishNode(node); } function parseThrowStatement() { // ThrowStatement[Yield] : // throw [no LineTerminator here]Expression[In, ?Yield]; // Because of automatic semicolon insertion, we need to report error if this // throw could be terminated with a semicolon. Note: we can't call 'parseExpression' // directly as that might consume an expression on the following line. // We just return 'undefined' in that case. The actual error will be reported in the // grammar walker. var node = createNode(224 /* ThrowStatement */); parseExpected(100 /* ThrowKeyword */); node.expression = scanner.hasPrecedingLineBreak() ? undefined : allowInAnd(parseExpression); parseSemicolon(); return finishNode(node); } // TODO: Review for error recovery function parseTryStatement() { var node = createNode(225 /* TryStatement */); parseExpected(102 /* TryKeyword */); node.tryBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); node.catchClause = token() === 74 /* CatchKeyword */ ? parseCatchClause() : undefined; // If we don't have a catch clause, then we must have a finally clause. Try to parse // one out no matter what. if (!node.catchClause || token() === 87 /* FinallyKeyword */) { parseExpected(87 /* FinallyKeyword */); node.finallyBlock = parseBlock(/*ignoreMissingOpenBrace*/ false); } return finishNode(node); } function parseCatchClause() { var result = createNode(264 /* CatchClause */); parseExpected(74 /* CatchKeyword */); if (parseOptional(19 /* OpenParenToken */)) { result.variableDeclaration = parseVariableDeclaration(); parseExpected(20 /* CloseParenToken */); } else { // Keep shape of node to avoid degrading performance. result.variableDeclaration = undefined; } result.block = parseBlock(/*ignoreMissingOpenBrace*/ false); return finishNode(result); } function parseDebuggerStatement() { var node = createNode(226 /* DebuggerStatement */); parseExpected(78 /* DebuggerKeyword */); parseSemicolon(); return finishNode(node); } function parseExpressionOrLabeledStatement() { // Avoiding having to do the lookahead for a labeled statement by just trying to parse // out an expression, seeing if it is identifier and then seeing if it is followed by // a colon. var node = createNodeWithJSDoc(0 /* Unknown */); var expression = allowInAnd(parseExpression); if (expression.kind === 71 /* Identifier */ && parseOptional(56 /* ColonToken */)) { node.kind = 223 /* LabeledStatement */; node.label = expression; node.statement = parseStatement(); } else { node.kind = 211 /* ExpressionStatement */; node.expression = expression; parseSemicolon(); } return finishNode(node); } function nextTokenIsIdentifierOrKeywordOnSameLine() { nextToken(); return ts.tokenIsIdentifierOrKeyword(token()) && !scanner.hasPrecedingLineBreak(); } function nextTokenIsClassKeywordOnSameLine() { nextToken(); return token() === 75 /* ClassKeyword */ && !scanner.hasPrecedingLineBreak(); } function nextTokenIsFunctionKeywordOnSameLine() { nextToken(); return token() === 89 /* FunctionKeyword */ && !scanner.hasPrecedingLineBreak(); } function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() { nextToken(); return (ts.tokenIsIdentifierOrKeyword(token()) || token() === 8 /* NumericLiteral */ || token() === 9 /* StringLiteral */) && !scanner.hasPrecedingLineBreak(); } function isDeclaration() { while (true) { switch (token()) { case 104 /* VarKeyword */: case 110 /* LetKeyword */: case 76 /* ConstKeyword */: case 89 /* FunctionKeyword */: case 75 /* ClassKeyword */: case 83 /* EnumKeyword */: return true; // 'declare', 'module', 'namespace', 'interface'* and 'type' are all legal JavaScript identifiers; // however, an identifier cannot be followed by another identifier on the same line. This is what we // count on to parse out the respective declarations. For instance, we exploit this to say that // // namespace n // // can be none other than the beginning of a namespace declaration, but need to respect that JavaScript sees // // namespace // n // // as the identifier 'namespace' on one line followed by the identifier 'n' on another. // We need to look one token ahead to see if it permissible to try parsing a declaration. // // *Note*: 'interface' is actually a strict mode reserved word. So while // // "use strict" // interface // I {} // // could be legal, it would add complexity for very little gain. case 109 /* InterfaceKeyword */: case 138 /* TypeKeyword */: return nextTokenIsIdentifierOnSameLine(); case 128 /* ModuleKeyword */: case 129 /* NamespaceKeyword */: return nextTokenIsIdentifierOrStringLiteralOnSameLine(); case 117 /* AbstractKeyword */: case 120 /* AsyncKeyword */: case 124 /* DeclareKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 114 /* PublicKeyword */: case 131 /* ReadonlyKeyword */: nextToken(); // ASI takes effect for this modifier. if (scanner.hasPrecedingLineBreak()) { return false; } continue; case 142 /* GlobalKeyword */: nextToken(); return token() === 17 /* OpenBraceToken */ || token() === 71 /* Identifier */ || token() === 84 /* ExportKeyword */; case 91 /* ImportKeyword */: nextToken(); return token() === 9 /* StringLiteral */ || token() === 39 /* AsteriskToken */ || token() === 17 /* OpenBraceToken */ || ts.tokenIsIdentifierOrKeyword(token()); case 84 /* ExportKeyword */: nextToken(); if (token() === 58 /* EqualsToken */ || token() === 39 /* AsteriskToken */ || token() === 17 /* OpenBraceToken */ || token() === 79 /* DefaultKeyword */ || token() === 118 /* AsKeyword */) { return true; } continue; case 115 /* StaticKeyword */: nextToken(); continue; default: return false; } } } function isStartOfDeclaration() { return lookAhead(isDeclaration); } function isStartOfStatement() { switch (token()) { case 57 /* AtToken */: case 25 /* SemicolonToken */: case 17 /* OpenBraceToken */: case 104 /* VarKeyword */: case 110 /* LetKeyword */: case 89 /* FunctionKeyword */: case 75 /* ClassKeyword */: case 83 /* EnumKeyword */: case 90 /* IfKeyword */: case 81 /* DoKeyword */: case 106 /* WhileKeyword */: case 88 /* ForKeyword */: case 77 /* ContinueKeyword */: case 72 /* BreakKeyword */: case 96 /* ReturnKeyword */: case 107 /* WithKeyword */: case 98 /* SwitchKeyword */: case 100 /* ThrowKeyword */: case 102 /* TryKeyword */: case 78 /* DebuggerKeyword */: // 'catch' and 'finally' do not actually indicate that the code is part of a statement, // however, we say they are here so that we may gracefully parse them and error later. case 74 /* CatchKeyword */: case 87 /* FinallyKeyword */: return true; case 91 /* ImportKeyword */: return isStartOfDeclaration() || lookAhead(nextTokenIsOpenParenOrLessThan); case 76 /* ConstKeyword */: case 84 /* ExportKeyword */: return isStartOfDeclaration(); case 120 /* AsyncKeyword */: case 124 /* DeclareKeyword */: case 109 /* InterfaceKeyword */: case 128 /* ModuleKeyword */: case 129 /* NamespaceKeyword */: case 138 /* TypeKeyword */: case 142 /* GlobalKeyword */: // When these don't start a declaration, they're an identifier in an expression statement return true; case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 115 /* StaticKeyword */: case 131 /* ReadonlyKeyword */: // When these don't start a declaration, they may be the start of a class member if an identifier // immediately follows. Otherwise they're an identifier in an expression statement. return isStartOfDeclaration() || !lookAhead(nextTokenIsIdentifierOrKeywordOnSameLine); default: return isStartOfExpression(); } } function nextTokenIsIdentifierOrStartOfDestructuring() { nextToken(); return isIdentifier() || token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */; } function isLetDeclaration() { // In ES6 'let' always starts a lexical declaration if followed by an identifier or { // or [. return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring); } function parseStatement() { switch (token()) { case 25 /* SemicolonToken */: return parseEmptyStatement(); case 17 /* OpenBraceToken */: return parseBlock(/*ignoreMissingOpenBrace*/ false); case 104 /* VarKeyword */: return parseVariableStatement(createNodeWithJSDoc(227 /* VariableDeclaration */)); case 110 /* LetKeyword */: if (isLetDeclaration()) { return parseVariableStatement(createNodeWithJSDoc(227 /* VariableDeclaration */)); } break; case 89 /* FunctionKeyword */: return parseFunctionDeclaration(createNodeWithJSDoc(229 /* FunctionDeclaration */)); case 75 /* ClassKeyword */: return parseClassDeclaration(createNodeWithJSDoc(230 /* ClassDeclaration */)); case 90 /* IfKeyword */: return parseIfStatement(); case 81 /* DoKeyword */: return parseDoStatement(); case 106 /* WhileKeyword */: return parseWhileStatement(); case 88 /* ForKeyword */: return parseForOrForInOrForOfStatement(); case 77 /* ContinueKeyword */: return parseBreakOrContinueStatement(218 /* ContinueStatement */); case 72 /* BreakKeyword */: return parseBreakOrContinueStatement(219 /* BreakStatement */); case 96 /* ReturnKeyword */: return parseReturnStatement(); case 107 /* WithKeyword */: return parseWithStatement(); case 98 /* SwitchKeyword */: return parseSwitchStatement(); case 100 /* ThrowKeyword */: return parseThrowStatement(); case 102 /* TryKeyword */: // Include 'catch' and 'finally' for error recovery. case 74 /* CatchKeyword */: case 87 /* FinallyKeyword */: return parseTryStatement(); case 78 /* DebuggerKeyword */: return parseDebuggerStatement(); case 57 /* AtToken */: return parseDeclaration(); case 120 /* AsyncKeyword */: case 109 /* InterfaceKeyword */: case 138 /* TypeKeyword */: case 128 /* ModuleKeyword */: case 129 /* NamespaceKeyword */: case 124 /* DeclareKeyword */: case 76 /* ConstKeyword */: case 83 /* EnumKeyword */: case 84 /* ExportKeyword */: case 91 /* ImportKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 114 /* PublicKeyword */: case 117 /* AbstractKeyword */: case 115 /* StaticKeyword */: case 131 /* ReadonlyKeyword */: case 142 /* GlobalKeyword */: if (isStartOfDeclaration()) { return parseDeclaration(); } break; } return parseExpressionOrLabeledStatement(); } function isDeclareModifier(modifier) { return modifier.kind === 124 /* DeclareKeyword */; } function parseDeclaration() { var node = createNodeWithJSDoc(0 /* Unknown */); node.decorators = parseDecorators(); node.modifiers = parseModifiers(); if (ts.some(node.modifiers, isDeclareModifier)) { for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) { var m = _a[_i]; m.flags |= 2097152 /* Ambient */; } return doInsideOfContext(2097152 /* Ambient */, function () { return parseDeclarationWorker(node); }); } else { return parseDeclarationWorker(node); } } function parseDeclarationWorker(node) { switch (token()) { case 104 /* VarKeyword */: case 110 /* LetKeyword */: case 76 /* ConstKeyword */: return parseVariableStatement(node); case 89 /* FunctionKeyword */: return parseFunctionDeclaration(node); case 75 /* ClassKeyword */: return parseClassDeclaration(node); case 109 /* InterfaceKeyword */: return parseInterfaceDeclaration(node); case 138 /* TypeKeyword */: return parseTypeAliasDeclaration(node); case 83 /* EnumKeyword */: return parseEnumDeclaration(node); case 142 /* GlobalKeyword */: case 128 /* ModuleKeyword */: case 129 /* NamespaceKeyword */: return parseModuleDeclaration(node); case 91 /* ImportKeyword */: return parseImportDeclarationOrImportEqualsDeclaration(node); case 84 /* ExportKeyword */: nextToken(); switch (token()) { case 79 /* DefaultKeyword */: case 58 /* EqualsToken */: return parseExportAssignment(node); case 118 /* AsKeyword */: return parseNamespaceExportDeclaration(node); default: return parseExportDeclaration(node); } default: if (node.decorators || node.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 missing = createMissingNode(248 /* MissingDeclaration */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected); missing.pos = node.pos; missing.decorators = node.decorators; missing.modifiers = node.modifiers; return finishNode(missing); } } } function nextTokenIsIdentifierOrStringLiteralOnSameLine() { nextToken(); return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token() === 9 /* StringLiteral */); } function parseFunctionBlockOrSemicolon(flags, diagnosticMessage) { if (token() !== 17 /* OpenBraceToken */ && canParseSemicolon()) { parseSemicolon(); return; } return parseFunctionBlock(flags, diagnosticMessage); } // DECLARATIONS function parseArrayBindingElement() { if (token() === 26 /* CommaToken */) { return createNode(201 /* OmittedExpression */); } var node = createNode(177 /* BindingElement */); node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */); node.name = parseIdentifierOrPattern(); node.initializer = parseInitializer(); return finishNode(node); } function parseObjectBindingElement() { var node = createNode(177 /* BindingElement */); node.dotDotDotToken = parseOptionalToken(24 /* DotDotDotToken */); var tokenIsIdentifier = isIdentifier(); var propertyName = parsePropertyName(); if (tokenIsIdentifier && token() !== 56 /* ColonToken */) { node.name = propertyName; } else { parseExpected(56 /* ColonToken */); node.propertyName = propertyName; node.name = parseIdentifierOrPattern(); } node.initializer = parseInitializer(); return finishNode(node); } function parseObjectBindingPattern() { var node = createNode(175 /* ObjectBindingPattern */); parseExpected(17 /* OpenBraceToken */); node.elements = parseDelimitedList(9 /* ObjectBindingElements */, parseObjectBindingElement); parseExpected(18 /* CloseBraceToken */); return finishNode(node); } function parseArrayBindingPattern() { var node = createNode(176 /* ArrayBindingPattern */); parseExpected(21 /* OpenBracketToken */); node.elements = parseDelimitedList(10 /* ArrayBindingElements */, parseArrayBindingElement); parseExpected(22 /* CloseBracketToken */); return finishNode(node); } function isIdentifierOrPattern() { return token() === 17 /* OpenBraceToken */ || token() === 21 /* OpenBracketToken */ || isIdentifier(); } function parseIdentifierOrPattern() { if (token() === 21 /* OpenBracketToken */) { return parseArrayBindingPattern(); } if (token() === 17 /* OpenBraceToken */) { return parseObjectBindingPattern(); } return parseIdentifier(); } function parseVariableDeclarationAllowExclamation() { return parseVariableDeclaration(/*allowExclamation*/ true); } function parseVariableDeclaration(allowExclamation) { var node = createNode(227 /* VariableDeclaration */); node.name = parseIdentifierOrPattern(); if (allowExclamation && node.name.kind === 71 /* Identifier */ && token() === 51 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) { node.exclamationToken = parseTokenNode(); } node.type = parseTypeAnnotation(); if (!isInOrOfKeyword(token())) { node.initializer = parseInitializer(); } return finishNode(node); } function parseVariableDeclarationList(inForStatementInitializer) { var node = createNode(228 /* VariableDeclarationList */); switch (token()) { case 104 /* VarKeyword */: break; case 110 /* LetKeyword */: node.flags |= 1 /* Let */; break; case 76 /* ConstKeyword */: node.flags |= 2 /* Const */; break; default: ts.Debug.fail(); } nextToken(); // The user may have written the following: // // for (let of X) { } // // In this case, we want to parse an empty declaration list, and then parse 'of' // as a keyword. The reason this is not automatic is that 'of' is a valid identifier. // So we need to look ahead to determine if 'of' should be treated as a keyword in // this context. // The checker will then give an error that there is an empty declaration list. if (token() === 143 /* OfKeyword */ && lookAhead(canFollowContextualOfKeyword)) { node.declarations = createMissingList(); } else { var savedDisallowIn = inDisallowInContext(); setDisallowInContext(inForStatementInitializer); node.declarations = parseDelimitedList(8 /* VariableDeclarations */, inForStatementInitializer ? parseVariableDeclaration : parseVariableDeclarationAllowExclamation); setDisallowInContext(savedDisallowIn); } return finishNode(node); } function canFollowContextualOfKeyword() { return nextTokenIsIdentifier() && nextToken() === 20 /* CloseParenToken */; } function parseVariableStatement(node) { node.kind = 209 /* VariableStatement */; node.declarationList = parseVariableDeclarationList(/*inForStatementInitializer*/ false); parseSemicolon(); return finishNode(node); } function parseFunctionDeclaration(node) { node.kind = 229 /* FunctionDeclaration */; parseExpected(89 /* FunctionKeyword */); node.asteriskToken = parseOptionalToken(39 /* AsteriskToken */); node.name = ts.hasModifier(node, 512 /* Default */) ? parseOptionalIdentifier() : parseIdentifier(); var isGenerator = node.asteriskToken ? 1 /* Yield */ : 0 /* None */; var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; fillSignature(56 /* ColonToken */, isGenerator | isAsync, node); node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, ts.Diagnostics.or_expected); return finishNode(node); } function parseConstructorDeclaration(node) { node.kind = 153 /* Constructor */; parseExpected(123 /* ConstructorKeyword */); fillSignature(56 /* ColonToken */, 0 /* None */, node); node.body = parseFunctionBlockOrSemicolon(0 /* None */, ts.Diagnostics.or_expected); return finishNode(node); } function parseMethodDeclaration(node, asteriskToken, diagnosticMessage) { node.kind = 152 /* MethodDeclaration */; node.asteriskToken = asteriskToken; var isGenerator = asteriskToken ? 1 /* Yield */ : 0 /* None */; var isAsync = ts.hasModifier(node, 256 /* Async */) ? 2 /* Await */ : 0 /* None */; fillSignature(56 /* ColonToken */, isGenerator | isAsync, node); node.body = parseFunctionBlockOrSemicolon(isGenerator | isAsync, diagnosticMessage); return finishNode(node); } function parsePropertyDeclaration(node) { node.kind = 150 /* PropertyDeclaration */; if (!node.questionToken && token() === 51 /* ExclamationToken */ && !scanner.hasPrecedingLineBreak()) { node.exclamationToken = parseTokenNode(); } node.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. node.initializer = ts.hasModifier(node, 32 /* Static */) ? allowInAnd(parseInitializer) : doOutsideOfContext(4096 /* YieldContext */ | 2048 /* DisallowInContext */, parseInitializer); parseSemicolon(); return finishNode(node); } function parsePropertyOrMethodDeclaration(node) { var asteriskToken = parseOptionalToken(39 /* AsteriskToken */); node.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. node.questionToken = parseOptionalToken(55 /* QuestionToken */); if (asteriskToken || token() === 19 /* OpenParenToken */ || token() === 27 /* LessThanToken */) { return parseMethodDeclaration(node, asteriskToken, ts.Diagnostics.or_expected); } return parsePropertyDeclaration(node); } function parseAccessorDeclaration(node, kind) { node.kind = kind; node.name = parsePropertyName(); fillSignature(56 /* ColonToken */, 0 /* None */, node); node.body = parseFunctionBlockOrSemicolon(0 /* None */); return finishNode(node); } function isClassMemberModifier(idToken) { switch (idToken) { case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 115 /* StaticKeyword */: case 131 /* ReadonlyKeyword */: return true; default: return false; } } function isClassMemberStart() { var idToken; if (token() === 57 /* AtToken */) { return true; } // Eat up all modifiers, but hold on to the last one in case it is actually an identifier. while (ts.isModifierKind(token())) { idToken = token(); // If the idToken is a class modifier (protected, private, public, and static), it is // certain that we are starting to parse class member. This allows better error recovery // Example: // public foo() ... // true // public @dec blah ... // true; we will then report an error later // export public ... // true; we will then report an error later if (isClassMemberModifier(idToken)) { return true; } nextToken(); } if (token() === 39 /* AsteriskToken */) { return true; } // Try to get the first property-like token following all modifiers. // This can either be an identifier or the 'get' or 'set' keywords. if (isLiteralPropertyName()) { idToken = token(); nextToken(); } // Index signatures and computed properties are class members; we can parse. if (token() === 21 /* OpenBracketToken */) { return true; } // If we were able to get any potential identifier... if (idToken !== undefined) { // If we have a non-keyword identifier, or if we have an accessor, then it's safe to parse. if (!ts.isKeyword(idToken) || idToken === 135 /* SetKeyword */ || idToken === 125 /* GetKeyword */) { return true; } // If it *is* a keyword, but not an accessor, check a little farther along // to see if it should actually be parsed as a class member. switch (token()) { case 19 /* OpenParenToken */: // Method declaration case 27 /* LessThanToken */: // Generic Method declaration case 56 /* ColonToken */: // Type Annotation for declaration case 58 /* EqualsToken */: // Initializer for declaration case 55 /* QuestionToken */:// Not valid, but permitted so that it gets caught later on. return true; default: // Covers // - Semicolons (declaration termination) // - Closing braces (end-of-class, must be declaration) // - End-of-files (not valid, but permitted so that it gets caught later on) // - Line-breaks (enabling *automatic semicolon insertion*) return canParseSemicolon(); } } return false; } function parseDecorators() { var list; var listPos = getNodePos(); while (true) { var decoratorStart = getNodePos(); if (!parseOptional(57 /* AtToken */)) { break; } var decorator = createNode(148 /* Decorator */, decoratorStart); decorator.expression = doInDecoratorContext(parseLeftHandSideExpressionOrHigher); finishNode(decorator); (list || (list = [])).push(decorator); } return list && createNodeArray(list, listPos); } /* * There are situations in which a modifier like 'const' will appear unexpectedly, such as on a class member. * In those situations, if we are entirely sure that 'const' is not valid on its own (such as when ASI takes effect * and turns it into a standalone declaration), then it is better to parse it and report an error later. * * In such situations, 'permitInvalidConstAsModifier' should be set to true. */ function parseModifiers(permitInvalidConstAsModifier) { var list; var listPos = getNodePos(); while (true) { var modifierStart = scanner.getStartPos(); var modifierKind = token(); if (token() === 76 /* ConstKeyword */ && permitInvalidConstAsModifier) { // We need to ensure that any subsequent modifiers appear on the same line // so that when 'const' is a standalone declaration, we don't issue an error. if (!tryParse(nextTokenIsOnSameLineAndCanFollowModifier)) { break; } } else { if (!parseAnyContextualModifier()) { break; } } var modifier = finishNode(createNode(modifierKind, modifierStart)); (list || (list = [])).push(modifier); } return list && createNodeArray(list, listPos); } function parseModifiersForArrowFunction() { var modifiers; if (token() === 120 /* AsyncKeyword */) { var modifierStart = scanner.getStartPos(); var modifierKind = token(); nextToken(); var modifier = finishNode(createNode(modifierKind, modifierStart)); modifiers = createNodeArray([modifier], modifierStart); } return modifiers; } function parseClassElement() { if (token() === 25 /* SemicolonToken */) { var result = createNode(207 /* SemicolonClassElement */); nextToken(); return finishNode(result); } var node = createNodeWithJSDoc(0 /* Unknown */); node.decorators = parseDecorators(); node.modifiers = parseModifiers(/*permitInvalidConstAsModifier*/ true); if (parseContextualModifier(125 /* GetKeyword */)) { return parseAccessorDeclaration(node, 154 /* GetAccessor */); } if (parseContextualModifier(135 /* SetKeyword */)) { return parseAccessorDeclaration(node, 155 /* SetAccessor */); } if (token() === 123 /* ConstructorKeyword */) { return parseConstructorDeclaration(node); } if (isIndexSignature()) { return parseIndexSignatureDeclaration(node); } // It is very important that we check this *after* checking indexers because // the [ token can start an index signature or a computed property name if (ts.tokenIsIdentifierOrKeyword(token()) || token() === 9 /* StringLiteral */ || token() === 8 /* NumericLiteral */ || token() === 39 /* AsteriskToken */ || token() === 21 /* OpenBracketToken */) { return parsePropertyOrMethodDeclaration(node); } if (node.decorators || node.modifiers) { // treat this as a property declaration with a missing name. node.name = createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Declaration_expected); return parsePropertyDeclaration(node); } // 'isClassMemberStart' should have hinted not to attempt parsing. ts.Debug.fail("Should not have attempted to parse class member declaration."); } function parseClassExpression() { return parseClassDeclarationOrExpression(createNodeWithJSDoc(0 /* Unknown */), 200 /* ClassExpression */); } function parseClassDeclaration(node) { return parseClassDeclarationOrExpression(node, 230 /* ClassDeclaration */); } function parseClassDeclarationOrExpression(node, kind) { node.kind = kind; parseExpected(75 /* ClassKeyword */); node.name = parseNameOfClassDeclarationOrExpression(); node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(); if (parseExpected(17 /* OpenBraceToken */)) { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } node.members = parseClassMembers(); parseExpected(18 /* CloseBraceToken */); } else { node.members = createMissingList(); } return finishNode(node); } function parseNameOfClassDeclarationOrExpression() { // implements is a future reserved word so // 'class implements' might mean either // - class expression with omitted name, 'implements' starts heritage clause // - class with name 'implements' // 'isImplementsClause' helps to disambiguate between these two cases return isIdentifier() && !isImplementsClause() ? parseIdentifier() : undefined; } function isImplementsClause() { return token() === 108 /* ImplementsKeyword */ && lookAhead(nextTokenIsIdentifierOrKeyword); } function parseHeritageClauses() { // ClassTail[Yield,Await] : (Modified) See 14.5 // ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt } if (isHeritageClause()) { return parseList(21 /* HeritageClauses */, parseHeritageClause); } return undefined; } function parseHeritageClause() { var tok = token(); if (tok === 85 /* ExtendsKeyword */ || tok === 108 /* ImplementsKeyword */) { var node = createNode(263 /* HeritageClause */); node.token = tok; nextToken(); node.types = parseDelimitedList(7 /* HeritageClauseElement */, parseExpressionWithTypeArguments); return finishNode(node); } return undefined; } function parseExpressionWithTypeArguments() { var node = createNode(202 /* ExpressionWithTypeArguments */); node.expression = parseLeftHandSideExpressionOrHigher(); node.typeArguments = tryParseTypeArguments(); return finishNode(node); } function tryParseTypeArguments() { return token() === 27 /* LessThanToken */ ? parseBracketedList(19 /* TypeArguments */, parseType, 27 /* LessThanToken */, 29 /* GreaterThanToken */) : undefined; } function isHeritageClause() { return token() === 85 /* ExtendsKeyword */ || token() === 108 /* ImplementsKeyword */; } function parseClassMembers() { return parseList(5 /* ClassMembers */, parseClassElement); } function parseInterfaceDeclaration(node) { node.kind = 231 /* InterfaceDeclaration */; parseExpected(109 /* InterfaceKeyword */); node.name = parseIdentifier(); node.typeParameters = parseTypeParameters(); node.heritageClauses = parseHeritageClauses(); node.members = parseObjectTypeMembers(); return finishNode(node); } function parseTypeAliasDeclaration(node) { node.kind = 232 /* TypeAliasDeclaration */; parseExpected(138 /* TypeKeyword */); node.name = parseIdentifier(); node.typeParameters = parseTypeParameters(); parseExpected(58 /* 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 = createNodeWithJSDoc(268 /* EnumMember */); node.name = parsePropertyName(); node.initializer = allowInAnd(parseInitializer); return finishNode(node); } function parseEnumDeclaration(node) { node.kind = 233 /* EnumDeclaration */; parseExpected(83 /* EnumKeyword */); node.name = parseIdentifier(); if (parseExpected(17 /* OpenBraceToken */)) { node.members = parseDelimitedList(6 /* EnumMembers */, parseEnumMember); parseExpected(18 /* CloseBraceToken */); } else { node.members = createMissingList(); } return finishNode(node); } function parseModuleBlock() { var node = createNode(235 /* ModuleBlock */); if (parseExpected(17 /* OpenBraceToken */)) { node.statements = parseList(1 /* BlockStatements */, parseStatement); parseExpected(18 /* CloseBraceToken */); } else { node.statements = createMissingList(); } return finishNode(node); } function parseModuleOrNamespaceDeclaration(node, flags) { node.kind = 234 /* ModuleDeclaration */; // If we are parsing a dotted namespace name, we want to // propagate the 'Namespace' flag across the names if set. var namespaceFlag = flags & 16 /* Namespace */; node.flags |= flags; node.name = parseIdentifier(); node.body = parseOptional(23 /* DotToken */) ? parseModuleOrNamespaceDeclaration(createNode(0 /* Unknown */), 4 /* NestedNamespace */ | namespaceFlag) : parseModuleBlock(); return finishNode(node); } function parseAmbientExternalModuleDeclaration(node) { node.kind = 234 /* ModuleDeclaration */; if (token() === 142 /* GlobalKeyword */) { // parse 'global' as name of global scope augmentation node.name = parseIdentifier(); node.flags |= 512 /* GlobalAugmentation */; } else { node.name = parseLiteralNode(); node.name.text = internIdentifier(node.name.text); } if (token() === 17 /* OpenBraceToken */) { node.body = parseModuleBlock(); } else { parseSemicolon(); } return finishNode(node); } function parseModuleDeclaration(node) { var flags = 0; if (token() === 142 /* GlobalKeyword */) { // global augmentation return parseAmbientExternalModuleDeclaration(node); } else if (parseOptional(129 /* NamespaceKeyword */)) { flags |= 16 /* Namespace */; } else { parseExpected(128 /* ModuleKeyword */); if (token() === 9 /* StringLiteral */) { return parseAmbientExternalModuleDeclaration(node); } } return parseModuleOrNamespaceDeclaration(node, flags); } function isExternalModuleReference() { return token() === 132 /* RequireKeyword */ && lookAhead(nextTokenIsOpenParen); } function nextTokenIsOpenParen() { return nextToken() === 19 /* OpenParenToken */; } function nextTokenIsSlash() { return nextToken() === 41 /* SlashToken */; } function parseNamespaceExportDeclaration(node) { node.kind = 237 /* NamespaceExportDeclaration */; parseExpected(118 /* AsKeyword */); parseExpected(129 /* NamespaceKeyword */); node.name = parseIdentifier(); parseSemicolon(); return finishNode(node); } function parseImportDeclarationOrImportEqualsDeclaration(node) { parseExpected(91 /* ImportKeyword */); var afterImportPos = scanner.getStartPos(); var identifier; if (isIdentifier()) { identifier = parseIdentifier(); if (token() !== 26 /* CommaToken */ && token() !== 141 /* FromKeyword */) { return parseImportEqualsDeclaration(node, identifier); } } // Import statement node.kind = 239 /* ImportDeclaration */; // ImportDeclaration: // import ImportClause from ModuleSpecifier ; // import ModuleSpecifier; if (identifier || // import id token() === 39 /* AsteriskToken */ || // import * token() === 17 /* OpenBraceToken */) { node.importClause = parseImportClause(identifier, afterImportPos); parseExpected(141 /* FromKeyword */); } node.moduleSpecifier = parseModuleSpecifier(); parseSemicolon(); return finishNode(node); } function parseImportEqualsDeclaration(node, identifier) { node.kind = 238 /* ImportEqualsDeclaration */; node.name = identifier; parseExpected(58 /* EqualsToken */); node.moduleReference = parseModuleReference(); parseSemicolon(); return finishNode(node); } function parseImportClause(identifier, fullStart) { // ImportClause: // ImportedDefaultBinding // NameSpaceImport // NamedImports // ImportedDefaultBinding, NameSpaceImport // ImportedDefaultBinding, NamedImports var importClause = createNode(240 /* ImportClause */, fullStart); if (identifier) { // ImportedDefaultBinding: // ImportedBinding importClause.name = identifier; } // If there was no default import or if there is comma token after default import // parse namespace or named imports if (!importClause.name || parseOptional(26 /* CommaToken */)) { importClause.namedBindings = token() === 39 /* AsteriskToken */ ? parseNamespaceImport() : parseNamedImportsOrExports(242 /* NamedImports */); } return finishNode(importClause); } function parseModuleReference() { return isExternalModuleReference() ? parseExternalModuleReference() : parseEntityName(/*allowReservedWords*/ false); } function parseExternalModuleReference() { var node = createNode(249 /* ExternalModuleReference */); parseExpected(132 /* RequireKeyword */); parseExpected(19 /* OpenParenToken */); node.expression = parseModuleSpecifier(); parseExpected(20 /* CloseParenToken */); return finishNode(node); } function parseModuleSpecifier() { if (token() === 9 /* StringLiteral */) { var result = parseLiteralNode(); result.text = internIdentifier(result.text); return result; } else { // We allow arbitrary expressions here, even though the grammar only allows string // literals. We check to ensure that it is only a string literal later in the grammar // check pass. return parseExpression(); } } function parseNamespaceImport() { // NameSpaceImport: // * as ImportedBinding var namespaceImport = createNode(241 /* NamespaceImport */); parseExpected(39 /* AsteriskToken */); parseExpected(118 /* AsKeyword */); namespaceImport.name = parseIdentifier(); return finishNode(namespaceImport); } function parseNamedImportsOrExports(kind) { var node = createNode(kind); // NamedImports: // { } // { ImportsList } // { ImportsList, } // ImportsList: // ImportSpecifier // ImportsList, ImportSpecifier node.elements = parseBracketedList(22 /* ImportOrExportSpecifiers */, kind === 242 /* NamedImports */ ? parseImportSpecifier : parseExportSpecifier, 17 /* OpenBraceToken */, 18 /* CloseBraceToken */); return finishNode(node); } function parseExportSpecifier() { return parseImportOrExportSpecifier(247 /* ExportSpecifier */); } function parseImportSpecifier() { return parseImportOrExportSpecifier(243 /* ImportSpecifier */); } function parseImportOrExportSpecifier(kind) { var node = createNode(kind); // ImportSpecifier: // BindingIdentifier // IdentifierName as BindingIdentifier // ExportSpecifier: // IdentifierName // IdentifierName as IdentifierName var checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier(); var checkIdentifierStart = scanner.getTokenPos(); var checkIdentifierEnd = scanner.getTextPos(); var identifierName = parseIdentifierName(); if (token() === 118 /* AsKeyword */) { node.propertyName = identifierName; parseExpected(118 /* AsKeyword */); checkIdentifierIsKeyword = ts.isKeyword(token()) && !isIdentifier(); checkIdentifierStart = scanner.getTokenPos(); checkIdentifierEnd = scanner.getTextPos(); node.name = parseIdentifierName(); } else { node.name = identifierName; } if (kind === 243 /* ImportSpecifier */ && checkIdentifierIsKeyword) { // Report error identifier expected parseErrorAtPosition(checkIdentifierStart, checkIdentifierEnd - checkIdentifierStart, ts.Diagnostics.Identifier_expected); } return finishNode(node); } function parseExportDeclaration(node) { node.kind = 245 /* ExportDeclaration */; if (parseOptional(39 /* AsteriskToken */)) { parseExpected(141 /* FromKeyword */); node.moduleSpecifier = parseModuleSpecifier(); } else { node.exportClause = parseNamedImportsOrExports(246 /* 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() === 141 /* FromKeyword */ || (token() === 9 /* StringLiteral */ && !scanner.hasPrecedingLineBreak())) { parseExpected(141 /* FromKeyword */); node.moduleSpecifier = parseModuleSpecifier(); } } parseSemicolon(); return finishNode(node); } function parseExportAssignment(node) { node.kind = 244 /* ExportAssignment */; if (parseOptional(58 /* EqualsToken */)) { node.isExportEquals = true; } else { parseExpected(79 /* DefaultKeyword */); } node.expression = parseAssignmentExpressionOrHigher(); parseSemicolon(); return finishNode(node); } function processReferenceComments(sourceFile) { var triviaScanner = ts.createScanner(sourceFile.languageVersion, /*skipTrivia*/ false, 0 /* Standard */, sourceText); var referencedFiles = []; var typeReferenceDirectives = []; var amdDependencies = []; var amdModuleName; var checkJsDirective = undefined; // Keep scanning all the leading trivia in the file until we get to something that // isn't trivia. Any single line comment will be analyzed to see if it is a // reference comment. while (true) { var kind = triviaScanner.scan(); if (kind !== 2 /* SingleLineCommentTrivia */) { if (ts.isTrivia(kind)) { continue; } else { break; } } var range = { kind: triviaScanner.getToken(), pos: triviaScanner.getTokenPos(), end: triviaScanner.getTextPos(), }; var comment = sourceText.substring(range.pos, range.end); var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, range); if (referencePathMatchResult) { var fileReference = referencePathMatchResult.fileReference; sourceFile.hasNoDefaultLib = referencePathMatchResult.isNoDefaultLib; var diagnosticMessage = referencePathMatchResult.diagnosticMessage; if (fileReference) { if (referencePathMatchResult.isTypeReferenceDirective) { typeReferenceDirectives.push(fileReference); } else { referencedFiles.push(fileReference); } } if (diagnosticMessage) { parseDiagnostics.push(ts.createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, diagnosticMessage)); } } else { var amdModuleNameRegEx = /^\/\/\/\s*= 0); ts.Debug.assert(start <= end); ts.Debug.assert(end <= content.length); var tags; var tagsPos; var tagsEnd; var comments = []; var result; // Check for /** (JSDoc opening part) if (!isJsDocStart(content, start)) { return result; } // + 3 for leading /**, - 5 in total for /** */ scanner.scanRange(start + 3, length - 5, function () { // Initially we can parse out a tag. We also have seen a starting asterisk. // This is so that /** * @type */ doesn't parse. var advanceToken = true; var state = 1 /* SawAsterisk */; var margin = undefined; // + 4 for leading '/** ' var indent = start - Math.max(content.lastIndexOf("\n", start), 0) + 4; function pushComment(text) { if (!margin) { margin = indent; } comments.push(text); indent += text.length; } nextJSDocToken(); while (token() === 5 /* WhitespaceTrivia */) { nextJSDocToken(); } if (token() === 4 /* NewLineTrivia */) { state = 0 /* BeginningOfLine */; indent = 0; nextJSDocToken(); } while (token() !== 1 /* EndOfFileToken */) { switch (token()) { case 57 /* AtToken */: if (state === 0 /* BeginningOfLine */ || state === 1 /* SawAsterisk */) { removeTrailingNewlines(comments); parseTag(indent); // NOTE: According to usejsdoc.org, a tag goes to end of line, except the last tag. // Real-world comments may break this rule, so "BeginningOfLine" will not be a real line beginning // for malformed examples like `/** @param {string} x @returns {number} the length */` state = 0 /* BeginningOfLine */; advanceToken = false; margin = undefined; indent++; } else { pushComment(scanner.getTokenText()); } break; case 4 /* NewLineTrivia */: comments.push(scanner.getTokenText()); state = 0 /* BeginningOfLine */; indent = 0; break; case 39 /* AsteriskToken */: var asterisk = scanner.getTokenText(); if (state === 1 /* SawAsterisk */ || state === 2 /* SavingComments */) { // If we've already seen an asterisk, then we can no longer parse a tag on this line state = 2 /* SavingComments */; pushComment(asterisk); } else { // Ignore the first asterisk on a line state = 1 /* SawAsterisk */; indent += asterisk.length; } break; case 71 /* Identifier */: // Anything else is doc comment text. We just save it. Because it // wasn't a tag, we can no longer parse a tag on this line until we hit the next // line break. pushComment(scanner.getTokenText()); state = 2 /* SavingComments */; break; case 5 /* WhitespaceTrivia */: // only collect whitespace if we're already saving comments or have just crossed the comment indent margin var whitespace = scanner.getTokenText(); if (state === 2 /* SavingComments */) { comments.push(whitespace); } else if (margin !== undefined && indent + whitespace.length > margin) { comments.push(whitespace.slice(margin - indent - 1)); } indent += whitespace.length; break; case 1 /* EndOfFileToken */: break; default: // anything other than whitespace or asterisk at the beginning of the line starts the comment text state = 2 /* SavingComments */; pushComment(scanner.getTokenText()); break; } if (advanceToken) { nextJSDocToken(); } else { advanceToken = true; } } removeLeadingNewlines(comments); removeTrailingNewlines(comments); result = createJSDocComment(); }); return result; function removeLeadingNewlines(comments) { while (comments.length && (comments[0] === "\n" || comments[0] === "\r")) { comments.shift(); } } function removeTrailingNewlines(comments) { while (comments.length && (comments[comments.length - 1] === "\n" || comments[comments.length - 1] === "\r")) { comments.pop(); } } function isJsDocStart(content, start) { return content.charCodeAt(start) === 47 /* slash */ && content.charCodeAt(start + 1) === 42 /* asterisk */ && content.charCodeAt(start + 2) === 42 /* asterisk */ && content.charCodeAt(start + 3) !== 42 /* asterisk */; } function createJSDocComment() { var result = createNode(279 /* JSDocComment */, start); result.tags = tags && createNodeArray(tags, tagsPos, tagsEnd); result.comment = comments.length ? comments.join("") : undefined; return finishNode(result, end); } function skipWhitespace() { while (token() === 5 /* WhitespaceTrivia */ || token() === 4 /* NewLineTrivia */) { nextJSDocToken(); } } function parseTag(indent) { ts.Debug.assert(token() === 57 /* AtToken */); var atToken = createNode(57 /* AtToken */, scanner.getTokenPos()); atToken.end = scanner.getTextPos(); nextJSDocToken(); var tagName = parseJSDocIdentifierName(); skipWhitespace(); if (!tagName) { return; } var tag; if (tagName) { switch (tagName.escapedText) { case "augments": case "extends": tag = parseAugmentsTag(atToken, tagName); break; case "class": case "constructor": tag = parseClassTag(atToken, tagName); break; case "arg": case "argument": case "param": tag = parseParameterOrPropertyTag(atToken, tagName, 1 /* Parameter */); break; case "return": case "returns": tag = parseReturnTag(atToken, tagName); break; case "template": tag = parseTemplateTag(atToken, tagName); break; case "type": tag = parseTypeTag(atToken, tagName); break; case "typedef": tag = parseTypedefTag(atToken, tagName); break; default: tag = parseUnknownTag(atToken, tagName); break; } } else { tag = parseUnknownTag(atToken, tagName); } if (!tag) { // a badly malformed tag should not be added to the list of tags return; } addTag(tag, parseTagComments(indent + tag.end - tag.pos)); } function parseTagComments(indent) { var comments = []; var state = 0 /* BeginningOfLine */; var margin; function pushComment(text) { if (!margin) { margin = indent; } comments.push(text); indent += text.length; } while (token() !== 57 /* AtToken */ && token() !== 1 /* EndOfFileToken */) { switch (token()) { case 4 /* NewLineTrivia */: if (state >= 1 /* SawAsterisk */) { state = 0 /* BeginningOfLine */; comments.push(scanner.getTokenText()); } indent = 0; break; case 57 /* AtToken */: // Done break; case 5 /* WhitespaceTrivia */: if (state === 2 /* SavingComments */) { pushComment(scanner.getTokenText()); } else { var whitespace = scanner.getTokenText(); // if the whitespace crosses the margin, take only the whitespace that passes the margin if (margin !== undefined && indent + whitespace.length > margin) { comments.push(whitespace.slice(margin - indent - 1)); } indent += whitespace.length; } break; case 39 /* AsteriskToken */: if (state === 0 /* BeginningOfLine */) { // leading asterisks start recording on the *next* (non-whitespace) token state = 1 /* SawAsterisk */; indent += scanner.getTokenText().length; break; } // record the * as a comment // falls through default: state = 2 /* SavingComments */; // leading identifiers start recording as well pushComment(scanner.getTokenText()); break; } if (token() === 57 /* AtToken */) { // Done break; } nextJSDocToken(); } removeLeadingNewlines(comments); removeTrailingNewlines(comments); return comments; } function parseUnknownTag(atToken, tagName) { var result = createNode(281 /* JSDocTag */, atToken.pos); result.atToken = atToken; result.tagName = tagName; return finishNode(result); } function addTag(tag, comments) { tag.comment = comments.join(""); if (!tags) { tags = [tag]; tagsPos = tag.pos; } else { tags.push(tag); } tagsEnd = tag.end; } function tryParseTypeExpression() { skipWhitespace(); return token() === 17 /* OpenBraceToken */ ? parseJSDocTypeExpression() : undefined; } function parseBracketNameInPropertyAndParamTag() { // Looking for something like '[foo]', 'foo', '[foo.bar]' or 'foo.bar' var isBracketed = parseOptional(21 /* OpenBracketToken */); var name = parseJSDocEntityName(); if (isBracketed) { skipWhitespace(); // May have an optional default, e.g. '[foo = 42]' if (parseOptionalToken(58 /* EqualsToken */)) { parseExpression(); } parseExpected(22 /* CloseBracketToken */); } return { name: name, isBracketed: isBracketed }; } function isObjectOrObjectArrayTypeReference(node) { switch (node.kind) { case 134 /* ObjectKeyword */: return true; case 165 /* ArrayType */: return isObjectOrObjectArrayTypeReference(node.elementType); default: return ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && node.typeName.escapedText === "Object"; } } function parseParameterOrPropertyTag(atToken, tagName, target) { var typeExpression = tryParseTypeExpression(); var isNameFirst = !typeExpression; skipWhitespace(); var _a = parseBracketNameInPropertyAndParamTag(), name = _a.name, isBracketed = _a.isBracketed; skipWhitespace(); if (isNameFirst) { typeExpression = tryParseTypeExpression(); } var result = target === 1 /* Parameter */ ? createNode(284 /* JSDocParameterTag */, atToken.pos) : createNode(289 /* JSDocPropertyTag */, atToken.pos); var nestedTypeLiteral = parseNestedTypeLiteral(typeExpression, name); if (nestedTypeLiteral) { typeExpression = nestedTypeLiteral; isNameFirst = true; } result.atToken = atToken; result.tagName = tagName; result.typeExpression = typeExpression; result.name = name; result.isNameFirst = isNameFirst; result.isBracketed = isBracketed; return finishNode(result); } function parseNestedTypeLiteral(typeExpression, name) { if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) { var typeLiteralExpression = createNode(271 /* JSDocTypeExpression */, scanner.getTokenPos()); var child = void 0; var jsdocTypeLiteral = void 0; var start_2 = scanner.getStartPos(); var children = void 0; while (child = tryParse(function () { return parseChildParameterOrPropertyTag(1 /* Parameter */, name); })) { if (!children) { children = []; } children.push(child); } if (children) { jsdocTypeLiteral = createNode(280 /* JSDocTypeLiteral */, start_2); jsdocTypeLiteral.jsDocPropertyTags = children; if (typeExpression.type.kind === 165 /* ArrayType */) { jsdocTypeLiteral.isArrayType = true; } typeLiteralExpression.type = finishNode(jsdocTypeLiteral); return finishNode(typeLiteralExpression); } } } function parseReturnTag(atToken, tagName) { if (ts.forEach(tags, function (t) { return t.kind === 285 /* JSDocReturnTag */; })) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText); } var result = createNode(285 /* JSDocReturnTag */, atToken.pos); result.atToken = atToken; result.tagName = tagName; result.typeExpression = tryParseTypeExpression(); return finishNode(result); } function parseTypeTag(atToken, tagName) { if (ts.forEach(tags, function (t) { return t.kind === 286 /* JSDocTypeTag */; })) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText); } var result = createNode(286 /* JSDocTypeTag */, atToken.pos); result.atToken = atToken; result.tagName = tagName; result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); return finishNode(result); } function parseAugmentsTag(atToken, tagName) { var result = createNode(282 /* JSDocAugmentsTag */, atToken.pos); result.atToken = atToken; result.tagName = tagName; result.class = parseExpressionWithTypeArgumentsForAugments(); return finishNode(result); } function parseExpressionWithTypeArgumentsForAugments() { var usedBrace = parseOptional(17 /* OpenBraceToken */); var node = createNode(202 /* ExpressionWithTypeArguments */); node.expression = parsePropertyAccessEntityNameExpression(); node.typeArguments = tryParseTypeArguments(); var res = finishNode(node); if (usedBrace) { parseExpected(18 /* CloseBraceToken */); } return res; } function parsePropertyAccessEntityNameExpression() { var node = parseJSDocIdentifierName(/*createIfMissing*/ true); while (parseOptional(23 /* DotToken */)) { var prop = createNode(180 /* PropertyAccessExpression */, node.pos); prop.expression = node; prop.name = parseJSDocIdentifierName(); node = finishNode(prop); } return node; } function parseClassTag(atToken, tagName) { var tag = createNode(283 /* JSDocClassTag */, atToken.pos); tag.atToken = atToken; tag.tagName = tagName; return finishNode(tag); } function parseTypedefTag(atToken, tagName) { var typeExpression = tryParseTypeExpression(); skipWhitespace(); var typedefTag = createNode(288 /* JSDocTypedefTag */, atToken.pos); typedefTag.atToken = atToken; typedefTag.tagName = tagName; typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0); if (typedefTag.fullName) { var rightNode = typedefTag.fullName; while (true) { if (rightNode.kind === 71 /* Identifier */ || !rightNode.body) { // if node is identifier - use it as name // otherwise use name of the rightmost part that we were able to parse typedefTag.name = rightNode.kind === 71 /* Identifier */ ? rightNode : rightNode.name; break; } rightNode = rightNode.body; } } skipWhitespace(); typedefTag.typeExpression = typeExpression; if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) { var child = void 0; var jsdocTypeLiteral = void 0; var childTypeTag = void 0; var start_3 = scanner.getStartPos(); while (child = tryParse(function () { return parseChildParameterOrPropertyTag(0 /* Property */); })) { if (!jsdocTypeLiteral) { jsdocTypeLiteral = createNode(280 /* JSDocTypeLiteral */, start_3); } if (child.kind === 286 /* JSDocTypeTag */) { if (childTypeTag) { break; } else { childTypeTag = child; } } else { if (!jsdocTypeLiteral.jsDocPropertyTags) { jsdocTypeLiteral.jsDocPropertyTags = []; } jsdocTypeLiteral.jsDocPropertyTags.push(child); } } if (jsdocTypeLiteral) { if (typeExpression && typeExpression.type.kind === 165 /* ArrayType */) { jsdocTypeLiteral.isArrayType = true; } typedefTag.typeExpression = childTypeTag && childTypeTag.typeExpression && !isObjectOrObjectArrayTypeReference(childTypeTag.typeExpression.type) ? childTypeTag.typeExpression : finishNode(jsdocTypeLiteral); } } return finishNode(typedefTag); function parseJSDocTypeNameWithNamespace(flags) { var pos = scanner.getTokenPos(); var typeNameOrNamespaceName = parseJSDocIdentifierName(); if (typeNameOrNamespaceName && parseOptional(23 /* DotToken */)) { var jsDocNamespaceNode = createNode(234 /* ModuleDeclaration */, pos); jsDocNamespaceNode.flags |= flags; jsDocNamespaceNode.name = typeNameOrNamespaceName; jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(4 /* NestedNamespace */); return finishNode(jsDocNamespaceNode); } if (typeNameOrNamespaceName && flags & 4 /* NestedNamespace */) { typeNameOrNamespaceName.isInJSDocNamespace = true; } return typeNameOrNamespaceName; } } function escapedTextsEqual(a, b) { while (!ts.isIdentifier(a) || !ts.isIdentifier(b)) { if (!ts.isIdentifier(a) && !ts.isIdentifier(b) && a.right.escapedText === b.right.escapedText) { a = a.left; b = b.left; } else { return false; } } return a.escapedText === b.escapedText; } function parseChildParameterOrPropertyTag(target, name) { var canParseTag = true; var seenAsterisk = false; while (true) { nextJSDocToken(); switch (token()) { case 57 /* AtToken */: if (canParseTag) { var child = tryParseChildTag(target); if (child && child.kind === 284 /* JSDocParameterTag */ && (ts.isIdentifier(child.name) || !escapedTextsEqual(name, child.name.left))) { return false; } return child; } seenAsterisk = false; break; case 4 /* NewLineTrivia */: canParseTag = true; seenAsterisk = false; break; case 39 /* AsteriskToken */: if (seenAsterisk) { canParseTag = false; } seenAsterisk = true; break; case 71 /* Identifier */: canParseTag = false; break; case 1 /* EndOfFileToken */: return false; } } } function tryParseChildTag(target) { ts.Debug.assert(token() === 57 /* AtToken */); var atToken = createNode(57 /* AtToken */); atToken.end = scanner.getTextPos(); nextJSDocToken(); var tagName = parseJSDocIdentifierName(); skipWhitespace(); if (!tagName) { return false; } switch (tagName.escapedText) { case "type": return target === 0 /* Property */ && parseTypeTag(atToken, tagName); case "prop": case "property": return target === 0 /* Property */ && parseParameterOrPropertyTag(atToken, tagName, target); case "arg": case "argument": case "param": return target === 1 /* Parameter */ && parseParameterOrPropertyTag(atToken, tagName, target); } return false; } function parseTemplateTag(atToken, tagName) { if (ts.forEach(tags, function (t) { return t.kind === 287 /* JSDocTemplateTag */; })) { parseErrorAtPosition(tagName.pos, scanner.getTokenPos() - tagName.pos, ts.Diagnostics._0_tag_already_specified, tagName.escapedText); } // Type parameter list looks like '@template T,U,V' var typeParameters = []; var typeParametersPos = getNodePos(); while (true) { var name = parseJSDocIdentifierName(); skipWhitespace(); if (!name) { parseErrorAtPosition(scanner.getStartPos(), 0, ts.Diagnostics.Identifier_expected); return undefined; } var typeParameter = createNode(146 /* TypeParameter */, name.pos); typeParameter.name = name; finishNode(typeParameter); typeParameters.push(typeParameter); if (token() === 26 /* CommaToken */) { nextJSDocToken(); skipWhitespace(); } else { break; } } var result = createNode(287 /* JSDocTemplateTag */, atToken.pos); result.atToken = atToken; result.tagName = tagName; result.typeParameters = createNodeArray(typeParameters, typeParametersPos); finishNode(result); return result; } function nextJSDocToken() { return currentToken = scanner.scanJSDocToken(); } function parseJSDocEntityName() { var entity = parseJSDocIdentifierName(/*createIfMissing*/ true); if (parseOptional(21 /* OpenBracketToken */)) { parseExpected(22 /* CloseBracketToken */); // Note that y[] is accepted as an entity name, but the postfix brackets are not saved for checking. // Technically usejsdoc.org requires them for specifying a property of a type equivalent to Array<{ x: ...}> // but it's not worth it to enforce that restriction. } while (parseOptional(23 /* DotToken */)) { var name = parseJSDocIdentifierName(/*createIfMissing*/ true); if (parseOptional(21 /* OpenBracketToken */)) { parseExpected(22 /* CloseBracketToken */); } entity = createQualifiedName(entity, name); } return entity; } function parseJSDocIdentifierName(createIfMissing) { if (createIfMissing === void 0) { createIfMissing = false; } if (!ts.tokenIsIdentifierOrKeyword(token())) { if (createIfMissing) { return createMissingNode(71 /* Identifier */, /*reportAtCurrentPosition*/ true, ts.Diagnostics.Identifier_expected); } else { parseErrorAtCurrentToken(ts.Diagnostics.Identifier_expected); return undefined; } } var pos = scanner.getTokenPos(); var end = scanner.getTextPos(); var result = createNode(71 /* Identifier */, pos); result.escapedText = ts.escapeLeadingUnderscores(content.substring(pos, end)); finishNode(result, end); nextJSDocToken(); return result; } } JSDocParser.parseJSDocCommentWorker = parseJSDocCommentWorker; })(JSDocParser = Parser.JSDocParser || (Parser.JSDocParser = {})); })(Parser || (Parser = {})); var IncrementalParser; (function (IncrementalParser) { function updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks) { aggressiveChecks = aggressiveChecks || ts.Debug.shouldAssert(2 /* Aggressive */); checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks); if (ts.textChangeRangeIsUnchanged(textChangeRange)) { // if the text didn't change, then we can just return our current source file as-is. return sourceFile; } if (sourceFile.statements.length === 0) { // If we don't have any statements in the current source file, then there's no real // way to incrementally parse. So just do a full parse instead. return Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, /*syntaxCursor*/ undefined, /*setParentNodes*/ true, sourceFile.scriptKind); } // Make sure we're not trying to incrementally update a source file more than once. Once // we do an update the original source file is considered unusable from that point onwards. // // This is because we do incremental parsing in-place. i.e. we take nodes from the old // tree and give them new positions and parents. From that point on, trusting the old // tree at all is not possible as far too much of it may violate invariants. var incrementalSourceFile = sourceFile; ts.Debug.assert(!incrementalSourceFile.hasBeenIncrementallyParsed); incrementalSourceFile.hasBeenIncrementallyParsed = true; var oldText = sourceFile.text; var syntaxCursor = createSyntaxCursor(sourceFile); // Make the actual change larger so that we know to reparse anything whose lookahead // might have intersected the change. var changeRange = extendToAffectedRange(sourceFile, textChangeRange); checkChangeRange(sourceFile, newText, changeRange, aggressiveChecks); // Ensure that extending the affected range only moved the start of the change range // earlier in the file. ts.Debug.assert(changeRange.span.start <= textChangeRange.span.start); ts.Debug.assert(ts.textSpanEnd(changeRange.span) === ts.textSpanEnd(textChangeRange.span)); ts.Debug.assert(ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)) === ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange))); // The is the amount the nodes after the edit range need to be adjusted. It can be // positive (if the edit added characters), negative (if the edit deleted characters) // or zero (if this was a pure overwrite with nothing added/removed). var delta = ts.textChangeRangeNewSpan(changeRange).length - changeRange.span.length; // If we added or removed characters during the edit, then we need to go and adjust all // the nodes after the edit. Those nodes may move forward (if we inserted chars) or they // may move backward (if we deleted chars). // // Doing this helps us out in two ways. First, it means that any nodes/tokens we want // to reuse are already at the appropriate position in the new text. That way when we // reuse them, we don't have to figure out if they need to be adjusted. Second, it makes // it very easy to determine if we can reuse a node. If the node's position is at where // we are in the text, then we can reuse it. Otherwise we can't. If the node's position // is ahead of us, then we'll need to rescan tokens. If the node's position is behind // us, then we'll need to skip it or crumble it as appropriate // // We will also adjust the positions of nodes that intersect the change range as well. // By doing this, we ensure that all the positions in the old tree are consistent, not // just the positions of nodes entirely before/after the change range. By being // consistent, we can then easily map from positions to nodes in the old tree easily. // // Also, mark any syntax elements that intersect the changed span. We know, up front, // that we cannot reuse these elements. updateTokenPositionsAndMarkElements(incrementalSourceFile, changeRange.span.start, ts.textSpanEnd(changeRange.span), ts.textSpanEnd(ts.textChangeRangeNewSpan(changeRange)), delta, oldText, newText, aggressiveChecks); // Now that we've set up our internal incremental state just proceed and parse the // source file in the normal fashion. When possible the parser will retrieve and // reuse nodes from the old tree. // // Note: passing in 'true' for setNodeParents is very important. When incrementally // parsing, we will be reusing nodes from the old tree, and placing it into new // parents. If we don't set the parents now, we'll end up with an observably // inconsistent tree. Setting the parents on the new tree should be very fast. We // will immediately bail out of walking any subtrees when we can see that their parents // are already correct. var result = Parser.parseSourceFile(sourceFile.fileName, newText, sourceFile.languageVersion, syntaxCursor, /*setParentNodes*/ true, sourceFile.scriptKind); return result; } IncrementalParser.updateSourceFile = updateSourceFile; function moveElementEntirelyPastChangeRange(element, isArray, delta, oldText, newText, aggressiveChecks) { if (isArray) { visitArray(element); } else { visitNode(element); } return; function visitNode(node) { var text = ""; if (aggressiveChecks && shouldCheckNode(node)) { text = oldText.substring(node.pos, node.end); } // Ditch any existing LS children we may have created. This way we can avoid // moving them forward. if (node._children) { node._children = undefined; } node.pos += delta; node.end += delta; if (aggressiveChecks && shouldCheckNode(node)) { ts.Debug.assert(text === newText.substring(node.pos, node.end)); } forEachChild(node, visitNode, visitArray); if (ts.hasJSDocNodes(node)) { for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) { var jsDocComment = _a[_i]; forEachChild(jsDocComment, visitNode, visitArray); } } checkNodePositions(node, aggressiveChecks); } function visitArray(array) { array._children = undefined; array.pos += delta; array.end += delta; for (var _i = 0, array_8 = array; _i < array_8.length; _i++) { var node = array_8[_i]; visitNode(node); } } } function shouldCheckNode(node) { switch (node.kind) { case 9 /* StringLiteral */: case 8 /* NumericLiteral */: case 71 /* Identifier */: return true; } return false; } function adjustIntersectingElement(element, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta) { ts.Debug.assert(element.end >= changeStart, "Adjusting an element that was entirely before the change range"); ts.Debug.assert(element.pos <= changeRangeOldEnd, "Adjusting an element that was entirely after the change range"); ts.Debug.assert(element.pos <= element.end); // We have an element that intersects the change range in some way. It may have its // start, or its end (or both) in the changed range. We want to adjust any part // that intersects such that the final tree is in a consistent state. i.e. all // children have spans within the span of their parent, and all siblings are ordered // properly. // We may need to update both the 'pos' and the 'end' of the element. // If the 'pos' is before the start of the change, then we don't need to touch it. // If it isn't, then the 'pos' must be inside the change. How we update it will // depend if delta is positive or negative. If delta is positive then we have // something like: // // -------------------AAA----------------- // -------------------BBBCCCCCCC----------------- // // In this case, we consider any node that started in the change range to still be // starting at the same position. // // however, if the delta is negative, then we instead have something like this: // // -------------------XXXYYYYYYY----------------- // -------------------ZZZ----------------- // // In this case, any element that started in the 'X' range will keep its position. // However any element that started after that will have their pos adjusted to be // at the end of the new range. i.e. any node that started in the 'Y' range will // be adjusted to have their start at the end of the 'Z' range. // // The element will keep its position if possible. Or Move backward to the new-end // if it's in the 'Y' range. element.pos = Math.min(element.pos, changeRangeNewEnd); // If the 'end' is after the change range, then we always adjust it by the delta // amount. However, if the end is in the change range, then how we adjust it // will depend on if delta is positive or negative. If delta is positive then we // have something like: // // -------------------AAA----------------- // -------------------BBBCCCCCCC----------------- // // In this case, we consider any node that ended inside the change range to keep its // end position. // // however, if the delta is negative, then we instead have something like this: // // -------------------XXXYYYYYYY----------------- // -------------------ZZZ----------------- // // In this case, any element that ended in the 'X' range will keep its position. // However any element that ended after that will have their pos adjusted to be // at the end of the new range. i.e. any node that ended in the 'Y' range will // be adjusted to have their end at the end of the 'Z' range. if (element.end >= changeRangeOldEnd) { // Element ends after the change range. Always adjust the end pos. element.end += delta; } else { // Element ends in the change range. The element will keep its position if // possible. Or Move backward to the new-end if it's in the 'Y' range. element.end = Math.min(element.end, changeRangeNewEnd); } ts.Debug.assert(element.pos <= element.end); if (element.parent) { ts.Debug.assert(element.pos >= element.parent.pos); ts.Debug.assert(element.end <= element.parent.end); } } function checkNodePositions(node, aggressiveChecks) { if (aggressiveChecks) { var pos_2 = node.pos; forEachChild(node, function (child) { ts.Debug.assert(child.pos >= pos_2); pos_2 = child.end; }); ts.Debug.assert(pos_2 <= node.end); } } function updateTokenPositionsAndMarkElements(sourceFile, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta, oldText, newText, aggressiveChecks) { visitNode(sourceFile); return; function visitNode(child) { ts.Debug.assert(child.pos <= child.end); if (child.pos > changeRangeOldEnd) { // Node is entirely past the change range. We need to move both its pos and // end, forward or backward appropriately. moveElementEntirelyPastChangeRange(child, /*isArray*/ false, delta, oldText, newText, aggressiveChecks); return; } // Check if the element intersects the change range. If it does, then it is not // reusable. Also, we'll need to recurse to see what constituent portions we may // be able to use. var fullEnd = child.end; if (fullEnd >= changeStart) { child.intersectsChange = true; child._children = undefined; // Adjust the pos or end (or both) of the intersecting element accordingly. adjustIntersectingElement(child, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); forEachChild(child, visitNode, visitArray); checkNodePositions(child, aggressiveChecks); return; } // Otherwise, the node is entirely before the change range. No need to do anything with it. ts.Debug.assert(fullEnd < changeStart); } function visitArray(array) { ts.Debug.assert(array.pos <= array.end); if (array.pos > changeRangeOldEnd) { // Array is entirely after the change range. We need to move it, and move any of // its children. moveElementEntirelyPastChangeRange(array, /*isArray*/ true, delta, oldText, newText, aggressiveChecks); return; } // Check if the element intersects the change range. If it does, then it is not // reusable. Also, we'll need to recurse to see what constituent portions we may // be able to use. var fullEnd = array.end; if (fullEnd >= changeStart) { array.intersectsChange = true; array._children = undefined; // Adjust the pos or end (or both) of the intersecting array accordingly. adjustIntersectingElement(array, changeStart, changeRangeOldEnd, changeRangeNewEnd, delta); for (var _i = 0, array_9 = array; _i < array_9.length; _i++) { var node = array_9[_i]; visitNode(node); } return; } // Otherwise, the array is entirely before the change range. No need to do anything with it. ts.Debug.assert(fullEnd < changeStart); } } function extendToAffectedRange(sourceFile, changeRange) { // Consider the following code: // void foo() { /; } // // If the text changes with an insertion of / just before the semicolon then we end up with: // void foo() { //; } // // If we were to just use the changeRange a is, then we would not rescan the { token // (as it does not intersect the actual original change range). Because an edit may // change the token touching it, we actually need to look back *at least* one token so // that the prior token sees that change. var maxLookahead = 1; var start = changeRange.span.start; // the first iteration aligns us with the change start. subsequent iteration move us to // the left by maxLookahead tokens. We only need to do this as long as we're not at the // start of the tree. for (var i = 0; start > 0 && i <= maxLookahead; i++) { var nearestNode = findNearestNodeStartingBeforeOrAtPosition(sourceFile, start); ts.Debug.assert(nearestNode.pos <= start); var position = nearestNode.pos; start = Math.max(0, position - 1); } var finalSpan = ts.createTextSpanFromBounds(start, ts.textSpanEnd(changeRange.span)); var finalLength = changeRange.newLength + (changeRange.span.start - start); return ts.createTextChangeRange(finalSpan, finalLength); } function findNearestNodeStartingBeforeOrAtPosition(sourceFile, position) { var bestResult = sourceFile; var lastNodeEntirelyBeforePosition; forEachChild(sourceFile, visit); if (lastNodeEntirelyBeforePosition) { var lastChildOfLastEntireNodeBeforePosition = getLastChild(lastNodeEntirelyBeforePosition); if (lastChildOfLastEntireNodeBeforePosition.pos > bestResult.pos) { bestResult = lastChildOfLastEntireNodeBeforePosition; } } return bestResult; function getLastChild(node) { while (true) { var lastChild = getLastChildWorker(node); if (lastChild) { node = lastChild; } else { return node; } } } function getLastChildWorker(node) { var last = undefined; forEachChild(node, function (child) { if (ts.nodeIsPresent(child)) { last = child; } }); return last; } function visit(child) { if (ts.nodeIsMissing(child)) { // Missing nodes are effectively invisible to us. We never even consider them // When trying to find the nearest node before us. return; } // If the child intersects this position, then this node is currently the nearest // node that starts before the position. if (child.pos <= position) { if (child.pos >= bestResult.pos) { // This node starts before the position, and is closer to the position than // the previous best node we found. It is now the new best node. bestResult = child; } // Now, the node may overlap the position, or it may end entirely before the // position. If it overlaps with the position, then either it, or one of its // children must be the nearest node before the position. So we can just // recurse into this child to see if we can find something better. if (position < child.end) { // The nearest node is either this child, or one of the children inside // of it. We've already marked this child as the best so far. Recurse // in case one of the children is better. forEachChild(child, visit); // Once we look at the children of this node, then there's no need to // continue any further. return true; } else { ts.Debug.assert(child.end <= position); // The child ends entirely before this position. Say you have the following // (where $ is the position) // // ? $ : <...> <...> // // We would want to find the nearest preceding node in "complex expr 2". // To support that, we keep track of this node, and once we're done searching // for a best node, we recurse down this node to see if we can find a good // result in it. // // This approach allows us to quickly skip over nodes that are entirely // before the position, while still allowing us to find any nodes in the // last one that might be what we want. lastNodeEntirelyBeforePosition = child; } } else { ts.Debug.assert(child.pos > position); // We're now at a node that is entirely past the position we're searching for. // This node (and all following nodes) could never contribute to the result, // so just skip them by returning 'true' here. return true; } } } function checkChangeRange(sourceFile, newText, textChangeRange, aggressiveChecks) { var oldText = sourceFile.text; if (textChangeRange) { ts.Debug.assert((oldText.length - textChangeRange.span.length + textChangeRange.newLength) === newText.length); if (aggressiveChecks || ts.Debug.shouldAssert(3 /* VeryAggressive */)) { var oldTextPrefix = oldText.substr(0, textChangeRange.span.start); var newTextPrefix = newText.substr(0, textChangeRange.span.start); ts.Debug.assert(oldTextPrefix === newTextPrefix); var oldTextSuffix = oldText.substring(ts.textSpanEnd(textChangeRange.span), oldText.length); var newTextSuffix = newText.substring(ts.textSpanEnd(ts.textChangeRangeNewSpan(textChangeRange)), newText.length); ts.Debug.assert(oldTextSuffix === newTextSuffix); } } } function createSyntaxCursor(sourceFile) { var currentArray = sourceFile.statements; var currentArrayIndex = 0; ts.Debug.assert(currentArrayIndex < currentArray.length); var current = currentArray[currentArrayIndex]; var lastQueriedPosition = -1 /* Value */; return { currentNode: function (position) { // Only compute the current node if the position is different than the last time // we were asked. The parser commonly asks for the node at the same position // twice. Once to know if can read an appropriate list element at a certain point, // and then to actually read and consume the node. if (position !== lastQueriedPosition) { // Much of the time the parser will need the very next node in the array that // we just returned a node from.So just simply check for that case and move // forward in the array instead of searching for the node again. if (current && current.end === position && currentArrayIndex < (currentArray.length - 1)) { currentArrayIndex++; current = currentArray[currentArrayIndex]; } // If we don't have a node, or the node we have isn't in the right position, // then try to find a viable node at the position requested. if (!current || current.pos !== position) { findHighestListElementThatStartsAtPosition(position); } } // Cache this query so that we don't do any extra work if the parser calls back // into us. Note: this is very common as the parser will make pairs of calls like // 'isListElement -> parseListElement'. If we were unable to find a node when // called with 'isListElement', we don't want to redo the work when parseListElement // is called immediately after. lastQueriedPosition = position; // Either we don'd have a node, or we have a node at the position being asked for. ts.Debug.assert(!current || current.pos === position); return current; } }; // Finds the highest element in the tree we can find that starts at the provided position. // The element must be a direct child of some node list in the tree. This way after we // return it, we can easily return its next sibling in the list. function findHighestListElementThatStartsAtPosition(position) { // Clear out any cached state about the last node we found. currentArray = undefined; currentArrayIndex = -1 /* Value */; current = undefined; // Recurse into the source file to find the highest node at this position. forEachChild(sourceFile, visitNode, visitArray); return; function visitNode(node) { if (position >= node.pos && position < node.end) { // Position was within this node. Keep searching deeper to find the node. forEachChild(node, visitNode, visitArray); // don't proceed any further in the search. return true; } // position wasn't in this node, have to keep searching. return false; } function visitArray(array) { if (position >= array.pos && position < array.end) { // position was in this array. Search through this array to see if we find a // viable element. for (var i = 0; i < array.length; i++) { var child = array[i]; if (child) { if (child.pos === position) { // Found the right node. We're done. currentArray = array; currentArrayIndex = i; current = child; return true; } else { if (child.pos < position && position < child.end) { // Position in somewhere within this child. Search in it and // stop searching in this array. forEachChild(child, visitNode, visitArray); return true; } } } } } // position wasn't in this array, have to keep searching. return false; } } } var InvalidPosition; (function (InvalidPosition) { InvalidPosition[InvalidPosition["Value"] = -1] = "Value"; })(InvalidPosition || (InvalidPosition = {})); })(IncrementalParser || (IncrementalParser = {})); function isDeclarationFileName(fileName) { return ts.fileExtensionIs(fileName, ".d.ts" /* Dts */); } })(ts || (ts = {})); /// /// /// /// /// var ts; (function (ts) { /* @internal */ ts.compileOnSaveCommandLineOption = { name: "compileOnSave", type: "boolean" }; /* @internal */ ts.optionDeclarations = [ // CommandLine only options { name: "help", shortName: "h", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Print_this_message, }, { name: "help", shortName: "?", type: "boolean" }, { name: "all", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Show_all_compiler_options, }, { name: "version", shortName: "v", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Print_the_compiler_s_version, }, { name: "init", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Initializes_a_TypeScript_project_and_creates_a_tsconfig_json_file, }, { name: "project", shortName: "p", type: "string", isFilePath: true, showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, paramType: ts.Diagnostics.FILE_OR_DIRECTORY, description: ts.Diagnostics.Compile_the_project_given_the_path_to_its_configuration_file_or_to_a_folder_with_a_tsconfig_json, }, { name: "pretty", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental }, { name: "watch", shortName: "w", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Command_line_Options, description: ts.Diagnostics.Watch_input_files, }, // Basic { name: "target", shortName: "t", type: ts.createMapFromTemplate({ es3: 0 /* ES3 */, es5: 1 /* ES5 */, es6: 2 /* ES2015 */, es2015: 2 /* ES2015 */, es2016: 3 /* ES2016 */, es2017: 4 /* ES2017 */, es2018: 5 /* ES2018 */, esnext: 6 /* ESNext */, }), paramType: ts.Diagnostics.VERSION, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Specify_ECMAScript_target_version_Colon_ES3_default_ES5_ES2015_ES2016_ES2017_ES2018_or_ESNEXT, }, { name: "module", shortName: "m", type: ts.createMapFromTemplate({ none: ts.ModuleKind.None, commonjs: ts.ModuleKind.CommonJS, amd: ts.ModuleKind.AMD, system: ts.ModuleKind.System, umd: ts.ModuleKind.UMD, es6: ts.ModuleKind.ES2015, es2015: ts.ModuleKind.ES2015, esnext: ts.ModuleKind.ESNext }), paramType: ts.Diagnostics.KIND, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Specify_module_code_generation_Colon_none_commonjs_amd_system_umd_es2015_or_ESNext, }, { name: "lib", type: "list", element: { name: "lib", type: ts.createMapFromTemplate({ // JavaScript only "es5": "lib.es5.d.ts", "es6": "lib.es2015.d.ts", "es2015": "lib.es2015.d.ts", "es7": "lib.es2016.d.ts", "es2016": "lib.es2016.d.ts", "es2017": "lib.es2017.d.ts", "es2018": "lib.es2018.d.ts", "esnext": "lib.esnext.d.ts", // Host only "dom": "lib.dom.d.ts", "dom.iterable": "lib.dom.iterable.d.ts", "webworker": "lib.webworker.d.ts", "scripthost": "lib.scripthost.d.ts", // ES2015 Or ESNext By-feature options "es2015.core": "lib.es2015.core.d.ts", "es2015.collection": "lib.es2015.collection.d.ts", "es2015.generator": "lib.es2015.generator.d.ts", "es2015.iterable": "lib.es2015.iterable.d.ts", "es2015.promise": "lib.es2015.promise.d.ts", "es2015.proxy": "lib.es2015.proxy.d.ts", "es2015.reflect": "lib.es2015.reflect.d.ts", "es2015.symbol": "lib.es2015.symbol.d.ts", "es2015.symbol.wellknown": "lib.es2015.symbol.wellknown.d.ts", "es2016.array.include": "lib.es2016.array.include.d.ts", "es2017.object": "lib.es2017.object.d.ts", "es2017.sharedmemory": "lib.es2017.sharedmemory.d.ts", "es2017.string": "lib.es2017.string.d.ts", "es2017.intl": "lib.es2017.intl.d.ts", "es2017.typedarrays": "lib.es2017.typedarrays.d.ts", "esnext.asynciterable": "lib.esnext.asynciterable.d.ts", }), }, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Specify_library_files_to_be_included_in_the_compilation_Colon }, { name: "allowJs", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Allow_javascript_files_to_be_compiled }, { name: "checkJs", type: "boolean", category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Report_errors_in_js_files }, { name: "jsx", type: ts.createMapFromTemplate({ "preserve": 1 /* Preserve */, "react-native": 3 /* ReactNative */, "react": 2 /* React */ }), paramType: ts.Diagnostics.KIND, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Specify_JSX_code_generation_Colon_preserve_react_native_or_react, }, { name: "declaration", shortName: "d", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Generates_corresponding_d_ts_file, }, { name: "sourceMap", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Generates_corresponding_map_file, }, { name: "outFile", type: "string", isFilePath: true, paramType: ts.Diagnostics.FILE, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Concatenate_and_emit_output_to_single_file, }, { name: "outDir", type: "string", isFilePath: true, paramType: ts.Diagnostics.DIRECTORY, showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Redirect_output_structure_to_the_directory, }, { name: "rootDir", type: "string", isFilePath: true, paramType: ts.Diagnostics.LOCATION, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir, }, { name: "removeComments", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Do_not_emit_comments_to_output, }, { name: "noEmit", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Do_not_emit_outputs, }, { name: "importHelpers", type: "boolean", category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Import_emit_helpers_from_tslib }, { name: "downlevelIteration", type: "boolean", category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Provide_full_support_for_iterables_in_for_of_spread_and_destructuring_when_targeting_ES5_or_ES3 }, { name: "isolatedModules", type: "boolean", category: ts.Diagnostics.Basic_Options, description: ts.Diagnostics.Transpile_each_file_as_a_separate_module_similar_to_ts_transpileModule }, // Strict Type Checks { name: "strict", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Enable_all_strict_type_checking_options }, { name: "noImplicitAny", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Raise_error_on_expressions_and_declarations_with_an_implied_any_type, }, { name: "strictNullChecks", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Enable_strict_null_checks }, { name: "strictFunctionTypes", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Enable_strict_checking_of_function_types }, { name: "strictPropertyInitialization", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Enable_strict_checking_of_property_initialization_in_classes }, { name: "noImplicitThis", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Raise_error_on_this_expressions_with_an_implied_any_type, }, { name: "alwaysStrict", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Strict_Type_Checking_Options, description: ts.Diagnostics.Parse_in_strict_mode_and_emit_use_strict_for_each_source_file }, // Additional Checks { name: "noUnusedLocals", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Additional_Checks, description: ts.Diagnostics.Report_errors_on_unused_locals, }, { name: "noUnusedParameters", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Additional_Checks, description: ts.Diagnostics.Report_errors_on_unused_parameters, }, { name: "noImplicitReturns", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Additional_Checks, description: ts.Diagnostics.Report_error_when_not_all_code_paths_in_function_return_a_value }, { name: "noFallthroughCasesInSwitch", type: "boolean", showInSimplifiedHelpView: true, category: ts.Diagnostics.Additional_Checks, description: ts.Diagnostics.Report_errors_for_fallthrough_cases_in_switch_statement }, // Module Resolution { name: "moduleResolution", type: ts.createMapFromTemplate({ node: ts.ModuleResolutionKind.NodeJs, classic: ts.ModuleResolutionKind.Classic, }), paramType: ts.Diagnostics.STRATEGY, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6, }, { name: "baseUrl", type: "string", isFilePath: true, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Base_directory_to_resolve_non_absolute_module_names }, { // this option can only be specified in tsconfig.json // use type = object to copy the value as-is name: "paths", type: "object", isTSConfigOnly: true, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl }, { // this option can only be specified in tsconfig.json // use type = object to copy the value as-is name: "rootDirs", type: "list", isTSConfigOnly: true, element: { name: "rootDirs", type: "string", isFilePath: true }, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime }, { name: "typeRoots", type: "list", element: { name: "typeRoots", type: "string", isFilePath: true }, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.List_of_folders_to_include_type_definitions_from }, { name: "types", type: "list", element: { name: "types", type: "string" }, showInSimplifiedHelpView: true, category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Type_declaration_files_to_be_included_in_compilation }, { name: "allowSyntheticDefaultImports", type: "boolean", category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking }, { name: "preserveSymlinks", type: "boolean", category: ts.Diagnostics.Module_Resolution_Options, description: ts.Diagnostics.Do_not_resolve_the_real_path_of_symlinks, }, // Source Maps { name: "sourceRoot", type: "string", isFilePath: true, paramType: ts.Diagnostics.LOCATION, category: ts.Diagnostics.Source_Map_Options, description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations, }, { name: "mapRoot", type: "string", isFilePath: true, paramType: ts.Diagnostics.LOCATION, category: ts.Diagnostics.Source_Map_Options, description: ts.Diagnostics.Specify_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations, }, { name: "inlineSourceMap", type: "boolean", category: ts.Diagnostics.Source_Map_Options, description: ts.Diagnostics.Emit_a_single_file_with_source_maps_instead_of_having_a_separate_file }, { name: "inlineSources", type: "boolean", category: ts.Diagnostics.Source_Map_Options, description: ts.Diagnostics.Emit_the_source_alongside_the_sourcemaps_within_a_single_file_requires_inlineSourceMap_or_sourceMap_to_be_set }, // Experimental { name: "experimentalDecorators", type: "boolean", category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_ES7_decorators }, { name: "emitDecoratorMetadata", type: "boolean", category: ts.Diagnostics.Experimental_Options, description: ts.Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators }, // Advanced { name: "jsxFactory", type: "string", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_the_JSX_factory_function_to_use_when_targeting_react_JSX_emit_e_g_React_createElement_or_h }, { name: "diagnostics", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Show_diagnostic_information }, { name: "extendedDiagnostics", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Show_verbose_diagnostic_information }, { name: "traceResolution", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Enable_tracing_of_the_name_resolution_process }, { name: "listFiles", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Print_names_of_files_part_of_the_compilation }, { name: "listEmittedFiles", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Print_names_of_generated_files_part_of_the_compilation }, { name: "out", type: "string", isFilePath: false, // for correct behaviour, please use outFile category: ts.Diagnostics.Advanced_Options, paramType: ts.Diagnostics.FILE, description: ts.Diagnostics.Deprecated_Use_outFile_instead_Concatenate_and_emit_output_to_single_file, }, { name: "reactNamespace", type: "string", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Deprecated_Use_jsxFactory_instead_Specify_the_object_invoked_for_createElement_when_targeting_react_JSX_emit }, { name: "skipDefaultLibCheck", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Deprecated_Use_skipLibCheck_instead_Skip_type_checking_of_default_library_declaration_files }, { name: "charset", type: "string", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.The_character_set_of_the_input_files }, { name: "emitBOM", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Emit_a_UTF_8_Byte_Order_Mark_BOM_in_the_beginning_of_output_files }, { name: "locale", type: "string", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.The_locale_used_when_displaying_messages_to_the_user_e_g_en_us }, { name: "newLine", type: ts.createMapFromTemplate({ crlf: 0 /* CarriageReturnLineFeed */, lf: 1 /* LineFeed */ }), paramType: ts.Diagnostics.NEWLINE, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Specify_the_end_of_line_sequence_to_be_used_when_emitting_files_Colon_CRLF_dos_or_LF_unix, }, { name: "noErrorTruncation", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_truncate_error_messages }, { name: "noLib", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_include_the_default_library_file_lib_d_ts }, { name: "noResolve", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files }, { name: "stripInternal", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_emit_declarations_for_code_that_has_an_internal_annotation, }, { name: "disableSizeLimit", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Disable_size_limitations_on_JavaScript_projects }, { name: "noImplicitUseStrict", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_emit_use_strict_directives_in_module_output }, { name: "noEmitHelpers", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_generate_custom_helper_functions_like_extends_in_compiled_output }, { name: "noEmitOnError", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_emit_outputs_if_any_errors_were_reported, }, { name: "preserveConstEnums", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_erase_const_enum_declarations_in_generated_code }, { name: "declarationDir", type: "string", isFilePath: true, paramType: ts.Diagnostics.DIRECTORY, category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Output_directory_for_generated_declaration_files }, { name: "skipLibCheck", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Skip_type_checking_of_declaration_files, }, { name: "allowUnusedLabels", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_report_errors_on_unused_labels }, { name: "allowUnreachableCode", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Do_not_report_errors_on_unreachable_code }, { name: "suppressExcessPropertyErrors", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Suppress_excess_property_checks_for_object_literals, }, { name: "suppressImplicitAnyIndexErrors", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Suppress_noImplicitAny_errors_for_indexing_objects_lacking_index_signatures, }, { name: "forceConsistentCasingInFileNames", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Disallow_inconsistently_cased_references_to_the_same_file }, { name: "maxNodeModuleJsDepth", type: "number", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files }, { name: "noStrictGenericChecks", type: "boolean", category: ts.Diagnostics.Advanced_Options, description: ts.Diagnostics.Disable_strict_checking_of_generic_signatures_in_function_types, }, { // A list of plugins to load in the language service name: "plugins", type: "list", isTSConfigOnly: true, element: { name: "plugin", type: "object" }, description: ts.Diagnostics.List_of_language_service_plugins } ]; /* @internal */ ts.typeAcquisitionDeclarations = [ { /* @deprecated typingOptions.enableAutoDiscovery * Use typeAcquisition.enable instead. */ name: "enableAutoDiscovery", type: "boolean", }, { name: "enable", type: "boolean", }, { name: "include", type: "list", element: { name: "include", type: "string" } }, { name: "exclude", type: "list", element: { name: "exclude", type: "string" } } ]; /* @internal */ ts.defaultInitCompilerOptions = { module: ts.ModuleKind.CommonJS, target: 1 /* ES5 */, strict: true }; var optionNameMapCache; /* @internal */ function convertEnableAutoDiscoveryToEnable(typeAcquisition) { // Convert deprecated typingOptions.enableAutoDiscovery to typeAcquisition.enable if (typeAcquisition && typeAcquisition.enableAutoDiscovery !== undefined && typeAcquisition.enable === undefined) { var result = { enable: typeAcquisition.enableAutoDiscovery, include: typeAcquisition.include || [], exclude: typeAcquisition.exclude || [] }; return result; } return typeAcquisition; } ts.convertEnableAutoDiscoveryToEnable = convertEnableAutoDiscoveryToEnable; function getOptionNameMap() { if (optionNameMapCache) { return optionNameMapCache; } var optionNameMap = ts.createMap(); var shortOptionNames = ts.createMap(); ts.forEach(ts.optionDeclarations, function (option) { optionNameMap.set(option.name.toLowerCase(), option); if (option.shortName) { shortOptionNames.set(option.shortName, option.name); } }); optionNameMapCache = { optionNameMap: optionNameMap, shortOptionNames: shortOptionNames }; return optionNameMapCache; } /* @internal */ function createCompilerDiagnosticForInvalidCustomType(opt) { return createDiagnosticForInvalidCustomType(opt, ts.createCompilerDiagnostic); } ts.createCompilerDiagnosticForInvalidCustomType = createCompilerDiagnosticForInvalidCustomType; function createDiagnosticForInvalidCustomType(opt, createDiagnostic) { var namesOfType = ts.arrayFrom(opt.type.keys()).map(function (key) { return "'" + key + "'"; }).join(", "); return createDiagnostic(ts.Diagnostics.Argument_for_0_option_must_be_Colon_1, "--" + opt.name, namesOfType); } /* @internal */ function parseCustomTypeOption(opt, value, errors) { return convertJsonOptionOfCustomType(opt, trimString(value || ""), errors); } ts.parseCustomTypeOption = parseCustomTypeOption; /* @internal */ function parseListTypeOption(opt, value, errors) { if (value === void 0) { value = ""; } value = trimString(value); if (ts.startsWith(value, "-")) { return undefined; } if (value === "") { return []; } var values = value.split(","); switch (opt.element.type) { case "number": return ts.map(values, parseInt); case "string": return ts.map(values, function (v) { return v || ""; }); default: return ts.filter(ts.map(values, function (v) { return parseCustomTypeOption(opt.element, v, errors); }), function (v) { return !!v; }); } } ts.parseListTypeOption = parseListTypeOption; function parseCommandLine(commandLine, readFile) { var options = {}; var fileNames = []; var errors = []; parseStrings(commandLine); return { options: options, fileNames: fileNames, errors: errors }; function parseStrings(args) { var i = 0; while (i < args.length) { var s = args[i]; i++; if (s.charCodeAt(0) === 64 /* at */) { parseResponseFile(s.slice(1)); } else if (s.charCodeAt(0) === 45 /* minus */) { var opt = getOptionFromName(s.slice(s.charCodeAt(1) === 45 /* minus */ ? 2 : 1), /*allowShort*/ true); if (opt) { if (opt.isTSConfigOnly) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_can_only_be_specified_in_tsconfig_json_file, opt.name)); } else { // Check to see if no argument was provided (e.g. "--locale" is the last command-line argument). if (!args[i] && opt.type !== "boolean") { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_expects_an_argument, opt.name)); } switch (opt.type) { case "number": options[opt.name] = parseInt(args[i]); i++; break; case "boolean": // boolean flag has optional value true, false, others var optValue = args[i]; options[opt.name] = optValue !== "false"; // consume next argument as boolean flag value if (optValue === "false" || optValue === "true") { i++; } break; case "string": options[opt.name] = args[i] || ""; i++; break; case "list": var result = parseListTypeOption(opt, args[i], errors); options[opt.name] = result || []; if (result) { i++; } break; // If not a primitive, the possible types are specified in what is effectively a map of options. default: options[opt.name] = parseCustomTypeOption(opt, args[i], errors); i++; break; } } } else { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_compiler_option_0, s)); } } else { fileNames.push(s); } } } function parseResponseFile(fileName) { var text = readFile ? readFile(fileName) : ts.sys.readFile(fileName); if (!text) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_not_found, fileName)); return; } var args = []; var pos = 0; while (true) { while (pos < text.length && text.charCodeAt(pos) <= 32 /* space */) pos++; if (pos >= text.length) break; var start = pos; if (text.charCodeAt(start) === 34 /* doubleQuote */) { pos++; while (pos < text.length && text.charCodeAt(pos) !== 34 /* doubleQuote */) pos++; if (pos < text.length) { args.push(text.substring(start + 1, pos)); pos++; } else { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unterminated_quoted_string_in_response_file_0, fileName)); } } else { while (text.charCodeAt(pos) > 32 /* space */) pos++; args.push(text.substring(start, pos)); } } parseStrings(args); } } ts.parseCommandLine = parseCommandLine; function getOptionFromName(optionName, allowShort) { if (allowShort === void 0) { allowShort = false; } optionName = optionName.toLowerCase(); var _a = getOptionNameMap(), optionNameMap = _a.optionNameMap, shortOptionNames = _a.shortOptionNames; // Try to translate short option names to their full equivalents. if (allowShort) { var short = shortOptionNames.get(optionName); if (short !== undefined) { optionName = short; } } return optionNameMap.get(optionName); } /** * Read tsconfig.json file * @param fileName The path to the config file */ function readConfigFile(fileName, readFile) { var textOrDiagnostic = tryReadFile(fileName, readFile); return ts.isString(textOrDiagnostic) ? parseConfigFileTextToJson(fileName, textOrDiagnostic) : { config: {}, error: textOrDiagnostic }; } ts.readConfigFile = readConfigFile; /** * Parse the text of the tsconfig.json file * @param fileName The path to the config file * @param jsonText The text of the config file */ function parseConfigFileTextToJson(fileName, jsonText) { var jsonSourceFile = ts.parseJsonText(fileName, jsonText); return { config: convertToObject(jsonSourceFile, jsonSourceFile.parseDiagnostics), error: jsonSourceFile.parseDiagnostics.length ? jsonSourceFile.parseDiagnostics[0] : undefined }; } ts.parseConfigFileTextToJson = parseConfigFileTextToJson; /** * Read tsconfig.json file * @param fileName The path to the config file */ function readJsonConfigFile(fileName, readFile) { var textOrDiagnostic = tryReadFile(fileName, readFile); return ts.isString(textOrDiagnostic) ? ts.parseJsonText(fileName, textOrDiagnostic) : { parseDiagnostics: [textOrDiagnostic] }; } ts.readJsonConfigFile = readJsonConfigFile; function tryReadFile(fileName, readFile) { var text; try { text = readFile(fileName); } catch (e) { return ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, e.message); } return text === undefined ? ts.createCompilerDiagnostic(ts.Diagnostics.The_specified_path_does_not_exist_Colon_0, fileName) : text; } function commandLineOptionsToMap(options) { return ts.arrayToMap(options, function (option) { return option.name; }); } var _tsconfigRootOptions; function getTsconfigRootOptionsMap() { if (_tsconfigRootOptions === undefined) { _tsconfigRootOptions = commandLineOptionsToMap([ { name: "compilerOptions", type: "object", elementOptions: commandLineOptionsToMap(ts.optionDeclarations), extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_compiler_option_0 }, { name: "typingOptions", type: "object", elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations), extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0 }, { name: "typeAcquisition", type: "object", elementOptions: commandLineOptionsToMap(ts.typeAcquisitionDeclarations), extraKeyDiagnosticMessage: ts.Diagnostics.Unknown_type_acquisition_option_0 }, { name: "extends", type: "string" }, { name: "files", type: "list", element: { name: "files", type: "string" } }, { name: "include", type: "list", element: { name: "include", type: "string" } }, { name: "exclude", type: "list", element: { name: "exclude", type: "string" } }, ts.compileOnSaveCommandLineOption ]); } return _tsconfigRootOptions; } /** * Convert the json syntax tree into the json value */ function convertToObject(sourceFile, errors) { return convertToObjectWorker(sourceFile, errors, /*knownRootOptions*/ undefined, /*jsonConversionNotifier*/ undefined); } ts.convertToObject = convertToObject; /** * Convert the json syntax tree into the json value */ function convertToObjectWorker(sourceFile, errors, knownRootOptions, jsonConversionNotifier) { if (!sourceFile.jsonObject) { return {}; } return convertObjectLiteralExpressionToJson(sourceFile.jsonObject, knownRootOptions, /*extraKeyDiagnosticMessage*/ undefined, /*parentOption*/ undefined); function convertObjectLiteralExpressionToJson(node, knownOptions, extraKeyDiagnosticMessage, parentOption) { var result = {}; for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var element = _a[_i]; if (element.kind !== 265 /* PropertyAssignment */) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element, ts.Diagnostics.Property_assignment_expected)); continue; } if (element.questionToken) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.questionToken, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?")); } if (!isDoubleQuotedString(element.name)) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, ts.Diagnostics.String_literal_with_double_quotes_expected)); } var keyText = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(element.name)); var option = knownOptions ? knownOptions.get(keyText) : undefined; if (extraKeyDiagnosticMessage && !option) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, element.name, extraKeyDiagnosticMessage, keyText)); } var value = convertPropertyValueToJson(element.initializer, option); if (typeof keyText !== "undefined") { result[keyText] = value; // Notify key value set, if user asked for it if (jsonConversionNotifier && // Current callbacks are only on known parent option or if we are setting values in the root (parentOption || knownOptions === knownRootOptions)) { var isValidOptionValue = isCompilerOptionsValue(option, value); if (parentOption) { if (isValidOptionValue) { // Notify option set in the parent if its a valid option value jsonConversionNotifier.onSetValidOptionKeyValueInParent(parentOption, option, value); } } else if (knownOptions === knownRootOptions) { if (isValidOptionValue) { // Notify about the valid root key value being set jsonConversionNotifier.onSetValidOptionKeyValueInRoot(keyText, element.name, value, element.initializer); } else if (!option) { // Notify about the unknown root key value being set jsonConversionNotifier.onSetUnknownOptionKeyValueInRoot(keyText, element.name, value, element.initializer); } } } } } return result; } function convertArrayLiteralExpressionToJson(elements, elementOption) { return elements.map(function (element) { return convertPropertyValueToJson(element, elementOption); }); } function convertPropertyValueToJson(valueExpression, option) { switch (valueExpression.kind) { case 101 /* TrueKeyword */: reportInvalidOptionValue(option && option.type !== "boolean"); return true; case 86 /* FalseKeyword */: reportInvalidOptionValue(option && option.type !== "boolean"); return false; case 95 /* NullKeyword */: reportInvalidOptionValue(option && option.name === "extends"); // "extends" is the only option we don't allow null/undefined for return null; // tslint:disable-line:no-null-keyword case 9 /* StringLiteral */: if (!isDoubleQuotedString(valueExpression)) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.String_literal_with_double_quotes_expected)); } reportInvalidOptionValue(option && (ts.isString(option.type) && option.type !== "string")); var text = valueExpression.text; if (option && !ts.isString(option.type)) { var customOption = option; // Validate custom option type if (!customOption.type.has(text.toLowerCase())) { errors.push(createDiagnosticForInvalidCustomType(customOption, function (message, arg0, arg1) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, message, arg0, arg1); })); } } return text; case 8 /* NumericLiteral */: reportInvalidOptionValue(option && option.type !== "number"); return Number(valueExpression.text); case 193 /* PrefixUnaryExpression */: if (valueExpression.operator !== 38 /* MinusToken */ || valueExpression.operand.kind !== 8 /* NumericLiteral */) { break; // not valid JSON syntax } reportInvalidOptionValue(option && option.type !== "number"); return -Number(valueExpression.operand.text); case 179 /* ObjectLiteralExpression */: reportInvalidOptionValue(option && option.type !== "object"); var objectLiteralExpression = valueExpression; // Currently having element option declaration in the tsconfig with type "object" // determines if it needs onSetValidOptionKeyValueInParent callback or not // At moment there are only "compilerOptions", "typeAcquisition" and "typingOptions" // that satifies it and need it to modify options set in them (for normalizing file paths) // vs what we set in the json // If need arises, we can modify this interface and callbacks as needed if (option) { var _a = option, elementOptions = _a.elementOptions, extraKeyDiagnosticMessage = _a.extraKeyDiagnosticMessage, optionName = _a.name; return convertObjectLiteralExpressionToJson(objectLiteralExpression, elementOptions, extraKeyDiagnosticMessage, optionName); } else { return convertObjectLiteralExpressionToJson(objectLiteralExpression, /* knownOptions*/ undefined, /*extraKeyDiagnosticMessage */ undefined, /*parentOption*/ undefined); } case 178 /* ArrayLiteralExpression */: reportInvalidOptionValue(option && option.type !== "list"); return convertArrayLiteralExpressionToJson(valueExpression.elements, option && option.element); } // Not in expected format if (option) { reportInvalidOptionValue(/*isError*/ true); } else { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Property_value_can_only_be_string_literal_numeric_literal_true_false_null_object_literal_or_array_literal)); } return undefined; function reportInvalidOptionValue(isError) { if (isError) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueExpression, ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, option.name, getCompilerOptionValueTypeString(option))); } } } function isDoubleQuotedString(node) { return ts.isStringLiteral(node) && ts.isStringDoubleQuoted(node, sourceFile); } } function getCompilerOptionValueTypeString(option) { return option.type === "list" ? "Array" : ts.isString(option.type) ? option.type : "string"; } function isCompilerOptionsValue(option, value) { if (option) { if (isNullOrUndefined(value)) return true; // All options are undefinable/nullable if (option.type === "list") { return ts.isArray(value); } var expectedType = ts.isString(option.type) ? option.type : "string"; return typeof value === expectedType; } } /** * Generate tsconfig configuration when running command line "--init" * @param options commandlineOptions to be generated into tsconfig.json * @param fileNames array of filenames to be generated into tsconfig.json */ /* @internal */ function generateTSConfig(options, fileNames, newLine) { var compilerOptions = ts.extend(options, ts.defaultInitCompilerOptions); var compilerOptionsMap = serializeCompilerOptions(compilerOptions); return writeConfigurations(); function getCustomTypeMapOfCommandLineOption(optionDefinition) { if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") { // this is of a type CommandLineOptionOfPrimitiveType return undefined; } else if (optionDefinition.type === "list") { return getCustomTypeMapOfCommandLineOption(optionDefinition.element); } else { return optionDefinition.type; } } function getNameOfCompilerOptionValue(value, customTypeMap) { // There is a typeMap associated with this command-line option so use it to map value back to its name return ts.forEachEntry(customTypeMap, function (mapValue, key) { if (mapValue === value) { return key; } }); } function serializeCompilerOptions(options) { var result = ts.createMap(); var optionsNameMap = getOptionNameMap().optionNameMap; var _loop_3 = function (name) { if (ts.hasProperty(options, name)) { // tsconfig only options cannot be specified via command line, // so we can assume that only types that can appear here string | number | boolean if (optionsNameMap.has(name) && optionsNameMap.get(name).category === ts.Diagnostics.Command_line_Options) { return "continue"; } var value = options[name]; var optionDefinition = optionsNameMap.get(name.toLowerCase()); if (optionDefinition) { var customTypeMap_1 = getCustomTypeMapOfCommandLineOption(optionDefinition); if (!customTypeMap_1) { // There is no map associated with this compiler option then use the value as-is // This is the case if the value is expect to be string, number, boolean or list of string result.set(name, value); } else { if (optionDefinition.type === "list") { result.set(name, value.map(function (element) { return getNameOfCompilerOptionValue(element, customTypeMap_1); })); } else { // There is a typeMap associated with this command-line option so use it to map value back to its name result.set(name, getNameOfCompilerOptionValue(value, customTypeMap_1)); } } } } }; for (var name in options) { _loop_3(name); } return result; } function getDefaultValueForOption(option) { switch (option.type) { case "number": return 1; case "boolean": return true; case "string": return option.isFilePath ? "./" : ""; case "list": return []; case "object": return {}; default: return option.type.keys().next().value; } } function makePadding(paddingLength) { return Array(paddingLength + 1).join(" "); } function writeConfigurations() { // Filter applicable options to place in the file var categorizedOptions = ts.createMultiMap(); for (var _i = 0, optionDeclarations_1 = ts.optionDeclarations; _i < optionDeclarations_1.length; _i++) { var option = optionDeclarations_1[_i]; var category = option.category; if (category !== undefined && category !== ts.Diagnostics.Command_line_Options && category !== ts.Diagnostics.Advanced_Options) { categorizedOptions.add(ts.getLocaleSpecificMessage(category), option); } } // Serialize all options and their descriptions var marginLength = 0; var seenKnownKeys = 0; var nameColumn = []; var descriptionColumn = []; categorizedOptions.forEach(function (options, category) { if (nameColumn.length !== 0) { nameColumn.push(""); descriptionColumn.push(""); } nameColumn.push("/* " + category + " */"); descriptionColumn.push(""); for (var _i = 0, options_1 = options; _i < options_1.length; _i++) { var option = options_1[_i]; var optionName = void 0; if (compilerOptionsMap.has(option.name)) { optionName = "\"" + option.name + "\": " + JSON.stringify(compilerOptionsMap.get(option.name)) + ((seenKnownKeys += 1) === compilerOptionsMap.size ? "" : ","); } else { optionName = "// \"" + option.name + "\": " + JSON.stringify(getDefaultValueForOption(option)) + ","; } nameColumn.push(optionName); descriptionColumn.push("/* " + (option.description && ts.getLocaleSpecificMessage(option.description) || option.name) + " */"); marginLength = Math.max(optionName.length, marginLength); } }); // Write the output var tab = makePadding(2); var result = []; result.push("{"); result.push(tab + "\"compilerOptions\": {"); // Print out each row, aligning all the descriptions on the same column. for (var i = 0; i < nameColumn.length; i++) { var optionName = nameColumn[i]; var description = descriptionColumn[i]; result.push(optionName && "" + tab + tab + optionName + (description && (makePadding(marginLength - optionName.length + 2) + description))); } if (fileNames.length) { result.push(tab + "},"); result.push(tab + "\"files\": ["); for (var i = 0; i < fileNames.length; i++) { result.push("" + tab + tab + JSON.stringify(fileNames[i]) + (i === fileNames.length - 1 ? "" : ",")); } result.push(tab + "]"); } else { result.push(tab + "}"); } result.push("}"); return result.join(newLine); } } ts.generateTSConfig = generateTSConfig; /** * Parse the contents of a config file (tsconfig.json). * @param json The contents of the config file to parse * @param host Instance of ParseConfigHost used to enumerate files in folder. * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ function parseJsonConfigFileContent(json, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) { return parseJsonConfigFileContentWorker(json, /*sourceFile*/ undefined, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions); } ts.parseJsonConfigFileContent = parseJsonConfigFileContent; /** * Parse the contents of a config file (tsconfig.json). * @param jsonNode The contents of the config file to parse * @param host Instance of ParseConfigHost used to enumerate files in folder. * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir */ function parseJsonSourceFileConfigFileContent(sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) { return parseJsonConfigFileContentWorker(/*json*/ undefined, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions); } ts.parseJsonSourceFileConfigFileContent = parseJsonSourceFileConfigFileContent; /*@internal*/ function setConfigFileInOptions(options, configFile) { if (configFile) { Object.defineProperty(options, "configFile", { enumerable: false, writable: false, value: configFile }); } } ts.setConfigFileInOptions = setConfigFileInOptions; function isNullOrUndefined(x) { // tslint:disable-next-line:no-null-keyword return x === undefined || x === null; } function directoryOfCombinedPath(fileName, basePath) { // Use the `identity` function to avoid canonicalizing the path, as it must remain noncanonical // until consistient casing errors are reported return ts.getDirectoryPath(ts.toPath(fileName, basePath, ts.identity)); } /** * Parse the contents of a config file from json or json source file (tsconfig.json). * @param json The contents of the config file to parse * @param sourceFile sourceFile corresponding to the Json * @param host Instance of ParseConfigHost used to enumerate files in folder. * @param basePath A root directory to resolve relative path entries in the config * file to. e.g. outDir * @param resolutionStack Only present for backwards-compatibility. Should be empty. */ function parseJsonConfigFileContentWorker(json, sourceFile, host, basePath, existingOptions, configFileName, resolutionStack, extraFileExtensions) { if (existingOptions === void 0) { existingOptions = {}; } if (resolutionStack === void 0) { resolutionStack = []; } if (extraFileExtensions === void 0) { extraFileExtensions = []; } ts.Debug.assert((json === undefined && sourceFile !== undefined) || (json !== undefined && sourceFile === undefined)); var errors = []; var getCanonicalFileName = ts.createGetCanonicalFileName(host.useCaseSensitiveFileNames); var parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors); var raw = parsedConfig.raw; var options = ts.extend(existingOptions, parsedConfig.options || {}); options.configFilePath = configFileName; setConfigFileInOptions(options, sourceFile); var _a = getFileNames(), fileNames = _a.fileNames, wildcardDirectories = _a.wildcardDirectories, spec = _a.spec; return { options: options, fileNames: fileNames, typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(), raw: raw, errors: errors, wildcardDirectories: wildcardDirectories, compileOnSave: !!raw.compileOnSave, configFileSpecs: spec }; function getFileNames() { var filesSpecs; if (ts.hasProperty(raw, "files") && !isNullOrUndefined(raw.files)) { if (ts.isArray(raw.files)) { filesSpecs = raw.files; if (filesSpecs.length === 0) { createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"); } } else { createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"); } } var includeSpecs; if (ts.hasProperty(raw, "include") && !isNullOrUndefined(raw.include)) { if (ts.isArray(raw.include)) { includeSpecs = raw.include; } else { createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "include", "Array"); } } var excludeSpecs; if (ts.hasProperty(raw, "exclude") && !isNullOrUndefined(raw.exclude)) { if (ts.isArray(raw.exclude)) { excludeSpecs = raw.exclude; } else { createCompilerDiagnosticOnlyIfJson(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "exclude", "Array"); } } else { var outDir = raw.compilerOptions && raw.compilerOptions.outDir; if (outDir) { excludeSpecs = [outDir]; } } if (filesSpecs === undefined && includeSpecs === undefined) { includeSpecs = ["**/*"]; } var result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile); if (result.fileNames.length === 0 && !ts.hasProperty(raw, "files") && resolutionStack.length === 0) { errors.push(getErrorForNoInputFiles(result.spec, configFileName)); } return result; } function createCompilerDiagnosticOnlyIfJson(message, arg0, arg1) { if (!sourceFile) { errors.push(ts.createCompilerDiagnostic(message, arg0, arg1)); } } } /*@internal*/ function isErrorNoInputFiles(error) { return error.code === ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code; } ts.isErrorNoInputFiles = isErrorNoInputFiles; /*@internal*/ function getErrorForNoInputFiles(_a, configFileName) { var includeSpecs = _a.includeSpecs, excludeSpecs = _a.excludeSpecs; return ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2, configFileName || "tsconfig.json", JSON.stringify(includeSpecs || []), JSON.stringify(excludeSpecs || [])); } ts.getErrorForNoInputFiles = getErrorForNoInputFiles; function isSuccessfulParsedTsconfig(value) { return !!value.options; } /** * This *just* extracts options/include/exclude/files out of a config file. * It does *not* resolve the included files. */ function parseConfig(json, sourceFile, host, basePath, configFileName, getCanonicalFileName, resolutionStack, errors) { basePath = ts.normalizeSlashes(basePath); var resolvedPath = ts.toPath(configFileName || "", basePath, getCanonicalFileName); if (resolutionStack.indexOf(resolvedPath) >= 0) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Circularity_detected_while_resolving_configuration_Colon_0, resolutionStack.concat([resolvedPath]).join(" -> "))); return { raw: json || convertToObject(sourceFile, errors) }; } var ownConfig = json ? parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) : parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors); if (ownConfig.extendedConfigPath) { // copy the resolution stack so it is never reused between branches in potential diamond-problem scenarios. resolutionStack = resolutionStack.concat([resolvedPath]); var extendedConfig = getExtendedConfig(sourceFile, ownConfig.extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors); if (extendedConfig && isSuccessfulParsedTsconfig(extendedConfig)) { var baseRaw_1 = extendedConfig.raw; var raw_1 = ownConfig.raw; var setPropertyInRawIfNotUndefined = function (propertyName) { var value = raw_1[propertyName] || baseRaw_1[propertyName]; if (value) { raw_1[propertyName] = value; } }; setPropertyInRawIfNotUndefined("include"); setPropertyInRawIfNotUndefined("exclude"); setPropertyInRawIfNotUndefined("files"); if (raw_1.compileOnSave === undefined) { raw_1.compileOnSave = baseRaw_1.compileOnSave; } ownConfig.options = ts.assign({}, extendedConfig.options, ownConfig.options); // TODO extend type typeAcquisition } } return ownConfig; } function parseOwnConfigOfJson(json, host, basePath, getCanonicalFileName, configFileName, errors) { if (ts.hasProperty(json, "excludes")) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); } var options = convertCompilerOptionsFromJsonWorker(json.compilerOptions, basePath, errors, configFileName); // typingOptions has been deprecated and is only supported for backward compatibility purposes. // It should be removed in future releases - use typeAcquisition instead. var typeAcquisition = convertTypeAcquisitionFromJsonWorker(json.typeAcquisition || json.typingOptions, basePath, errors, configFileName); json.compileOnSave = convertCompileOnSaveOptionFromJson(json, basePath, errors); var extendedConfigPath; if (json.extends) { if (!ts.isString(json.extends)) { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "extends", "string")); } else { var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath; extendedConfigPath = getExtendsConfigPath(json.extends, host, newBase, getCanonicalFileName, errors, ts.createCompilerDiagnostic); } } return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath }; } function parseOwnConfigOfJsonSourceFile(sourceFile, host, basePath, getCanonicalFileName, configFileName, errors) { var options = getDefaultCompilerOptions(configFileName); var typeAcquisition, typingOptionstypeAcquisition; var extendedConfigPath; var optionsIterator = { onSetValidOptionKeyValueInParent: function (parentOption, option, value) { ts.Debug.assert(parentOption === "compilerOptions" || parentOption === "typeAcquisition" || parentOption === "typingOptions"); var currentOption = parentOption === "compilerOptions" ? options : parentOption === "typeAcquisition" ? (typeAcquisition || (typeAcquisition = getDefaultTypeAcquisition(configFileName))) : (typingOptionstypeAcquisition || (typingOptionstypeAcquisition = getDefaultTypeAcquisition(configFileName))); currentOption[option.name] = normalizeOptionValue(option, basePath, value); }, onSetValidOptionKeyValueInRoot: function (key, _keyNode, value, valueNode) { switch (key) { case "extends": var newBase = configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath; extendedConfigPath = getExtendsConfigPath(value, host, newBase, getCanonicalFileName, errors, function (message, arg0) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, message, arg0); }); return; case "files": if (value.length === 0) { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, valueNode, ts.Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json")); } return; } }, onSetUnknownOptionKeyValueInRoot: function (key, keyNode, _value, _valueNode) { if (key === "excludes") { errors.push(ts.createDiagnosticForNodeInSourceFile(sourceFile, keyNode, ts.Diagnostics.Unknown_option_excludes_Did_you_mean_exclude)); } } }; var json = convertToObjectWorker(sourceFile, errors, getTsconfigRootOptionsMap(), optionsIterator); if (!typeAcquisition) { if (typingOptionstypeAcquisition) { typeAcquisition = (typingOptionstypeAcquisition.enableAutoDiscovery !== undefined) ? { enable: typingOptionstypeAcquisition.enableAutoDiscovery, include: typingOptionstypeAcquisition.include, exclude: typingOptionstypeAcquisition.exclude } : typingOptionstypeAcquisition; } else { typeAcquisition = getDefaultTypeAcquisition(configFileName); } } return { raw: json, options: options, typeAcquisition: typeAcquisition, extendedConfigPath: extendedConfigPath }; } function getExtendsConfigPath(extendedConfig, host, basePath, getCanonicalFileName, errors, createDiagnostic) { extendedConfig = ts.normalizeSlashes(extendedConfig); // If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future) if (!(ts.isRootedDiskPath(extendedConfig) || ts.startsWith(extendedConfig, "./") || ts.startsWith(extendedConfig, "../"))) { errors.push(createDiagnostic(ts.Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig)); return undefined; } var extendedConfigPath = ts.toPath(extendedConfig, basePath, getCanonicalFileName); if (!host.fileExists(extendedConfigPath) && !ts.endsWith(extendedConfigPath, ".json" /* Json */)) { extendedConfigPath = extendedConfigPath + ".json"; if (!host.fileExists(extendedConfigPath)) { errors.push(createDiagnostic(ts.Diagnostics.File_0_does_not_exist, extendedConfig)); return undefined; } } return extendedConfigPath; } function getExtendedConfig(sourceFile, extendedConfigPath, host, basePath, getCanonicalFileName, resolutionStack, errors) { var extendedResult = readJsonConfigFile(extendedConfigPath, function (path) { return host.readFile(path); }); if (sourceFile) { (sourceFile.extendedSourceFiles || (sourceFile.extendedSourceFiles = [])).push(extendedResult.fileName); } if (extendedResult.parseDiagnostics.length) { errors.push.apply(errors, extendedResult.parseDiagnostics); return undefined; } var extendedDirname = ts.getDirectoryPath(extendedConfigPath); var extendedConfig = parseConfig(/*json*/ undefined, extendedResult, host, extendedDirname, ts.getBaseFileName(extendedConfigPath), getCanonicalFileName, resolutionStack, errors); if (sourceFile) { (_a = sourceFile.extendedSourceFiles).push.apply(_a, extendedResult.extendedSourceFiles); } if (isSuccessfulParsedTsconfig(extendedConfig)) { // Update the paths to reflect base path var relativeDifference_1 = ts.convertToRelativePath(extendedDirname, basePath, getCanonicalFileName); var updatePath_1 = function (path) { return ts.isRootedDiskPath(path) ? path : ts.combinePaths(relativeDifference_1, path); }; var mapPropertiesInRawIfNotUndefined = function (propertyName) { if (raw_2[propertyName]) { raw_2[propertyName] = ts.map(raw_2[propertyName], updatePath_1); } }; var raw_2 = extendedConfig.raw; mapPropertiesInRawIfNotUndefined("include"); mapPropertiesInRawIfNotUndefined("exclude"); mapPropertiesInRawIfNotUndefined("files"); } return extendedConfig; var _a; } function convertCompileOnSaveOptionFromJson(jsonOption, basePath, errors) { if (!ts.hasProperty(jsonOption, ts.compileOnSaveCommandLineOption.name)) { return undefined; } var result = convertJsonOption(ts.compileOnSaveCommandLineOption, jsonOption.compileOnSave, basePath, errors); if (typeof result === "boolean" && result) { return result; } return false; } function convertCompilerOptionsFromJson(jsonOptions, basePath, configFileName) { var errors = []; var options = convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName); return { options: options, errors: errors }; } ts.convertCompilerOptionsFromJson = convertCompilerOptionsFromJson; function convertTypeAcquisitionFromJson(jsonOptions, basePath, configFileName) { var errors = []; var options = convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName); return { options: options, errors: errors }; } ts.convertTypeAcquisitionFromJson = convertTypeAcquisitionFromJson; function getDefaultCompilerOptions(configFileName) { var options = ts.getBaseFileName(configFileName) === "jsconfig.json" ? { allowJs: true, maxNodeModuleJsDepth: 2, allowSyntheticDefaultImports: true, skipLibCheck: true } : {}; return options; } function convertCompilerOptionsFromJsonWorker(jsonOptions, basePath, errors, configFileName) { var options = getDefaultCompilerOptions(configFileName); convertOptionsFromJson(ts.optionDeclarations, jsonOptions, basePath, options, ts.Diagnostics.Unknown_compiler_option_0, errors); return options; } function getDefaultTypeAcquisition(configFileName) { var options = { enable: ts.getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] }; return options; } function convertTypeAcquisitionFromJsonWorker(jsonOptions, basePath, errors, configFileName) { var options = getDefaultTypeAcquisition(configFileName); var typeAcquisition = convertEnableAutoDiscoveryToEnable(jsonOptions); convertOptionsFromJson(ts.typeAcquisitionDeclarations, typeAcquisition, basePath, options, ts.Diagnostics.Unknown_type_acquisition_option_0, errors); return options; } function convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, defaultOptions, diagnosticMessage, errors) { if (!jsonOptions) { return; } var optionNameMap = commandLineOptionsToMap(optionDeclarations); for (var id in jsonOptions) { var opt = optionNameMap.get(id); if (opt) { defaultOptions[opt.name] = convertJsonOption(opt, jsonOptions[id], basePath, errors); } else { errors.push(ts.createCompilerDiagnostic(diagnosticMessage, id)); } } } function convertJsonOption(opt, value, basePath, errors) { if (isCompilerOptionsValue(opt, value)) { var optType = opt.type; if (optType === "list" && ts.isArray(value)) { return convertJsonOptionOfListType(opt, value, basePath, errors); } else if (!ts.isString(optType)) { return convertJsonOptionOfCustomType(opt, value, errors); } return normalizeNonListOptionValue(opt, basePath, value); } else { errors.push(ts.createCompilerDiagnostic(ts.Diagnostics.Compiler_option_0_requires_a_value_of_type_1, opt.name, getCompilerOptionValueTypeString(opt))); } } function normalizeOptionValue(option, basePath, value) { if (isNullOrUndefined(value)) return undefined; if (option.type === "list") { var listOption_1 = option; if (listOption_1.element.isFilePath || !ts.isString(listOption_1.element.type)) { return ts.filter(ts.map(value, function (v) { return normalizeOptionValue(listOption_1.element, basePath, v); }), function (v) { return !!v; }); } return value; } else if (!ts.isString(option.type)) { return option.type.get(ts.isString(value) ? value.toLowerCase() : value); } return normalizeNonListOptionValue(option, basePath, value); } function normalizeNonListOptionValue(option, basePath, value) { if (option.isFilePath) { value = ts.normalizePath(ts.combinePaths(basePath, value)); if (value === "") { value = "."; } } return value; } function convertJsonOptionOfCustomType(opt, value, errors) { if (isNullOrUndefined(value)) return undefined; var key = value.toLowerCase(); var val = opt.type.get(key); if (val !== undefined) { return val; } else { errors.push(createCompilerDiagnosticForInvalidCustomType(opt)); } } function convertJsonOptionOfListType(option, values, basePath, errors) { return ts.filter(ts.map(values, function (v) { return convertJsonOption(option.element, v, basePath, errors); }), function (v) { return !!v; }); } function trimString(s) { return typeof s.trim === "function" ? s.trim() : s.replace(/^[\s]+|[\s]+$/g, ""); } /** * Tests for a path that ends in a recursive directory wildcard. * Matches **, \**, **\, and \**\, but not a**b. * * NOTE: used \ in place of / above to avoid issues with multiline comments. * * Breakdown: * (^|\/) # matches either the beginning of the string or a directory separator. * \*\* # matches the recursive directory wildcard "**". * \/?$ # matches an optional trailing directory separator at the end of the string. */ var invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/; /** * Tests for a path with multiple recursive directory wildcards. * Matches **\** and **\a\**, but not **\a**b. * * NOTE: used \ in place of / above to avoid issues with multiline comments. * * Breakdown: * (^|\/) # matches either the beginning of the string or a directory separator. * \*\*\/ # matches a recursive directory wildcard "**" followed by a directory separator. * (.*\/)? # optionally matches any number of characters followed by a directory separator. * \*\* # matches a recursive directory wildcard "**" * ($|\/) # matches either the end of the string or a directory separator. */ var invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/; /** * Tests for a path where .. appears after a recursive directory wildcard. * Matches **\..\*, **\a\..\*, and **\.., but not ..\**\* * * NOTE: used \ in place of / above to avoid issues with multiline comments. * * Breakdown: * (^|\/) # matches either the beginning of the string or a directory separator. * \*\*\/ # matches a recursive directory wildcard "**" followed by a directory separator. * (.*\/)? # optionally matches any number of characters followed by a directory separator. * \.\. # matches a parent directory path component ".." * ($|\/) # matches either the end of the string or a directory separator. */ var invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/; /** * Tests for a path containing a wildcard character in a directory component of the path. * Matches \*\, \?\, and \a*b\, but not \a\ or \a\*. * * NOTE: used \ in place of / above to avoid issues with multiline comments. * * Breakdown: * \/ # matches a directory separator. * [^/]*? # matches any number of characters excluding directory separators (non-greedy). * [*?] # matches either a wildcard character (* or ?) * [^/]* # matches any number of characters excluding directory separators (greedy). * \/ # matches a directory separator. */ var watchRecursivePattern = /\/[^/]*?[*?][^/]*\//; /** * Matches the portion of a wildcard path that does not contain wildcards. * Matches \a of \a\*, or \a\b\c of \a\b\c\?\d. * * NOTE: used \ in place of / above to avoid issues with multiline comments. * * Breakdown: * ^ # matches the beginning of the string * [^*?]* # matches any number of non-wildcard characters * (?=\/[^/]*[*?]) # lookahead that matches a directory separator followed by * # a path component that contains at least one wildcard character (* or ?). */ var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/; /** * Expands an array of file specifications. * * @param filesSpecs The literal file names to include. * @param includeSpecs The wildcard file specifications to include. * @param excludeSpecs The wildcard file specifications to exclude. * @param basePath The base path for any relative file specifications. * @param options Compiler options. * @param host The host used to resolve files and directories. * @param errors An array for diagnostic reporting. */ function matchFileNames(filesSpecs, includeSpecs, excludeSpecs, basePath, options, host, errors, extraFileExtensions, jsonSourceFile) { basePath = ts.normalizePath(basePath); var validatedIncludeSpecs, validatedExcludeSpecs; // The exclude spec list is converted into a regular expression, which allows us to quickly // test whether a file or directory should be excluded before recursively traversing the // file system. if (includeSpecs) { validatedIncludeSpecs = validateSpecs(includeSpecs, errors, /*allowTrailingRecursion*/ false, jsonSourceFile, "include"); } if (excludeSpecs) { validatedExcludeSpecs = validateSpecs(excludeSpecs, errors, /*allowTrailingRecursion*/ true, jsonSourceFile, "exclude"); } // Wildcard directories (provided as part of a wildcard path) are stored in a // file map that marks whether it was a regular wildcard match (with a `*` or `?` token), // or a recursive directory. This information is used by filesystem watchers to monitor for // new entries in these paths. var wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames); var spec = { filesSpecs: filesSpecs, includeSpecs: includeSpecs, excludeSpecs: excludeSpecs, validatedIncludeSpecs: validatedIncludeSpecs, validatedExcludeSpecs: validatedExcludeSpecs, wildcardDirectories: wildcardDirectories }; return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions); } /** * Gets the file names from the provided config file specs that contain, files, include, exclude and * other properties needed to resolve the file names * @param spec The config file specs extracted with file names to include, wildcards to include/exclude and other details * @param basePath The base path for any relative file specifications. * @param options Compiler options. * @param host The host used to resolve files and directories. * @param extraFileExtensions optionaly file extra file extension information from host */ /* @internal */ function getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions) { if (extraFileExtensions === void 0) { extraFileExtensions = []; } basePath = ts.normalizePath(basePath); var keyMapper = host.useCaseSensitiveFileNames ? caseSensitiveKeyMapper : caseInsensitiveKeyMapper; // Literal file names (provided via the "files" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map later when when including // wildcard paths. var literalFileMap = ts.createMap(); // Wildcard paths (provided via the "includes" array in tsconfig.json) are stored in a // file map with a possibly case insensitive key. We use this map to store paths matched // via wildcard, and to handle extension priority. var wildcardFileMap = ts.createMap(); var filesSpecs = spec.filesSpecs, validatedIncludeSpecs = spec.validatedIncludeSpecs, validatedExcludeSpecs = spec.validatedExcludeSpecs, wildcardDirectories = spec.wildcardDirectories; // Rather than requery this for each file and filespec, we query the supported extensions // once and store it on the expansion context. var supportedExtensions = ts.getSupportedExtensions(options, extraFileExtensions); // Literal files are always included verbatim. An "include" or "exclude" specification cannot // remove a literal file. if (filesSpecs) { for (var _i = 0, filesSpecs_1 = filesSpecs; _i < filesSpecs_1.length; _i++) { var fileName = filesSpecs_1[_i]; var file = ts.getNormalizedAbsolutePath(fileName, basePath); literalFileMap.set(keyMapper(file), file); } } if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) { for (var _a = 0, _b = host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined); _a < _b.length; _a++) { var file = _b[_a]; // If we have already included a literal or wildcard path with a // higher priority extension, we should skip this file. // // This handles cases where we may encounter both .ts and // .d.ts (or .js if "allowJs" is enabled) in the same // directory when they are compilation outputs. if (hasFileWithHigherPriorityExtension(file, literalFileMap, wildcardFileMap, supportedExtensions, keyMapper)) { continue; } // We may have included a wildcard path with a lower priority // extension due to the user-defined order of entries in the // "include" array. If there is a lower priority extension in the // same directory, we should remove it. removeWildcardFilesWithLowerPriorityExtension(file, wildcardFileMap, supportedExtensions, keyMapper); var key = keyMapper(file); if (!literalFileMap.has(key) && !wildcardFileMap.has(key)) { wildcardFileMap.set(key, file); } } } var literalFiles = ts.arrayFrom(literalFileMap.values()); var wildcardFiles = ts.arrayFrom(wildcardFileMap.values()); return { fileNames: literalFiles.concat(wildcardFiles), wildcardDirectories: wildcardDirectories, spec: spec }; } ts.getFileNamesFromConfigSpecs = getFileNamesFromConfigSpecs; function validateSpecs(specs, errors, allowTrailingRecursion, jsonSourceFile, specKey) { return specs.filter(function (spec) { var diag = specToDiagnostic(spec, allowTrailingRecursion); if (diag !== undefined) { errors.push(createDiagnostic(diag, spec)); } return diag === undefined; }); function createDiagnostic(message, spec) { if (jsonSourceFile && jsonSourceFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(jsonSourceFile.jsonObject, specKey); _i < _a.length; _i++) { var property = _a[_i]; if (ts.isArrayLiteralExpression(property.initializer)) { for (var _b = 0, _c = property.initializer.elements; _b < _c.length; _b++) { var element = _c[_b]; if (ts.isStringLiteral(element) && element.text === spec) { return ts.createDiagnosticForNodeInSourceFile(jsonSourceFile, element, message, spec); } } } } } return ts.createCompilerDiagnostic(message, spec); } } function specToDiagnostic(spec, allowTrailingRecursion) { if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) { return ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; } else if (invalidMultipleRecursionPatterns.test(spec)) { return ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0; } else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) { return ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0; } } /** * Gets directories in a set of include patterns that should be watched for changes. */ function getWildcardDirectories(include, exclude, path, useCaseSensitiveFileNames) { // We watch a directory recursively if it contains a wildcard anywhere in a directory segment // of the pattern: // // /a/b/**/d - Watch /a/b recursively to catch changes to any d in any subfolder recursively // /a/b/*/d - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added // /a/b - Watch /a/b recursively to catch changes to anything in any recursive subfoler // // We watch a directory without recursion if it contains a wildcard in the file segment of // the pattern: // // /a/b/* - Watch /a/b directly to catch any new file // /a/b/a?z - Watch /a/b directly to catch any new file matching a?z var rawExcludeRegex = ts.getRegularExpressionForWildcard(exclude, path, "exclude"); var excludeRegex = rawExcludeRegex && new RegExp(rawExcludeRegex, useCaseSensitiveFileNames ? "" : "i"); var wildcardDirectories = {}; if (include !== undefined) { var recursiveKeys = []; for (var _i = 0, include_1 = include; _i < include_1.length; _i++) { var file = include_1[_i]; var spec = ts.normalizePath(ts.combinePaths(path, file)); if (excludeRegex && excludeRegex.test(spec)) { continue; } var match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames); if (match) { var key = match.key, flags = match.flags; var existingFlags = wildcardDirectories[key]; if (existingFlags === undefined || existingFlags < flags) { wildcardDirectories[key] = flags; if (flags === 1 /* Recursive */) { recursiveKeys.push(key); } } } } // Remove any subpaths under an existing recursively watched directory. for (var key in wildcardDirectories) { if (ts.hasProperty(wildcardDirectories, key)) { for (var _a = 0, recursiveKeys_1 = recursiveKeys; _a < recursiveKeys_1.length; _a++) { var recursiveKey = recursiveKeys_1[_a]; if (key !== recursiveKey && ts.containsPath(recursiveKey, key, path, !useCaseSensitiveFileNames)) { delete wildcardDirectories[key]; } } } } } return wildcardDirectories; } function getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames) { var match = wildcardDirectoryPattern.exec(spec); if (match) { return { key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(), flags: watchRecursivePattern.test(spec) ? 1 /* Recursive */ : 0 /* None */ }; } if (ts.isImplicitGlob(spec)) { return { key: spec, flags: 1 /* Recursive */ }; } return undefined; } /** * Determines whether a literal or wildcard file has already been included that has a higher * extension priority. * * @param file The path to the file. * @param extensionPriority The priority of the extension. * @param context The expansion context. */ function hasFileWithHigherPriorityExtension(file, literalFiles, wildcardFiles, extensions, keyMapper) { var extensionPriority = ts.getExtensionPriority(file, extensions); var adjustedExtensionPriority = ts.adjustExtensionPriority(extensionPriority, extensions); for (var i = 0 /* Highest */; i < adjustedExtensionPriority; i++) { var higherPriorityExtension = extensions[i]; var higherPriorityPath = keyMapper(ts.changeExtension(file, higherPriorityExtension)); if (literalFiles.has(higherPriorityPath) || wildcardFiles.has(higherPriorityPath)) { return true; } } return false; } /** * Removes files included via wildcard expansion with a lower extension priority that have * already been included. * * @param file The path to the file. * @param extensionPriority The priority of the extension. * @param context The expansion context. */ function removeWildcardFilesWithLowerPriorityExtension(file, wildcardFiles, extensions, keyMapper) { var extensionPriority = ts.getExtensionPriority(file, extensions); var nextExtensionPriority = ts.getNextLowestExtensionPriority(extensionPriority, extensions); for (var i = nextExtensionPriority; i < extensions.length; i++) { var lowerPriorityExtension = extensions[i]; var lowerPriorityPath = keyMapper(ts.changeExtension(file, lowerPriorityExtension)); wildcardFiles.delete(lowerPriorityPath); } } /** * Gets a case sensitive key. * * @param key The original key. */ function caseSensitiveKeyMapper(key) { return key; } /** * Gets a case insensitive key. * * @param key The original key. */ function caseInsensitiveKeyMapper(key) { return key.toLowerCase(); } /** * Produces a cleaned version of compiler options with personally identifiying info (aka, paths) removed. * Also converts enum values back to strings. */ /* @internal */ function convertCompilerOptionsForTelemetry(opts) { var out = {}; for (var key in opts) { if (opts.hasOwnProperty(key)) { var type = getOptionFromName(key); if (type !== undefined) { out[key] = getOptionValueWithEmptyStrings(opts[key], type); } } } return out; } ts.convertCompilerOptionsForTelemetry = convertCompilerOptionsForTelemetry; function getOptionValueWithEmptyStrings(value, option) { switch (option.type) { case "object":// "paths". Can't get any useful information from the value since we blank out strings, so just return "". return ""; case "string":// Could be any arbitrary string -- use empty string instead. return ""; case "number":// Allow numbers, but be sure to check it's actually a number. return typeof value === "number" ? value : ""; case "boolean": return typeof value === "boolean" ? value : ""; case "list": var elementType_1 = option.element; return ts.isArray(value) ? value.map(function (v) { return getOptionValueWithEmptyStrings(v, elementType_1); }) : ""; default: return ts.forEachEntry(option.type, function (optionEnumValue, optionStringValue) { if (optionEnumValue === value) { return optionStringValue; } }); } } })(ts || (ts = {})); /// /// var ts; (function (ts) { function trace(host) { host.trace(ts.formatMessage.apply(undefined, arguments)); } ts.trace = trace; /* @internal */ function isTraceEnabled(compilerOptions, host) { return compilerOptions.traceResolution && host.trace !== undefined; } ts.isTraceEnabled = isTraceEnabled; function withPackageId(packageId, r) { return r && { path: r.path, extension: r.ext, packageId: packageId }; } function noPackageId(r) { return withPackageId(/*packageId*/ undefined, r); } /** * Kinds of file that we are currently looking for. * Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript. */ var Extensions; (function (Extensions) { Extensions[Extensions["TypeScript"] = 0] = "TypeScript"; Extensions[Extensions["JavaScript"] = 1] = "JavaScript"; Extensions[Extensions["DtsOnly"] = 2] = "DtsOnly"; /** Only '.d.ts' */ })(Extensions || (Extensions = {})); /** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */ function resolvedTypeScriptOnly(resolved) { if (!resolved) { return undefined; } ts.Debug.assert(ts.extensionIsTypeScript(resolved.extension)); return { fileName: resolved.path, packageId: resolved.packageId }; } function createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations) { return { resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport: isExternalLibraryImport, packageId: resolved.packageId }, failedLookupLocations: failedLookupLocations }; } /** Reads from "main" or "types"/"typings" depending on `extensions`. */ function tryReadPackageJsonFields(readTypes, jsonContent, baseDirectory, state) { return readTypes ? tryReadFromField("typings") || tryReadFromField("types") : tryReadFromField("main"); function tryReadFromField(fieldName) { if (!ts.hasProperty(jsonContent, fieldName)) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.package_json_does_not_have_a_0_field, fieldName); } return; } var fileName = jsonContent[fieldName]; if (!ts.isString(fileName)) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Expected_type_of_0_field_in_package_json_to_be_string_got_1, fieldName, typeof fileName); } return; } var path = ts.normalizePath(ts.combinePaths(baseDirectory, fileName)); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.package_json_has_0_field_1_that_references_2, fieldName, fileName, path); } return path; } } function readJson(path, host) { try { var jsonText = host.readFile(path); return jsonText ? JSON.parse(jsonText) : {}; } catch (e) { // gracefully handle if readFile fails or returns not JSON return {}; } } function getEffectiveTypeRoots(options, host) { if (options.typeRoots) { return options.typeRoots; } var currentDirectory; if (options.configFilePath) { currentDirectory = ts.getDirectoryPath(options.configFilePath); } else if (host.getCurrentDirectory) { currentDirectory = host.getCurrentDirectory(); } if (currentDirectory !== undefined) { return getDefaultTypeRoots(currentDirectory, host); } } ts.getEffectiveTypeRoots = getEffectiveTypeRoots; /** * Returns the path to every node_modules/@types directory from some ancestor directory. * Returns undefined if there are none. */ function getDefaultTypeRoots(currentDirectory, host) { if (!host.directoryExists) { return [ts.combinePaths(currentDirectory, nodeModulesAtTypes)]; // And if it doesn't exist, tough. } var typeRoots; ts.forEachAncestorDirectory(ts.normalizePath(currentDirectory), function (directory) { var atTypes = ts.combinePaths(directory, nodeModulesAtTypes); if (host.directoryExists(atTypes)) { (typeRoots || (typeRoots = [])).push(atTypes); } return undefined; }); return typeRoots; } var nodeModulesAtTypes = ts.combinePaths("node_modules", "@types"); /** * @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown. * This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups * is assumed to be the same as root directory of the project. */ function resolveTypeReferenceDirective(typeReferenceDirectiveName, containingFile, options, host) { var traceEnabled = isTraceEnabled(options, host); var moduleResolutionState = { compilerOptions: options, host: host, traceEnabled: traceEnabled }; var typeRoots = getEffectiveTypeRoots(options, host); if (traceEnabled) { if (containingFile === undefined) { if (typeRoots === undefined) { trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_not_set, typeReferenceDirectiveName); } else { trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_not_set_root_directory_1, typeReferenceDirectiveName, typeRoots); } } else { if (typeRoots === undefined) { trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_not_set, typeReferenceDirectiveName, containingFile); } else { trace(host, ts.Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots); } } } var failedLookupLocations = []; var resolved = primaryLookup(); var primary = true; if (!resolved) { resolved = secondaryLookup(); primary = false; } var resolvedTypeReferenceDirective; if (resolved) { if (!options.preserveSymlinks) { resolved = __assign({}, resolved, { fileName: realPath(resolved.fileName, host, traceEnabled) }); } if (traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary); } resolvedTypeReferenceDirective = { primary: primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId }; } return { resolvedTypeReferenceDirective: resolvedTypeReferenceDirective, failedLookupLocations: failedLookupLocations }; function primaryLookup() { // Check primary library paths if (typeRoots && typeRoots.length) { if (traceEnabled) { trace(host, ts.Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", ")); } return ts.forEach(typeRoots, function (typeRoot) { var candidate = ts.combinePaths(typeRoot, typeReferenceDirectiveName); var candidateDirectory = ts.getDirectoryPath(candidate); var directoryExists = directoryProbablyExists(candidateDirectory, host); if (!directoryExists && traceEnabled) { trace(host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidateDirectory); } return resolvedTypeScriptOnly(loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations, !directoryExists, moduleResolutionState)); }); } else { if (traceEnabled) { trace(host, ts.Diagnostics.Root_directory_cannot_be_determined_skipping_primary_search_paths); } } } function secondaryLookup() { var resolvedFile; var initialLocationForSecondaryLookup = containingFile && ts.getDirectoryPath(containingFile); if (initialLocationForSecondaryLookup !== undefined) { // check secondary locations if (traceEnabled) { trace(host, ts.Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup); } var result = loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*cache*/ undefined); resolvedFile = resolvedTypeScriptOnly(result && result.value); if (!resolvedFile && traceEnabled) { trace(host, ts.Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName); } return resolvedFile; } else { if (traceEnabled) { trace(host, ts.Diagnostics.Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder); } } } } ts.resolveTypeReferenceDirective = resolveTypeReferenceDirective; /** * Given a set of options, returns the set of type directive names * that should be included for this program automatically. * This list could either come from the config file, * or from enumerating the types root + initial secondary types lookup location. * More type directives might appear in the program later as a result of loading actual source files; * this list is only the set of defaults that are implicitly included. */ function getAutomaticTypeDirectiveNames(options, host) { // Use explicit type list from tsconfig.json if (options.types) { return options.types; } // Walk the primary type lookup locations var result = []; if (host.directoryExists && host.getDirectories) { var typeRoots = getEffectiveTypeRoots(options, host); if (typeRoots) { for (var _i = 0, typeRoots_1 = typeRoots; _i < typeRoots_1.length; _i++) { var root = typeRoots_1[_i]; if (host.directoryExists(root)) { for (var _a = 0, _b = host.getDirectories(root); _a < _b.length; _a++) { var typeDirectivePath = _b[_a]; var normalized = ts.normalizePath(typeDirectivePath); var packageJsonPath = pathToPackageJson(ts.combinePaths(root, normalized)); // `types-publisher` sometimes creates packages with `"typings": null` for packages that don't provide their own types. // See `createNotNeededPackageJSON` in the types-publisher` repo. // tslint:disable-next-line:no-null-keyword var isNotNeededPackage = host.fileExists(packageJsonPath) && readJson(packageJsonPath, host).typings === null; if (!isNotNeededPackage) { // Return just the type directive names result.push(ts.getBaseFileName(normalized)); } } } } } } return result; } ts.getAutomaticTypeDirectiveNames = getAutomaticTypeDirectiveNames; function createModuleResolutionCache(currentDirectory, getCanonicalFileName) { var directoryToModuleNameMap = ts.createMap(); var moduleNameToDirectoryMap = ts.createMap(); return { getOrCreateCacheForDirectory: getOrCreateCacheForDirectory, getOrCreateCacheForModuleName: getOrCreateCacheForModuleName }; function getOrCreateCacheForDirectory(directoryName) { var path = ts.toPath(directoryName, currentDirectory, getCanonicalFileName); var perFolderCache = directoryToModuleNameMap.get(path); if (!perFolderCache) { perFolderCache = ts.createMap(); directoryToModuleNameMap.set(path, perFolderCache); } return perFolderCache; } function getOrCreateCacheForModuleName(nonRelativeModuleName) { if (ts.isExternalModuleNameRelative(nonRelativeModuleName)) { return undefined; } var perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName); if (!perModuleNameCache) { perModuleNameCache = createPerModuleNameCache(); moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache); } return perModuleNameCache; } function createPerModuleNameCache() { var directoryPathMap = ts.createMap(); return { get: get, set: set }; function get(directory) { return directoryPathMap.get(ts.toPath(directory, currentDirectory, getCanonicalFileName)); } /** * At first this function add entry directory -> module resolution result to the table. * Then it computes the set of parent folders for 'directory' that should have the same module resolution result * and for every parent folder in set it adds entry: parent -> module resolution. . * Lets say we first directory name: /a/b/c/d/e and resolution result is: /a/b/bar.ts. * Set of parent folders that should have the same result will be: * [ * /a/b/c/d, /a/b/c, /a/b * ] * this means that request for module resolution from file in any of these folder will be immediately found in cache. */ function set(directory, result) { var path = ts.toPath(directory, currentDirectory, getCanonicalFileName); // if entry is already in cache do nothing if (directoryPathMap.has(path)) { return; } directoryPathMap.set(path, result); var resolvedFileName = result.resolvedModule && result.resolvedModule.resolvedFileName; // find common prefix between directory and resolved file name // this common prefix should be the shorted path that has the same resolution // directory: /a/b/c/d/e // resolvedFileName: /a/b/foo.d.ts var commonPrefix = getCommonPrefix(path, resolvedFileName); var current = path; while (true) { var parent = ts.getDirectoryPath(current); if (parent === current || directoryPathMap.has(parent)) { break; } directoryPathMap.set(parent, result); current = parent; if (current === commonPrefix) { break; } } } function getCommonPrefix(directory, resolution) { if (resolution === undefined) { return undefined; } var resolutionDirectory = ts.toPath(ts.getDirectoryPath(resolution), currentDirectory, getCanonicalFileName); // find first position where directory and resolution differs var i = 0; while (i < Math.min(directory.length, resolutionDirectory.length) && directory.charCodeAt(i) === resolutionDirectory.charCodeAt(i)) { i++; } // find last directory separator before position i var sep = directory.lastIndexOf(ts.directorySeparator, i); if (sep < 0) { return undefined; } return directory.substr(0, sep); } } } ts.createModuleResolutionCache = createModuleResolutionCache; function resolveModuleName(moduleName, containingFile, compilerOptions, host, cache) { var traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { trace(host, ts.Diagnostics.Resolving_module_0_from_1, moduleName, containingFile); } var containingDirectory = ts.getDirectoryPath(containingFile); var perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory); var result = perFolderCache && perFolderCache.get(moduleName); if (result) { if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } } else { var moduleResolution = compilerOptions.moduleResolution; if (moduleResolution === undefined) { moduleResolution = ts.getEmitModuleKind(compilerOptions) === ts.ModuleKind.CommonJS ? ts.ModuleResolutionKind.NodeJs : ts.ModuleResolutionKind.Classic; if (traceEnabled) { trace(host, ts.Diagnostics.Module_resolution_kind_is_not_specified_using_0, ts.ModuleResolutionKind[moduleResolution]); } } else { if (traceEnabled) { trace(host, ts.Diagnostics.Explicitly_specified_module_resolution_kind_Colon_0, ts.ModuleResolutionKind[moduleResolution]); } } switch (moduleResolution) { case ts.ModuleResolutionKind.NodeJs: result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache); break; case ts.ModuleResolutionKind.Classic: result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache); break; default: ts.Debug.fail("Unexpected moduleResolution: " + moduleResolution); } if (perFolderCache) { perFolderCache.set(moduleName, result); // put result in per-module name cache var perModuleNameCache = cache.getOrCreateCacheForModuleName(moduleName); if (perModuleNameCache) { perModuleNameCache.set(containingDirectory, result); } } } if (traceEnabled) { if (result.resolvedModule) { trace(host, ts.Diagnostics.Module_name_0_was_successfully_resolved_to_1, moduleName, result.resolvedModule.resolvedFileName); } else { trace(host, ts.Diagnostics.Module_name_0_was_not_resolved, moduleName); } } return result; } ts.resolveModuleName = resolveModuleName; /** * Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to * mitigate differences between design time structure of the project and its runtime counterpart so the same import name * can be resolved successfully by TypeScript compiler and runtime module loader. * If these settings are set then loading procedure will try to use them to resolve module name and it can of failure it will * fallback to standard resolution routine. * * - baseUrl - this setting controls how non-relative module names are resolved. If this setting is specified then non-relative * names will be resolved relative to baseUrl: i.e. if baseUrl is '/a/b' then candidate location to resolve module name 'c/d' will * be '/a/b/c/d' * - paths - this setting can only be used when baseUrl is specified. allows to tune how non-relative module names * will be resolved based on the content of the module name. * Structure of 'paths' compiler options * 'paths': { * pattern-1: [...substitutions], * pattern-2: [...substitutions], * ... * pattern-n: [...substitutions] * } * Pattern here is a string that can contain zero or one '*' character. During module resolution module name will be matched against * all patterns in the list. Matching for patterns that don't contain '*' means that module name must be equal to pattern respecting the case. * If pattern contains '*' then to match pattern "*" module name must start with the and end with . * denotes part of the module name between and . * 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 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, * // will be looked as /a/b/c/ * * "folder1/*" // substitution will convert matched name to 'folder1/', * // since it is not rooted then final candidate location will be /a/b/c/folder1/ * ], * // match module names that start with 'components/' * "components/*": [ "/root/components/*" ] // substitution will convert /components/folder1/ to '/root/components/folder1/', * // it is rooted so it will be final candidate location * } * * 'rootDirs' allows the project to be spreaded across multiple locations and resolve modules with relative names as if * they were in the same location. For example lets say there are two files * '/local/src/content/file1.ts' * '/shared/components/contracts/src/content/protocols/file2.ts' * After bundling content of '/shared/components/contracts/src' will be merged with '/local/src' so * if file1 has the following import 'import {x} from "./protocols/file2"' it will be resolved successfully in runtime. * 'rootDirs' provides the way to tell compiler that in order to get the whole project it should behave as if content of all * root dirs were merged together. * I.e. for the example above 'rootDirs' will have two entries: [ '/local/src', '/shared/components/contracts/src' ]. * Compiler will first convert './protocols/file2' into absolute path relative to the location of containing file: * '/local/src/content/protocols/file2' and try to load it - failure. * Then it will search 'rootDirs' looking for a longest matching prefix of this absolute path and if such prefix is found - absolute path will * be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining * entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location. */ function tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) { if (!ts.isExternalModuleNameRelative(moduleName)) { return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state); } else { return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); } } function tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state) { if (!state.compilerOptions.rootDirs) { return undefined; } if (state.traceEnabled) { trace(state.host, ts.Diagnostics.rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0, moduleName); } var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); var matchedRootDir; var matchedNormalizedPrefix; for (var _i = 0, _a = state.compilerOptions.rootDirs; _i < _a.length; _i++) { var rootDir = _a[_i]; // rootDirs are expected to be absolute // in case of tsconfig.json this will happen automatically - compiler will expand relative names // using location of tsconfig.json as base location var normalizedRoot = ts.normalizePath(rootDir); if (!ts.endsWith(normalizedRoot, ts.directorySeparator)) { normalizedRoot += ts.directorySeparator; } var isLongestMatchingPrefix = ts.startsWith(candidate, normalizedRoot) && (matchedNormalizedPrefix === undefined || matchedNormalizedPrefix.length < normalizedRoot.length); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Checking_if_0_is_the_longest_matching_prefix_for_1_2, normalizedRoot, candidate, isLongestMatchingPrefix); } if (isLongestMatchingPrefix) { matchedNormalizedPrefix = normalizedRoot; matchedRootDir = rootDir; } } if (matchedNormalizedPrefix) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Longest_matching_prefix_for_0_is_1, candidate, matchedNormalizedPrefix); } var suffix = candidate.substr(matchedNormalizedPrefix.length); // first - try to load from a initial location if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate); } var resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state); if (resolvedFileName) { return resolvedFileName; } if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Trying_other_entries_in_rootDirs); } // then try to resolve using remaining entries in rootDirs for (var _b = 0, _c = state.compilerOptions.rootDirs; _b < _c.length; _b++) { var rootDir = _c[_b]; if (rootDir === matchedRootDir) { // skip the initially matched entry continue; } var candidate_1 = ts.combinePaths(ts.normalizePath(rootDir), suffix); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate_1); } var baseDirectory = ts.getDirectoryPath(candidate_1); var resolvedFileName_1 = loader(extensions, candidate_1, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state); if (resolvedFileName_1) { return resolvedFileName_1; } } if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Module_resolution_using_rootDirs_has_failed); } } return undefined; } function tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state) { if (!state.compilerOptions.baseUrl) { return undefined; } if (state.traceEnabled) { trace(state.host, ts.Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, state.compilerOptions.baseUrl, moduleName); } // string is for exact match var matchedPattern = undefined; if (state.compilerOptions.paths) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName); } matchedPattern = ts.matchPatternOrExact(ts.getOwnKeys(state.compilerOptions.paths), moduleName); } if (matchedPattern) { var matchedStar_1 = ts.isString(matchedPattern) ? undefined : ts.matchedText(matchedPattern, moduleName); var matchedPatternText = ts.isString(matchedPattern) ? matchedPattern : ts.patternText(matchedPattern); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Module_name_0_matched_pattern_1, moduleName, matchedPatternText); } return ts.forEach(state.compilerOptions.paths[matchedPatternText], function (subst) { var path = matchedStar_1 ? subst.replace("*", matchedStar_1) : subst; var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, path)); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path); } // A path mapping may have an extension, in contrast to an import, which should omit it. var extension = ts.tryGetExtensionFromPath(candidate); if (extension !== undefined) { var path_1 = tryFile(candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state); if (path_1 !== undefined) { return noPackageId({ path: path_1, ext: extension }); } } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); }); } else { var candidate = ts.normalizePath(ts.combinePaths(state.compilerOptions.baseUrl, moduleName)); if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate); } return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(ts.getDirectoryPath(candidate), state.host), state); } } function nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache) { return nodeModuleNameResolverWorker(moduleName, ts.getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false); } ts.nodeModuleNameResolver = nodeModuleNameResolver; /** * Expose resolution logic to allow us to use Node module resolution logic from arbitrary locations. * No way to do this with `require()`: https://github.com/nodejs/node/issues/5963 * Throws an error if the module can't be resolved. */ /* @internal */ function resolveJavaScriptModule(moduleName, initialDir, host) { var _a = nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ts.ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (!resolvedModule) { throw new Error("Could not resolve JS module '" + moduleName + "' starting at '" + initialDir + "'. Looked in: " + failedLookupLocations.join(", ")); } return resolvedModule.resolvedFileName; } ts.resolveJavaScriptModule = resolveJavaScriptModule; function nodeModuleNameResolverWorker(moduleName, containingDirectory, compilerOptions, host, cache, jsOnly) { var traceEnabled = isTraceEnabled(compilerOptions, host); var failedLookupLocations = []; var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; var result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript)); if (result && result.value) { var _a = result.value, resolved = _a.resolved, isExternalLibraryImport = _a.isExternalLibraryImport; return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations); } return { resolvedModule: undefined, failedLookupLocations: failedLookupLocations }; function tryResolve(extensions) { var loader = function (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { return nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true); }; var resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state); if (resolved) { return toSearchResult({ resolved: resolved, isExternalLibraryImport: false }); } if (!ts.isExternalModuleNameRelative(moduleName)) { if (traceEnabled) { trace(host, ts.Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]); } var resolved_1 = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, cache); if (!resolved_1) return undefined; var resolvedValue = resolved_1.value; if (!compilerOptions.preserveSymlinks) { resolvedValue = resolvedValue && __assign({}, resolved_1.value, { path: realPath(resolved_1.value.path, host, traceEnabled), extension: resolved_1.value.extension }); } // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files. return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } }; } else { var _a = ts.normalizePathAndParts(ts.combinePaths(containingDirectory, moduleName)), candidate = _a.path, parts = _a.parts; var resolved_2 = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state, /*considerPackageJson*/ true); // Treat explicit "node_modules" import as an external library import. return resolved_2 && toSearchResult({ resolved: resolved_2, isExternalLibraryImport: ts.contains(parts, "node_modules") }); } } } function realPath(path, host, traceEnabled) { if (!host.realpath) { return path; } var real = ts.normalizePath(host.realpath(path)); if (traceEnabled) { trace(host, ts.Diagnostics.Resolving_real_path_for_0_result_1, path, real); } return real; } function nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1, candidate, Extensions[extensions]); } if (!ts.pathEndsWithDirectorySeparator(candidate)) { if (!onlyRecordFailures) { var parentOfCandidate = ts.getDirectoryPath(candidate); if (!directoryProbablyExists(parentOfCandidate, state.host)) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, parentOfCandidate); } onlyRecordFailures = true; } } var resolvedFromFile = loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state); if (resolvedFromFile) { return noPackageId(resolvedFromFile); } } if (!onlyRecordFailures) { var candidateExists = directoryProbablyExists(candidate, state.host); if (!candidateExists) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, candidate); } onlyRecordFailures = true; } } return loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson); } /* @internal */ function directoryProbablyExists(directoryName, host) { // if host does not support 'directoryExists' assume that directory will exist return !host.directoryExists || host.directoryExists(directoryName); } ts.directoryProbablyExists = directoryProbablyExists; function loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { return noPackageId(loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state)); } /** * @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary * in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations. */ function loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state) { // First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts" var resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state); if (resolvedByAddingExtension) { return resolvedByAddingExtension; } // If that didn't work, try stripping a ".js" or ".jsx" extension and replacing it with a TypeScript one; // e.g. "./foo.js" can be matched by "./foo.ts" or "./foo.d.ts" if (ts.hasJavaScriptFileExtension(candidate)) { var extensionless = ts.removeFileExtension(candidate); if (state.traceEnabled) { var extension = candidate.substring(extensionless.length); trace(state.host, ts.Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension); } return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state); } } /** Try to return an existing file that adds one of the `extensions` to `candidate`. */ function tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state) { if (!onlyRecordFailures) { // check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing var directory = ts.getDirectoryPath(candidate); if (directory) { onlyRecordFailures = !directoryProbablyExists(directory, state.host); } } switch (extensions) { case Extensions.DtsOnly: return tryExtension(".d.ts" /* Dts */); case Extensions.TypeScript: return tryExtension(".ts" /* Ts */) || tryExtension(".tsx" /* Tsx */) || tryExtension(".d.ts" /* Dts */); case Extensions.JavaScript: return tryExtension(".js" /* Js */) || tryExtension(".jsx" /* Jsx */); } function tryExtension(ext) { var path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state); return path && { path: path, ext: ext }; } } /** Return the file if it exists. */ function tryFile(fileName, failedLookupLocations, onlyRecordFailures, state) { if (!onlyRecordFailures) { if (state.host.fileExists(fileName)) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.File_0_exist_use_it_as_a_name_resolution_result, fileName); } return fileName; } else { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.File_0_does_not_exist, fileName); } } } failedLookupLocations.push(fileName); return undefined; } function loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, considerPackageJson) { if (considerPackageJson === void 0) { considerPackageJson = true; } var _a = considerPackageJson ? getPackageJsonInfo(candidate, "", failedLookupLocations, onlyRecordFailures, state) : { packageJsonContent: undefined, packageId: undefined }, packageJsonContent = _a.packageJsonContent, packageId = _a.packageId; return withPackageId(packageId, loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent)); } function loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, packageJsonContent) { var fromPackageJson = packageJsonContent && loadModuleFromPackageJson(packageJsonContent, extensions, candidate, failedLookupLocations, state); if (fromPackageJson) { return fromPackageJson; } var directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host); return loadModuleFromFile(extensions, ts.combinePaths(candidate, "index"), failedLookupLocations, !directoryExists, state); } function getPackageJsonInfo(nodeModuleDirectory, subModuleName, failedLookupLocations, onlyRecordFailures, _a) { var host = _a.host, traceEnabled = _a.traceEnabled; var directoryExists = !onlyRecordFailures && directoryProbablyExists(nodeModuleDirectory, host); var packageJsonPath = pathToPackageJson(nodeModuleDirectory); if (directoryExists && host.fileExists(packageJsonPath)) { if (traceEnabled) { trace(host, ts.Diagnostics.Found_package_json_at_0, packageJsonPath); } var packageJsonContent = readJson(packageJsonPath, host); var packageId = typeof packageJsonContent.name === "string" && typeof packageJsonContent.version === "string" ? { name: packageJsonContent.name, subModuleName: subModuleName, version: packageJsonContent.version } : undefined; return { found: true, packageJsonContent: packageJsonContent, packageId: packageId }; } else { if (directoryExists && traceEnabled) { trace(host, ts.Diagnostics.File_0_does_not_exist, packageJsonPath); } // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results failedLookupLocations.push(packageJsonPath); return { found: false, packageJsonContent: undefined, packageId: undefined }; } } function loadModuleFromPackageJson(jsonContent, extensions, candidate, failedLookupLocations, state) { var file = tryReadPackageJsonFields(extensions !== Extensions.JavaScript, jsonContent, candidate, state); if (!file) { return undefined; } var onlyRecordFailures = !directoryProbablyExists(ts.getDirectoryPath(file), state.host); var fromFile = tryFile(file, failedLookupLocations, onlyRecordFailures, state); if (fromFile) { var resolved = fromFile && resolvedIfExtensionMatches(extensions, fromFile); if (resolved) { return resolved; } if (state.traceEnabled) { trace(state.host, ts.Diagnostics.File_0_has_an_unsupported_extension_so_skipping_it, fromFile); } } // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types" var nextExtensions = extensions === Extensions.DtsOnly ? Extensions.TypeScript : extensions; // Don't do package.json lookup recursively, because Node.js' package lookup doesn't. var result = nodeLoadModuleByRelativeName(nextExtensions, file, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ false); if (result) { // It won't have a `packageId` set, because we disabled `considerPackageJson`. ts.Debug.assert(result.packageId === undefined); return { path: result.path, ext: result.extension }; } } /** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */ function resolvedIfExtensionMatches(extensions, path) { var ext = ts.tryGetExtensionFromPath(path); return ext !== undefined && extensionIsOk(extensions, ext) ? { path: path, ext: ext } : undefined; } /** True if `extension` is one of the supported `extensions`. */ function extensionIsOk(extensions, extension) { switch (extensions) { case Extensions.JavaScript: return extension === ".js" /* Js */ || extension === ".jsx" /* Jsx */; case Extensions.TypeScript: return extension === ".ts" /* Ts */ || extension === ".tsx" /* Tsx */ || extension === ".d.ts" /* Dts */; case Extensions.DtsOnly: return extension === ".d.ts" /* Dts */; } } function pathToPackageJson(directory) { return ts.combinePaths(directory, "package.json"); } function loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state) { var candidate = ts.normalizePath(ts.combinePaths(nodeModulesFolder, moduleName)); // First look for a nested package.json, as in `node_modules/foo/bar/package.json`. var packageJsonContent; var packageId; var packageInfo = getPackageJsonInfo(candidate, "", failedLookupLocations, /*onlyRecordFailures*/ !nodeModulesFolderExists, state); if (packageInfo.found) { (packageJsonContent = packageInfo.packageJsonContent, packageId = packageInfo.packageId); } else { var _a = getPackageName(moduleName), packageName = _a.packageName, rest = _a.rest; if (rest !== "") { var packageRootPath = ts.combinePaths(nodeModulesFolder, packageName); // Don't use a "types" or "main" from here because we're not loading the root, but a subdirectory -- just here for the packageId. packageId = getPackageJsonInfo(packageRootPath, rest, failedLookupLocations, !nodeModulesFolderExists, state).packageId; } } var pathAndExtension = loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) || loadNodeModuleFromDirectoryWorker(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state, packageJsonContent); return withPackageId(packageId, pathAndExtension); } /* @internal */ function getPackageName(moduleName) { var idx = moduleName.indexOf(ts.directorySeparator); if (moduleName[0] === "@") { idx = moduleName.indexOf(ts.directorySeparator, idx + 1); } return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) }; } ts.getPackageName = getPackageName; function loadModuleFromNodeModules(extensions, moduleName, directory, failedLookupLocations, state, cache) { return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache); } function loadModuleFromNodeModulesAtTypes(moduleName, directory, failedLookupLocations, state) { // Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly. return loadModuleFromNodeModulesWorker(Extensions.DtsOnly, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ true, /*cache*/ undefined); } function loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, typesOnly, cache) { var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); return ts.forEachAncestorDirectory(ts.normalizeSlashes(directory), function (ancestorDirectory) { if (ts.getBaseFileName(ancestorDirectory) !== "node_modules") { var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state.traceEnabled, state.host); if (resolutionFromCache) { return resolutionFromCache; } return toSearchResult(loadModuleFromNodeModulesOneLevel(extensions, moduleName, ancestorDirectory, failedLookupLocations, state, typesOnly)); } }); } /** Load a module from a single node_modules directory, but not from any ancestors' node_modules directories. */ function loadModuleFromNodeModulesOneLevel(extensions, moduleName, directory, failedLookupLocations, state, typesOnly) { if (typesOnly === void 0) { typesOnly = false; } var nodeModulesFolder = ts.combinePaths(directory, "node_modules"); var nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host); if (!nodeModulesFolderExists && state.traceEnabled) { trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesFolder); } var packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, nodeModulesFolder, nodeModulesFolderExists, failedLookupLocations, state); if (packageResult) { return packageResult; } if (extensions !== Extensions.JavaScript) { var nodeModulesAtTypes_1 = ts.combinePaths(nodeModulesFolder, "@types"); var nodeModulesAtTypesExists = nodeModulesFolderExists; if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes_1, state.host)) { if (state.traceEnabled) { trace(state.host, ts.Diagnostics.Directory_0_does_not_exist_skipping_all_lookups_in_it, nodeModulesAtTypes_1); } nodeModulesAtTypesExists = false; } return loadModuleFromNodeModulesFolder(Extensions.DtsOnly, mangleScopedPackage(moduleName, state), nodeModulesAtTypes_1, nodeModulesAtTypesExists, failedLookupLocations, state); } } /** Double underscores are used in DefinitelyTyped to delimit scoped packages. */ var mangledScopedPackageSeparator = "__"; /** For a scoped package, we must look in `@types/foo__bar` instead of `@types/@foo/bar`. */ function mangleScopedPackage(packageName, state) { var mangled = getMangledNameForScopedPackage(packageName); if (state.traceEnabled && mangled !== packageName) { trace(state.host, ts.Diagnostics.Scoped_package_detected_looking_in_0, mangled); } return mangled; } /* @internal */ function getTypesPackageName(packageName) { return "@types/" + getMangledNameForScopedPackage(packageName); } ts.getTypesPackageName = getTypesPackageName; function getMangledNameForScopedPackage(packageName) { if (ts.startsWith(packageName, "@")) { var replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator); if (replaceSlash !== packageName) { return replaceSlash.slice(1); // Take off the "@" } } return packageName; } /* @internal */ function getPackageNameFromAtTypesDirectory(mangledName) { var withoutAtTypePrefix = ts.removePrefix(mangledName, "@types/"); if (withoutAtTypePrefix !== mangledName) { return ts.stringContains(withoutAtTypePrefix, mangledScopedPackageSeparator) ? "@" + withoutAtTypePrefix.replace(mangledScopedPackageSeparator, ts.directorySeparator) : withoutAtTypePrefix; } return mangledName; } ts.getPackageNameFromAtTypesDirectory = getPackageNameFromAtTypesDirectory; function tryFindNonRelativeModuleNameInCache(cache, moduleName, containingDirectory, traceEnabled, host) { var result = cache && cache.get(containingDirectory); if (result) { if (traceEnabled) { trace(host, ts.Diagnostics.Resolution_for_module_0_was_found_in_cache, moduleName); } return { value: result.resolvedModule && { path: result.resolvedModule.resolvedFileName, extension: result.resolvedModule.extension, packageId: result.resolvedModule.packageId } }; } } function classicNameResolver(moduleName, containingFile, compilerOptions, host, cache) { var traceEnabled = isTraceEnabled(compilerOptions, host); var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; var failedLookupLocations = []; var containingDirectory = ts.getDirectoryPath(containingFile); var resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript); return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations); function tryResolve(extensions) { var resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state); if (resolvedUsingSettings) { return { value: resolvedUsingSettings }; } var perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName); if (!ts.isExternalModuleNameRelative(moduleName)) { // Climb up parent directories looking for a module. var resolved_3 = ts.forEachAncestorDirectory(containingDirectory, function (directory) { var resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, traceEnabled, host); if (resolutionFromCache) { return resolutionFromCache; } var searchName = ts.normalizePath(ts.combinePaths(directory, moduleName)); return toSearchResult(loadModuleFromFileNoPackageId(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state)); }); if (resolved_3) { return resolved_3; } if (extensions === Extensions.TypeScript) { // If we didn't find the file normally, look it up in @types. return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state); } } else { var candidate = ts.normalizePath(ts.combinePaths(containingDirectory, moduleName)); return toSearchResult(loadModuleFromFileNoPackageId(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state)); } } } ts.classicNameResolver = classicNameResolver; /** * LSHost may load a module from a global cache of typings. * This is the minumum code needed to expose that functionality; the rest is in LSHost. */ /* @internal */ function loadModuleFromGlobalCache(moduleName, projectName, compilerOptions, host, globalCache) { var traceEnabled = isTraceEnabled(compilerOptions, host); if (traceEnabled) { trace(host, ts.Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache); } var state = { compilerOptions: compilerOptions, host: host, traceEnabled: traceEnabled }; var failedLookupLocations = []; var resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state); return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations); } ts.loadModuleFromGlobalCache = loadModuleFromGlobalCache; /** * Wraps value to SearchResult. * @returns undefined if value is undefined or { value } otherwise */ function toSearchResult(value) { return value !== undefined ? { value: value } : undefined; } })(ts || (ts = {})); /// /// /* @internal */ var ts; (function (ts) { var ModuleInstanceState; (function (ModuleInstanceState) { ModuleInstanceState[ModuleInstanceState["NonInstantiated"] = 0] = "NonInstantiated"; ModuleInstanceState[ModuleInstanceState["Instantiated"] = 1] = "Instantiated"; ModuleInstanceState[ModuleInstanceState["ConstEnumOnly"] = 2] = "ConstEnumOnly"; })(ModuleInstanceState = ts.ModuleInstanceState || (ts.ModuleInstanceState = {})); function getModuleInstanceState(node) { return node.body ? getModuleInstanceStateWorker(node.body) : 1 /* Instantiated */; } ts.getModuleInstanceState = getModuleInstanceState; function getModuleInstanceStateWorker(node) { // A module is uninstantiated if it contains only switch (node.kind) { // 1. interface declarations, type alias declarations case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: return 0 /* NonInstantiated */; // 2. const enum declarations case 233 /* EnumDeclaration */: if (ts.isConst(node)) { return 2 /* ConstEnumOnly */; } break; // 3. non-exported import declarations case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: if (!(ts.hasModifier(node, 1 /* Export */))) { return 0 /* NonInstantiated */; } break; // 4. other uninstantiated module declarations. case 235 /* ModuleBlock */: { var state_1 = 0 /* NonInstantiated */; ts.forEachChild(node, function (n) { var childState = getModuleInstanceStateWorker(n); switch (childState) { case 0 /* NonInstantiated */: // child is non-instantiated - continue searching return; case 2 /* ConstEnumOnly */: // child is const enum only - record state and continue searching state_1 = 2 /* ConstEnumOnly */; return; case 1 /* Instantiated */: // child is instantiated - record state and stop state_1 = 1 /* Instantiated */; return true; default: ts.Debug.assertNever(childState); } }); return state_1; } case 234 /* ModuleDeclaration */: return getModuleInstanceState(node); case 71 /* Identifier */: // Only jsdoc typedef definition can exist in jsdoc namespace, and it should // be considered the same as type alias if (node.isInJSDocNamespace) { return 0 /* NonInstantiated */; } } return 1 /* Instantiated */; } var ContainerFlags; (function (ContainerFlags) { // The current node is not a container, and no container manipulation should happen before // recursing into it. ContainerFlags[ContainerFlags["None"] = 0] = "None"; // The current node is a container. It should be set as the current container (and block- // container) before recursing into it. The current node does not have locals. Examples: // // Classes, ObjectLiterals, TypeLiterals, Interfaces... ContainerFlags[ContainerFlags["IsContainer"] = 1] = "IsContainer"; // The current node is a block-scoped-container. It should be set as the current block- // container before recursing into it. Examples: // // Blocks (when not parented by functions), Catch clauses, For/For-in/For-of statements... ContainerFlags[ContainerFlags["IsBlockScopedContainer"] = 2] = "IsBlockScopedContainer"; // The current node is the container of a control flow path. The current control flow should // be saved and restored, and a new control flow initialized within the container. ContainerFlags[ContainerFlags["IsControlFlowContainer"] = 4] = "IsControlFlowContainer"; ContainerFlags[ContainerFlags["IsFunctionLike"] = 8] = "IsFunctionLike"; ContainerFlags[ContainerFlags["IsFunctionExpression"] = 16] = "IsFunctionExpression"; ContainerFlags[ContainerFlags["HasLocals"] = 32] = "HasLocals"; ContainerFlags[ContainerFlags["IsInterface"] = 64] = "IsInterface"; ContainerFlags[ContainerFlags["IsObjectLiteralOrClassExpressionMethod"] = 128] = "IsObjectLiteralOrClassExpressionMethod"; })(ContainerFlags || (ContainerFlags = {})); var binder = createBinder(); function bindSourceFile(file, options) { ts.performance.mark("beforeBind"); binder(file, options); ts.performance.mark("afterBind"); ts.performance.measure("Bind", "beforeBind", "afterBind"); } ts.bindSourceFile = bindSourceFile; function createBinder() { var file; var options; var languageVersion; var parent; var container; var blockScopeContainer; var lastContainer; var seenThisKeyword; // state used by control flow analysis var currentFlow; var currentBreakTarget; var currentContinueTarget; var currentReturnTarget; var currentTrueTarget; var currentFalseTarget; var preSwitchCaseFlow; var activeLabels; var hasExplicitReturn; // state used for emit helpers var emitFlags; // If this file is an external module, then it is automatically in strict-mode according to // ES6. If it is not an external module, then we'll determine if it is in strict mode or // not depending on if we see "use strict" in certain places or if we hit a class/namespace // or if compiler options contain alwaysStrict. var inStrictMode; var symbolCount = 0; var Symbol; // tslint:disable-line variable-name var classifiableNames; var unreachableFlow = { flags: 1 /* Unreachable */ }; var reportedUnreachableFlow = { flags: 1 /* Unreachable */ }; // state used to aggregate transform flags during bind. var subtreeTransformFlags = 0 /* None */; var skipTransformFlagAggregation; /** * Inside the binder, we may create a diagnostic for an as-yet unbound node (with potentially no parent pointers, implying no accessible source file) * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. */ function createDiagnosticForNode(node, message, arg0, arg1, arg2) { return ts.createDiagnosticForNodeInSourceFile(ts.getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); } function bindSourceFile(f, opts) { file = f; options = opts; languageVersion = ts.getEmitScriptTarget(options); inStrictMode = bindInStrictMode(file, opts); classifiableNames = ts.createUnderscoreEscapedMap(); symbolCount = 0; skipTransformFlagAggregation = file.isDeclarationFile; Symbol = ts.objectAllocator.getSymbolConstructor(); if (!file.locals) { bind(file); file.symbolCount = symbolCount; file.classifiableNames = classifiableNames; } file = undefined; options = undefined; languageVersion = undefined; parent = undefined; container = undefined; blockScopeContainer = undefined; lastContainer = undefined; seenThisKeyword = false; currentFlow = undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; currentReturnTarget = undefined; currentTrueTarget = undefined; currentFalseTarget = undefined; activeLabels = undefined; hasExplicitReturn = false; emitFlags = 0 /* None */; subtreeTransformFlags = 0 /* None */; } return bindSourceFile; function bindInStrictMode(file, opts) { if (ts.getStrictOptionValue(opts, "alwaysStrict") && !file.isDeclarationFile) { // bind in strict mode source files with alwaysStrict option return true; } else { return !!file.externalModuleIndicator; } } function createSymbol(flags, name) { symbolCount++; return new Symbol(flags, name); } function addDeclarationToSymbol(symbol, node, symbolFlags) { symbol.flags |= symbolFlags; node.symbol = symbol; if (!symbol.declarations) { symbol.declarations = [node]; } else { symbol.declarations.push(node); } if (symbolFlags & 1952 /* HasExports */ && !symbol.exports) { symbol.exports = ts.createSymbolTable(); } if (symbolFlags & 6240 /* HasMembers */ && !symbol.members) { symbol.members = ts.createSymbolTable(); } if (symbolFlags & 107455 /* Value */) { var valueDeclaration = symbol.valueDeclaration; if (!valueDeclaration || (valueDeclaration.kind !== node.kind && valueDeclaration.kind === 234 /* ModuleDeclaration */)) { // other kinds of value declarations take precedence over modules symbol.valueDeclaration = node; } } } // Should not be called on a declaration with a computed property name, // unless it is a well known Symbol. function getDeclarationName(node) { if (node.kind === 244 /* ExportAssignment */) { return node.isExportEquals ? "export=" /* ExportEquals */ : "default" /* Default */; } var name = ts.getNameOfDeclaration(node); if (name) { if (ts.isAmbientModule(node)) { var moduleName = ts.getTextOfIdentifierOrLiteral(name); return (ts.isGlobalScopeAugmentation(node) ? "__global" : "\"" + moduleName + "\""); } if (name.kind === 145 /* ComputedPropertyName */) { var nameExpression = name.expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal if (ts.isStringOrNumericLiteral(nameExpression)) { return ts.escapeLeadingUnderscores(nameExpression.text); } ts.Debug.assert(ts.isWellKnownSymbolSyntactically(nameExpression)); return ts.getPropertyNameForKnownSymbolName(ts.idText(nameExpression.name)); } return ts.getEscapedTextOfIdentifierOrLiteral(name); } switch (node.kind) { case 153 /* Constructor */: return "__constructor" /* Constructor */; case 161 /* FunctionType */: case 156 /* CallSignature */: return "__call" /* Call */; case 162 /* ConstructorType */: case 157 /* ConstructSignature */: return "__new" /* New */; case 158 /* IndexSignature */: return "__index" /* Index */; case 245 /* ExportDeclaration */: return "__export" /* ExportStar */; case 195 /* BinaryExpression */: if (ts.getSpecialPropertyAssignmentKind(node) === 2 /* ModuleExports */) { // module.exports = ... return "export=" /* ExportEquals */; } ts.Debug.fail("Unknown binary declaration kind"); break; case 229 /* FunctionDeclaration */: case 230 /* ClassDeclaration */: return (ts.hasModifier(node, 512 /* Default */) ? "default" /* Default */ : undefined); case 277 /* JSDocFunctionType */: return (ts.isJSDocConstructSignature(node) ? "__new" /* New */ : "__call" /* Call */); case 147 /* 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 === 277 /* JSDocFunctionType */); var functionType = node.parent; var index = ts.indexOf(functionType.parameters, node); return "arg" + index; case 288 /* JSDocTypedefTag */: var name_2 = ts.getNameOfJSDocTypedef(node); return typeof name_2 !== "undefined" ? name_2.escapedText : undefined; } } function getDisplayName(node) { return node.name ? ts.declarationNameToString(node.name) : ts.unescapeLeadingUnderscores(getDeclarationName(node)); } /** * Declares a Symbol for the node and adds it to symbols. Reports errors for conflicting identifier names. * @param symbolTable - The symbol table which node will be added to. * @param parent - node's parent declaration. * @param node - The declaration to be added to the symbol table * @param includes - The SymbolFlags that node has in addition to its declaration type (eg: export, ambient, etc.) * @param excludes - The flags which node cannot be declared alongside in a symbol table. Used to report forbidden declarations. */ function declareSymbol(symbolTable, parent, node, includes, excludes, isReplaceableByMethod) { ts.Debug.assert(!ts.hasDynamicName(node)); var isDefaultExport = ts.hasModifier(node, 512 /* Default */); // The exported symbol for an export default function/class node is always named "default" var name = isDefaultExport && parent ? "default" /* Default */ : getDeclarationName(node); var symbol; if (name === undefined) { symbol = createSymbol(0 /* None */, "__missing" /* Missing */); } else { // Check and see if the symbol table already has a symbol with this name. If not, // create a new symbol with this name and add it to the table. Note that we don't // give the new symbol any flags *yet*. This ensures that it will not conflict // with the 'excludes' flags we pass in. // // If we do get an existing symbol, see if it conflicts with the new symbol we're // creating. For example, a 'var' symbol and a 'class' symbol will conflict within // the same symbol table. If we have a conflict, report the issue on each // declaration we have for this symbol, and then create a new symbol for this // declaration. // // Note that when properties declared in Javascript constructors // (marked by isReplaceableByMethod) conflict with another symbol, the property loses. // Always. This allows the common Javascript pattern of overwriting a prototype method // with an bound instance method of the same type: `this.method = this.method.bind(this)` // // If we created a new symbol, either because we didn't have a symbol with this name // in the symbol table, or we conflicted with an existing symbol, then just add this // node as the sole declaration of the new symbol. // // Otherwise, we'll be merging into a compatible existing symbol (for example when // you have multiple 'vars' with the same name in the same container). In this case // just add this node into the declarations list of the symbol. symbol = symbolTable.get(name); if (includes & 2885600 /* Classifiable */) { classifiableNames.set(name, true); } if (!symbol) { symbolTable.set(name, symbol = createSymbol(0 /* None */, name)); if (isReplaceableByMethod) symbol.isReplaceableByMethod = true; } else if (isReplaceableByMethod && !symbol.isReplaceableByMethod) { // A symbol already exists, so don't add this as a declaration. return symbol; } else if (symbol.flags & excludes) { if (symbol.isReplaceableByMethod) { // Javascript constructor-declared symbols can be discarded in favor of // prototype symbols like methods. symbolTable.set(name, symbol = createSymbol(0 /* None */, name)); } else { if (node.name) { node.name.parent = node; } // Report errors every position with duplicate declaration // Report errors on previous encountered declarations var message_1 = symbol.flags & 2 /* BlockScopedVariable */ ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0; if (symbol.declarations && symbol.declarations.length) { // If the current node is a default export of some sort, then check if // there are any other default exports that we need to error on. // We'll know whether we have other default exports depending on if `symbol` already has a declaration list set. if (isDefaultExport) { message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports; } else { // This is to properly report an error in the case "export default { }" is after export default of class declaration or function declaration. // Error on multiple export default in the following case: // 1. multiple export default of class declaration or function declaration by checking NodeFlags.Default // 2. multiple export default of export assignment. This one doesn't have NodeFlags.Default on (as export default doesn't considered as modifiers) if (symbol.declarations && symbol.declarations.length && (isDefaultExport || (node.kind === 244 /* ExportAssignment */ && !node.isExportEquals))) { message_1 = ts.Diagnostics.A_module_cannot_have_multiple_default_exports; } } } ts.forEach(symbol.declarations, function (declaration) { file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(declaration) || declaration, message_1, getDisplayName(declaration))); }); file.bindDiagnostics.push(createDiagnosticForNode(ts.getNameOfDeclaration(node) || node, message_1, getDisplayName(node))); symbol = createSymbol(0 /* None */, name); } } } addDeclarationToSymbol(symbol, node, includes); symbol.parent = parent; return symbol; } function declareModuleMember(node, symbolFlags, symbolExcludes) { var hasExportModifier = ts.getCombinedModifierFlags(node) & 1 /* Export */; if (symbolFlags & 2097152 /* Alias */) { if (node.kind === 247 /* ExportSpecifier */ || (node.kind === 238 /* ImportEqualsDeclaration */ && hasExportModifier)) { return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); } else { return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } else { // Exported module members are given 2 symbols: A local symbol that is classified with an ExportValue flag, // and an associated export symbol with all the correct flags set on it. There are 2 main reasons: // // 1. We treat locals and exports of the same name as mutually exclusive within a container. // That means the binder will issue a Duplicate Identifier error if you mix locals and exports // with the same name in the same container. // TODO: Make this a more specific error and decouple it from the exclusion logic. // 2. When we checkIdentifier in the checker, we set its resolved symbol to the local symbol, // but return the export symbol (by calling getExportSymbolOfValueSymbolIfExported). That way // when the emitter comes back to it, it knows not to qualify the name if it was found in a containing scope. // NOTE: Nested ambient modules always should go to to 'locals' table to prevent their automatic merge // during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. if (node.kind === 288 /* JSDocTypedefTag */) ts.Debug.assert(ts.isInJavaScriptFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. var isJSDocTypedefInJSDocNamespace = node.kind === 288 /* JSDocTypedefTag */ && node.name && node.name.kind === 71 /* Identifier */ && node.name.isInJSDocNamespace; if ((!ts.isAmbientModule(node) && (hasExportModifier || container.flags & 32 /* ExportContext */)) || isJSDocTypedefInJSDocNamespace) { var exportKind = symbolFlags & 107455 /* Value */ ? 1048576 /* ExportValue */ : 0; var local = declareSymbol(container.locals, /*parent*/ undefined, node, exportKind, symbolExcludes); local.exportSymbol = declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); node.localSymbol = local; return local; } else { return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } } // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. function bindContainer(node, containerFlags) { // Before we recurse into a node's children, we first save the existing parent, container // and block-container. Then after we pop out of processing the children, we restore // these saved values. var saveContainer = container; var savedBlockScopeContainer = blockScopeContainer; // Depending on what kind of node this is, we may have to adjust the current container // and block-container. If the current node is a container, then it is automatically // considered the current block-container as well. Also, for containers that we know // may contain locals, we proactively initialize the .locals field. We do this because // it's highly likely that the .locals will be needed to place some child in (for example, // a parameter, or variable declaration). // // However, we do not proactively create the .locals for block-containers because it's // totally normal and common for block-containers to never actually have a block-scoped // variable in them. We don't want to end up allocating an object for every 'block' we // run into when most of them won't be necessary. // // Finally, if this is a block-container, then we clear out any existing .locals object // it may contain within it. This happens in incremental scenarios. Because we can be // reusing a node from a previous compilation, that node may have had 'locals' created // for it. We must clear this so we don't accidentally move any stale data forward from // a previous compilation. if (containerFlags & 1 /* IsContainer */) { container = blockScopeContainer = node; if (containerFlags & 32 /* HasLocals */) { container.locals = ts.createSymbolTable(); } addToContainerChain(container); } else if (containerFlags & 2 /* IsBlockScopedContainer */) { blockScopeContainer = node; blockScopeContainer.locals = undefined; } if (containerFlags & 4 /* IsControlFlowContainer */) { var saveCurrentFlow = currentFlow; var saveBreakTarget = currentBreakTarget; var saveContinueTarget = currentContinueTarget; var saveReturnTarget = currentReturnTarget; var saveActiveLabels = activeLabels; var saveHasExplicitReturn = hasExplicitReturn; var isIIFE = containerFlags & 16 /* IsFunctionExpression */ && !ts.hasModifier(node, 256 /* Async */) && !!ts.getImmediatelyInvokedFunctionExpression(node); // A non-async IIFE is considered part of the containing control flow. Return statements behave // similarly to break statements that exit to a label just past the statement body. if (!isIIFE) { currentFlow = { flags: 2 /* Start */ }; if (containerFlags & (16 /* IsFunctionExpression */ | 128 /* IsObjectLiteralOrClassExpressionMethod */)) { currentFlow.container = node; } } // We create a return control flow graph for IIFEs and constructors. For constructors // we use the return control flow graph in strict property intialization checks. currentReturnTarget = isIIFE || node.kind === 153 /* Constructor */ ? createBranchLabel() : undefined; currentBreakTarget = undefined; currentContinueTarget = undefined; activeLabels = undefined; hasExplicitReturn = false; bindChildren(node); // Reset all reachability check related flags on node (for incremental scenarios) node.flags &= ~1408 /* ReachabilityAndEmitFlags */; if (!(currentFlow.flags & 1 /* Unreachable */) && containerFlags & 8 /* IsFunctionLike */ && ts.nodeIsPresent(node.body)) { node.flags |= 128 /* HasImplicitReturn */; if (hasExplicitReturn) node.flags |= 256 /* HasExplicitReturn */; } if (node.kind === 269 /* SourceFile */) { node.flags |= emitFlags; } if (currentReturnTarget) { addAntecedent(currentReturnTarget, currentFlow); currentFlow = finishFlowLabel(currentReturnTarget); if (node.kind === 153 /* Constructor */) { node.returnFlowNode = currentFlow; } } if (!isIIFE) { currentFlow = saveCurrentFlow; } currentBreakTarget = saveBreakTarget; currentContinueTarget = saveContinueTarget; currentReturnTarget = saveReturnTarget; activeLabels = saveActiveLabels; hasExplicitReturn = saveHasExplicitReturn; } else if (containerFlags & 64 /* IsInterface */) { seenThisKeyword = false; bindChildren(node); node.flags = seenThisKeyword ? node.flags | 64 /* ContainsThis */ : node.flags & ~64 /* ContainsThis */; } else { bindChildren(node); } container = saveContainer; blockScopeContainer = savedBlockScopeContainer; } function bindChildren(node) { if (skipTransformFlagAggregation) { bindChildrenWorker(node); } else if (node.transformFlags & 536870912 /* HasComputedFlags */) { skipTransformFlagAggregation = true; bindChildrenWorker(node); skipTransformFlagAggregation = false; subtreeTransformFlags |= node.transformFlags & ~getTransformFlagsSubtreeExclusions(node.kind); } else { var savedSubtreeTransformFlags = subtreeTransformFlags; subtreeTransformFlags = 0; bindChildrenWorker(node); subtreeTransformFlags = savedSubtreeTransformFlags | computeTransformFlagsForNode(node, subtreeTransformFlags); } } function bindEach(nodes) { if (nodes === undefined) { return; } if (skipTransformFlagAggregation) { ts.forEach(nodes, bind); } else { var savedSubtreeTransformFlags = subtreeTransformFlags; subtreeTransformFlags = 0 /* None */; var nodeArrayFlags = 0 /* None */; for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) { var node = nodes_2[_i]; bind(node); nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */; } nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */; subtreeTransformFlags |= savedSubtreeTransformFlags; } } function bindEachChild(node) { ts.forEachChild(node, bind, bindEach); } function bindChildrenWorker(node) { // Binding of JsDocComment should be done before the current block scope container changes. // because the scope of JsDocComment should not be affected by whether the current node is a // container or not. if (ts.hasJSDocNodes(node)) { if (ts.isInJavaScriptFile(node)) { for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) { var j = _a[_i]; bind(j); } } else { for (var _b = 0, _c = node.jsDoc; _b < _c.length; _b++) { var j = _c[_b]; setParentPointers(node, j); } } } if (checkUnreachable(node)) { bindEachChild(node); return; } switch (node.kind) { case 214 /* WhileStatement */: bindWhileStatement(node); break; case 213 /* DoStatement */: bindDoStatement(node); break; case 215 /* ForStatement */: bindForStatement(node); break; case 216 /* ForInStatement */: case 217 /* ForOfStatement */: bindForInOrForOfStatement(node); break; case 212 /* IfStatement */: bindIfStatement(node); break; case 220 /* ReturnStatement */: case 224 /* ThrowStatement */: bindReturnOrThrow(node); break; case 219 /* BreakStatement */: case 218 /* ContinueStatement */: bindBreakOrContinueStatement(node); break; case 225 /* TryStatement */: bindTryStatement(node); break; case 222 /* SwitchStatement */: bindSwitchStatement(node); break; case 236 /* CaseBlock */: bindCaseBlock(node); break; case 261 /* CaseClause */: bindCaseClause(node); break; case 223 /* LabeledStatement */: bindLabeledStatement(node); break; case 193 /* PrefixUnaryExpression */: bindPrefixUnaryExpressionFlow(node); break; case 194 /* PostfixUnaryExpression */: bindPostfixUnaryExpressionFlow(node); break; case 195 /* BinaryExpression */: bindBinaryExpressionFlow(node); break; case 189 /* DeleteExpression */: bindDeleteExpressionFlow(node); break; case 196 /* ConditionalExpression */: bindConditionalExpressionFlow(node); break; case 227 /* VariableDeclaration */: bindVariableDeclarationFlow(node); break; case 182 /* CallExpression */: bindCallExpressionFlow(node); break; case 279 /* JSDocComment */: bindJSDocComment(node); break; case 288 /* JSDocTypedefTag */: bindJSDocTypedefTag(node); break; default: bindEachChild(node); break; } } function isNarrowingExpression(expr) { switch (expr.kind) { case 71 /* Identifier */: case 99 /* ThisKeyword */: case 180 /* PropertyAccessExpression */: return isNarrowableReference(expr); case 182 /* CallExpression */: return hasNarrowableArgument(expr); case 186 /* ParenthesizedExpression */: return isNarrowingExpression(expr.expression); case 195 /* BinaryExpression */: return isNarrowingBinaryExpression(expr); case 193 /* PrefixUnaryExpression */: return expr.operator === 51 /* ExclamationToken */ && isNarrowingExpression(expr.operand); } return false; } function isNarrowableReference(expr) { return expr.kind === 71 /* Identifier */ || expr.kind === 99 /* ThisKeyword */ || expr.kind === 97 /* SuperKeyword */ || expr.kind === 180 /* 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 === 180 /* PropertyAccessExpression */ && isNarrowableReference(expr.expression.expression)) { return true; } return false; } function isNarrowingTypeofOperands(expr1, expr2) { return expr1.kind === 190 /* TypeOfExpression */ && isNarrowableOperand(expr1.expression) && expr2.kind === 9 /* StringLiteral */; } function isNarrowingBinaryExpression(expr) { switch (expr.operatorToken.kind) { case 58 /* EqualsToken */: return isNarrowableReference(expr.left); case 32 /* EqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: return isNarrowableOperand(expr.left) || isNarrowableOperand(expr.right) || isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right); case 93 /* InstanceOfKeyword */: return isNarrowableOperand(expr.left); case 26 /* CommaToken */: return isNarrowingExpression(expr.right); } return false; } function isNarrowableOperand(expr) { switch (expr.kind) { case 186 /* ParenthesizedExpression */: return isNarrowableOperand(expr.expression); case 195 /* BinaryExpression */: switch (expr.operatorToken.kind) { case 58 /* EqualsToken */: return isNarrowableOperand(expr.left); case 26 /* CommaToken */: return isNarrowableOperand(expr.right); } } return isNarrowableReference(expr); } function createBranchLabel() { return { flags: 4 /* BranchLabel */, antecedents: undefined }; } function createLoopLabel() { return { flags: 8 /* LoopLabel */, antecedents: undefined }; } function setFlowNodeReferenced(flow) { // On first reference we set the Referenced flag, thereafter we set the Shared flag flow.flags |= flow.flags & 512 /* Referenced */ ? 1024 /* Shared */ : 512 /* Referenced */; } function addAntecedent(label, antecedent) { if (!(antecedent.flags & 1 /* Unreachable */) && !ts.contains(label.antecedents, antecedent)) { (label.antecedents || (label.antecedents = [])).push(antecedent); setFlowNodeReferenced(antecedent); } } function createFlowCondition(flags, antecedent, expression) { if (antecedent.flags & 1 /* Unreachable */) { return antecedent; } if (!expression) { return flags & 32 /* TrueCondition */ ? antecedent : unreachableFlow; } if (expression.kind === 101 /* TrueKeyword */ && flags & 64 /* FalseCondition */ || expression.kind === 86 /* FalseKeyword */ && flags & 32 /* TrueCondition */) { return unreachableFlow; } if (!isNarrowingExpression(expression)) { return antecedent; } setFlowNodeReferenced(antecedent); return { flags: flags, expression: expression, antecedent: antecedent }; } function createFlowSwitchClause(antecedent, switchStatement, clauseStart, clauseEnd) { if (!isNarrowingExpression(switchStatement.expression)) { return antecedent; } setFlowNodeReferenced(antecedent); return { flags: 128 /* SwitchClause */, switchStatement: switchStatement, clauseStart: clauseStart, clauseEnd: clauseEnd, antecedent: antecedent }; } function createFlowAssignment(antecedent, node) { setFlowNodeReferenced(antecedent); return { flags: 16 /* Assignment */, antecedent: antecedent, node: node }; } function createFlowArrayMutation(antecedent, node) { setFlowNodeReferenced(antecedent); var res = { flags: 256 /* ArrayMutation */, antecedent: antecedent, node: node }; return res; } function finishFlowLabel(flow) { var antecedents = flow.antecedents; if (!antecedents) { return unreachableFlow; } if (antecedents.length === 1) { return antecedents[0]; } return flow; } function isStatementCondition(node) { var parent = node.parent; switch (parent.kind) { case 212 /* IfStatement */: case 214 /* WhileStatement */: case 213 /* DoStatement */: return parent.expression === node; case 215 /* ForStatement */: case 196 /* ConditionalExpression */: return parent.condition === node; } return false; } function isLogicalExpression(node) { while (true) { if (node.kind === 186 /* ParenthesizedExpression */) { node = node.expression; } else if (node.kind === 193 /* PrefixUnaryExpression */ && node.operator === 51 /* ExclamationToken */) { node = node.operand; } else { return node.kind === 195 /* BinaryExpression */ && (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */ || node.operatorToken.kind === 54 /* BarBarToken */); } } } function isTopLevelLogicalExpression(node) { while (node.parent.kind === 186 /* ParenthesizedExpression */ || node.parent.kind === 193 /* PrefixUnaryExpression */ && node.parent.operator === 51 /* ExclamationToken */) { node = node.parent; } return !isStatementCondition(node) && !isLogicalExpression(node.parent); } function bindCondition(node, trueTarget, falseTarget) { var saveTrueTarget = currentTrueTarget; var saveFalseTarget = currentFalseTarget; currentTrueTarget = trueTarget; currentFalseTarget = falseTarget; bind(node); currentTrueTarget = saveTrueTarget; currentFalseTarget = saveFalseTarget; if (!node || !isLogicalExpression(node)) { addAntecedent(trueTarget, createFlowCondition(32 /* TrueCondition */, currentFlow, node)); addAntecedent(falseTarget, createFlowCondition(64 /* FalseCondition */, currentFlow, node)); } } function bindIterativeStatement(node, breakTarget, continueTarget) { var saveBreakTarget = currentBreakTarget; var saveContinueTarget = currentContinueTarget; currentBreakTarget = breakTarget; currentContinueTarget = continueTarget; bind(node); currentBreakTarget = saveBreakTarget; currentContinueTarget = saveContinueTarget; } function bindWhileStatement(node) { var preWhileLabel = createLoopLabel(); var preBodyLabel = createBranchLabel(); var postWhileLabel = createBranchLabel(); addAntecedent(preWhileLabel, currentFlow); currentFlow = preWhileLabel; bindCondition(node.expression, preBodyLabel, postWhileLabel); currentFlow = finishFlowLabel(preBodyLabel); bindIterativeStatement(node.statement, postWhileLabel, preWhileLabel); addAntecedent(preWhileLabel, currentFlow); currentFlow = finishFlowLabel(postWhileLabel); } function bindDoStatement(node) { var preDoLabel = createLoopLabel(); var enclosingLabeledStatement = node.parent.kind === 223 /* LabeledStatement */ ? ts.lastOrUndefined(activeLabels) : undefined; // if do statement is wrapped in labeled statement then target labels for break/continue with or without // label should be the same var preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel(); var postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel(); addAntecedent(preDoLabel, currentFlow); currentFlow = preDoLabel; bindIterativeStatement(node.statement, postDoLabel, preConditionLabel); addAntecedent(preConditionLabel, currentFlow); currentFlow = finishFlowLabel(preConditionLabel); bindCondition(node.expression, preDoLabel, postDoLabel); currentFlow = finishFlowLabel(postDoLabel); } function bindForStatement(node) { var preLoopLabel = createLoopLabel(); var preBodyLabel = createBranchLabel(); var postLoopLabel = createBranchLabel(); bind(node.initializer); addAntecedent(preLoopLabel, currentFlow); currentFlow = preLoopLabel; bindCondition(node.condition, preBodyLabel, postLoopLabel); currentFlow = finishFlowLabel(preBodyLabel); bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); bind(node.incrementor); addAntecedent(preLoopLabel, currentFlow); currentFlow = finishFlowLabel(postLoopLabel); } function bindForInOrForOfStatement(node) { var preLoopLabel = createLoopLabel(); var postLoopLabel = createBranchLabel(); addAntecedent(preLoopLabel, currentFlow); currentFlow = preLoopLabel; if (node.kind === 217 /* ForOfStatement */) { bind(node.awaitModifier); } bind(node.expression); addAntecedent(postLoopLabel, currentFlow); bind(node.initializer); if (node.initializer.kind !== 228 /* 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 === 220 /* 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 === 219 /* BreakStatement */ ? breakTarget : continueTarget; if (flowLabel) { addAntecedent(flowLabel, currentFlow); currentFlow = unreachableFlow; } } function bindBreakOrContinueStatement(node) { bind(node.label); if (node.label) { var activeLabel = findActiveLabel(node.label.escapedText); if (activeLabel) { activeLabel.referenced = true; bindBreakOrContinueFlow(node, activeLabel.breakTarget, activeLabel.continueTarget); } } else { bindBreakOrContinueFlow(node, currentBreakTarget, currentContinueTarget); } } function bindTryStatement(node) { var preFinallyLabel = createBranchLabel(); var preTryFlow = currentFlow; // TODO: Every statement in try block is potentially an exit point! bind(node.tryBlock); addAntecedent(preFinallyLabel, currentFlow); var flowAfterTry = currentFlow; var flowAfterCatch = unreachableFlow; if (node.catchClause) { currentFlow = preTryFlow; bind(node.catchClause); addAntecedent(preFinallyLabel, currentFlow); flowAfterCatch = currentFlow; } if (node.finallyBlock) { // in finally flow is combined from pre-try/flow from try/flow from catch // pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable // also for finally blocks we inject two extra edges into the flow graph. // first -> edge that connects pre-try flow with the label at the beginning of the finally block, it has lock associated with it // second -> edge that represents post-finally flow. // these edges are used in following scenario: // let a; (1) // try { a = someOperation(); (2)} // finally { (3) console.log(a) } (4) // (5) a // flow graph for this case looks roughly like this (arrows show ): // (1-pre-try-flow) <--.. <-- (2-post-try-flow) // ^ ^ // |*****(3-pre-finally-label) -----| // ^ // |-- ... <-- (4-post-finally-label) <--- (5) // In case when we walk the flow starting from inside the finally block we want to take edge '*****' into account // since it ensures that finally is always reachable. However when we start outside the finally block and go through label (5) // then edge '*****' should be discarded because label 4 is only reachable if post-finally label-4 is reachable // Simply speaking code inside finally block is treated as reachable as pre-try-flow // since we conservatively assume that any line in try block can throw or return in which case we'll enter finally. // However code after finally is reachable only if control flow was not abrupted in try/catch or finally blocks - it should be composed from // final flows of these blocks without taking pre-try flow into account. // // extra edges that we inject allows to control this behavior // if when walking the flow we step on post-finally edge - we can mark matching pre-finally edge as locked so it will be skipped. var preFinallyFlow = { flags: 2048 /* PreFinally */, antecedent: preTryFlow, lock: {} }; addAntecedent(preFinallyLabel, preFinallyFlow); currentFlow = finishFlowLabel(preFinallyLabel); bind(node.finallyBlock); // if flow after finally is unreachable - keep it // otherwise check if flows after try and after catch are unreachable // if yes - convert current flow to unreachable // i.e. // try { return "1" } finally { console.log(1); } // console.log(2); // this line should be unreachable even if flow falls out of finally block if (!(currentFlow.flags & 1 /* Unreachable */)) { if ((flowAfterTry.flags & 1 /* Unreachable */) && (flowAfterCatch.flags & 1 /* Unreachable */)) { currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow ? reportedUnreachableFlow : unreachableFlow; } } if (!(currentFlow.flags & 1 /* Unreachable */)) { var afterFinallyFlow = { flags: 4096 /* AfterFinally */, antecedent: currentFlow }; preFinallyFlow.lock = afterFinallyFlow; currentFlow = afterFinallyFlow; } } else { currentFlow = finishFlowLabel(preFinallyLabel); } } function bindSwitchStatement(node) { var postSwitchLabel = createBranchLabel(); bind(node.expression); var saveBreakTarget = currentBreakTarget; var savePreSwitchCaseFlow = preSwitchCaseFlow; currentBreakTarget = postSwitchLabel; preSwitchCaseFlow = currentFlow; bind(node.caseBlock); addAntecedent(postSwitchLabel, currentFlow); var hasDefault = ts.forEach(node.caseBlock.clauses, function (c) { return c.kind === 262 /* DefaultClause */; }); // We mark a switch statement as possibly exhaustive if it has no default clause and if all // case clauses have unreachable end points (e.g. they all return). node.possiblyExhaustive = !hasDefault && !postSwitchLabel.antecedents; if (!hasDefault) { addAntecedent(postSwitchLabel, createFlowSwitchClause(preSwitchCaseFlow, node, 0, 0)); } currentBreakTarget = saveBreakTarget; preSwitchCaseFlow = savePreSwitchCaseFlow; currentFlow = finishFlowLabel(postSwitchLabel); } function bindCaseBlock(node) { var savedSubtreeTransformFlags = subtreeTransformFlags; subtreeTransformFlags = 0; var clauses = node.clauses; var fallthroughFlow = unreachableFlow; for (var i = 0; i < clauses.length; i++) { var clauseStart = i; while (!clauses[i].statements.length && i + 1 < clauses.length) { bind(clauses[i]); i++; } var preCaseLabel = createBranchLabel(); addAntecedent(preCaseLabel, createFlowSwitchClause(preSwitchCaseFlow, node.parent, clauseStart, i + 1)); addAntecedent(preCaseLabel, fallthroughFlow); currentFlow = finishFlowLabel(preCaseLabel); var clause = clauses[i]; bind(clause); fallthroughFlow = currentFlow; if (!(currentFlow.flags & 1 /* Unreachable */) && i !== clauses.length - 1 && options.noFallthroughCasesInSwitch) { errorOnFirstToken(clause, ts.Diagnostics.Fallthrough_case_in_switch); } } clauses.transformFlags = subtreeTransformFlags | 536870912 /* HasComputedFlags */; subtreeTransformFlags |= savedSubtreeTransformFlags; } function bindCaseClause(node) { var saveCurrentFlow = currentFlow; currentFlow = preSwitchCaseFlow; bind(node.expression); currentFlow = saveCurrentFlow; bindEach(node.statements); } function pushActiveLabel(name, breakTarget, continueTarget) { var activeLabel = { name: name, breakTarget: breakTarget, continueTarget: continueTarget, referenced: false }; (activeLabels || (activeLabels = [])).push(activeLabel); return activeLabel; } function popActiveLabel() { activeLabels.pop(); } function bindLabeledStatement(node) { var preStatementLabel = createLoopLabel(); var postStatementLabel = createBranchLabel(); bind(node.label); addAntecedent(preStatementLabel, currentFlow); var activeLabel = pushActiveLabel(node.label.escapedText, postStatementLabel, preStatementLabel); bind(node.statement); popActiveLabel(); if (!activeLabel.referenced && !options.allowUnusedLabels) { file.bindDiagnostics.push(createDiagnosticForNode(node.label, ts.Diagnostics.Unused_label)); } if (!node.statement || node.statement.kind !== 213 /* DoStatement */) { // do statement sets current flow inside bindDoStatement addAntecedent(postStatementLabel, currentFlow); currentFlow = finishFlowLabel(postStatementLabel); } } function bindDestructuringTargetFlow(node) { if (node.kind === 195 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */) { bindAssignmentTargetFlow(node.left); } else { bindAssignmentTargetFlow(node); } } function bindAssignmentTargetFlow(node) { if (isNarrowableReference(node)) { currentFlow = createFlowAssignment(currentFlow, node); } else if (node.kind === 178 /* ArrayLiteralExpression */) { for (var _i = 0, _a = node.elements; _i < _a.length; _i++) { var e = _a[_i]; if (e.kind === 199 /* SpreadElement */) { bindAssignmentTargetFlow(e.expression); } else { bindDestructuringTargetFlow(e); } } } else if (node.kind === 179 /* ObjectLiteralExpression */) { for (var _b = 0, _c = node.properties; _b < _c.length; _b++) { var p = _c[_b]; if (p.kind === 265 /* PropertyAssignment */) { bindDestructuringTargetFlow(p.initializer); } else if (p.kind === 266 /* ShorthandPropertyAssignment */) { bindAssignmentTargetFlow(p.name); } else if (p.kind === 267 /* SpreadAssignment */) { bindAssignmentTargetFlow(p.expression); } } } } function bindLogicalExpression(node, trueTarget, falseTarget) { var preRightLabel = createBranchLabel(); if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) { bindCondition(node.left, preRightLabel, falseTarget); } else { bindCondition(node.left, trueTarget, preRightLabel); } currentFlow = finishFlowLabel(preRightLabel); bind(node.operatorToken); bindCondition(node.right, trueTarget, falseTarget); } function bindPrefixUnaryExpressionFlow(node) { if (node.operator === 51 /* ExclamationToken */) { var saveTrueTarget = currentTrueTarget; currentTrueTarget = currentFalseTarget; currentFalseTarget = saveTrueTarget; bindEachChild(node); currentFalseTarget = currentTrueTarget; currentTrueTarget = saveTrueTarget; } else { bindEachChild(node); if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) { bindAssignmentTargetFlow(node.operand); } } } function bindPostfixUnaryExpressionFlow(node) { bindEachChild(node); if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) { bindAssignmentTargetFlow(node.operand); } } function bindBinaryExpressionFlow(node) { var operator = node.operatorToken.kind; if (operator === 53 /* AmpersandAmpersandToken */ || operator === 54 /* BarBarToken */) { if (isTopLevelLogicalExpression(node)) { var postExpressionLabel = createBranchLabel(); bindLogicalExpression(node, postExpressionLabel, postExpressionLabel); currentFlow = finishFlowLabel(postExpressionLabel); } else { bindLogicalExpression(node, currentTrueTarget, currentFalseTarget); } } else { bindEachChild(node); if (ts.isAssignmentOperator(operator) && !ts.isAssignmentTarget(node)) { bindAssignmentTargetFlow(node.left); if (operator === 58 /* EqualsToken */ && node.left.kind === 181 /* ElementAccessExpression */) { var elementAccess = node.left; if (isNarrowableOperand(elementAccess.expression)) { currentFlow = createFlowArrayMutation(currentFlow, node); } } } } } function bindDeleteExpressionFlow(node) { bindEachChild(node); if (node.expression.kind === 180 /* PropertyAccessExpression */) { bindAssignmentTargetFlow(node.expression); } } function bindConditionalExpressionFlow(node) { var trueLabel = createBranchLabel(); var falseLabel = createBranchLabel(); var postExpressionLabel = createBranchLabel(); bindCondition(node.condition, trueLabel, falseLabel); currentFlow = finishFlowLabel(trueLabel); bind(node.questionToken); bind(node.whenTrue); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(falseLabel); bind(node.colonToken); bind(node.whenFalse); addAntecedent(postExpressionLabel, currentFlow); currentFlow = finishFlowLabel(postExpressionLabel); } function bindInitializedVariableFlow(node) { var name = !ts.isOmittedExpression(node) ? node.name : undefined; if (ts.isBindingPattern(name)) { for (var _i = 0, _a = name.elements; _i < _a.length; _i++) { var child = _a[_i]; bindInitializedVariableFlow(child); } } else { currentFlow = createFlowAssignment(currentFlow, node); } } function bindVariableDeclarationFlow(node) { bindEachChild(node); if (node.initializer || ts.isForInOrOfStatement(node.parent.parent)) { bindInitializedVariableFlow(node); } } function bindJSDocComment(node) { ts.forEachChild(node, function (n) { if (n.kind !== 288 /* JSDocTypedefTag */) { bind(n); } }); } function bindJSDocTypedefTag(node) { ts.forEachChild(node, function (n) { // if the node has a fullName "A.B.C", that means symbol "C" was already bound // when we visit "fullName"; so when we visit the name "C" as the next child of // the jsDocTypedefTag, we should skip binding it. if (node.fullName && n === node.name && node.fullName.kind !== 71 /* Identifier */) { return; } bind(n); }); } function bindCallExpressionFlow(node) { // If the target of the call expression is a function expression or arrow function we have // an immediately invoked function expression (IIFE). Initialize the flowNode property to // the current control flow (which includes evaluation of the IIFE arguments). var expr = node.expression; while (expr.kind === 186 /* ParenthesizedExpression */) { expr = expr.expression; } if (expr.kind === 187 /* FunctionExpression */ || expr.kind === 188 /* ArrowFunction */) { bindEach(node.typeArguments); bindEach(node.arguments); bind(node.expression); } else { bindEachChild(node); } if (node.expression.kind === 180 /* PropertyAccessExpression */) { var propertyAccess = node.expression; if (isNarrowableOperand(propertyAccess.expression) && ts.isPushOrUnshiftIdentifier(propertyAccess.name)) { currentFlow = createFlowArrayMutation(currentFlow, node); } } } function getContainerFlags(node) { switch (node.kind) { case 200 /* ClassExpression */: case 230 /* ClassDeclaration */: case 233 /* EnumDeclaration */: case 179 /* ObjectLiteralExpression */: case 164 /* TypeLiteral */: case 280 /* JSDocTypeLiteral */: case 258 /* JsxAttributes */: return 1 /* IsContainer */; case 231 /* InterfaceDeclaration */: return 1 /* IsContainer */ | 64 /* IsInterface */; case 234 /* ModuleDeclaration */: case 232 /* TypeAliasDeclaration */: case 173 /* MappedType */: return 1 /* IsContainer */ | 32 /* HasLocals */; case 269 /* SourceFile */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */; case 152 /* MethodDeclaration */: if (ts.isObjectLiteralOrClassExpressionMethod(node)) { return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 128 /* IsObjectLiteralOrClassExpressionMethod */; } // falls through case 153 /* Constructor */: case 229 /* FunctionDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 156 /* CallSignature */: case 277 /* JSDocFunctionType */: case 161 /* FunctionType */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 162 /* ConstructorType */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */; case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return 1 /* IsContainer */ | 4 /* IsControlFlowContainer */ | 32 /* HasLocals */ | 8 /* IsFunctionLike */ | 16 /* IsFunctionExpression */; case 235 /* ModuleBlock */: return 4 /* IsControlFlowContainer */; case 150 /* PropertyDeclaration */: return node.initializer ? 4 /* IsControlFlowContainer */ : 0; case 264 /* CatchClause */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 236 /* CaseBlock */: return 2 /* IsBlockScopedContainer */; case 208 /* Block */: // do not treat blocks directly inside a function as a block-scoped-container. // Locals that reside in this block should go to the function locals. Otherwise 'x' // would not appear to be a redeclaration of a block scoped local in the following // example: // // function foo() { // var x; // let x; // } // // If we placed 'var x' into the function locals and 'let x' into the locals of // the block, then there would be no collision. // // By not creating a new block-scoped-container here, we ensure that both 'var x' // and 'let x' go into the Function-container's locals, and we do get a collision // conflict. return ts.isFunctionLike(node.parent) ? 0 /* None */ : 2 /* IsBlockScopedContainer */; } return 0 /* None */; } function addToContainerChain(next) { if (lastContainer) { lastContainer.nextContainer = next; } lastContainer = next; } function declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes) { switch (container.kind) { // Modules, source files, and classes need specialized handling for how their // members are declared (for example, a member of a class will go into a specific // symbol table depending on if it is static or not). We defer to specialized // handlers to take care of declaring these child members. case 234 /* ModuleDeclaration */: return declareModuleMember(node, symbolFlags, symbolExcludes); case 269 /* SourceFile */: return declareSourceFileMember(node, symbolFlags, symbolExcludes); case 200 /* ClassExpression */: case 230 /* ClassDeclaration */: return declareClassMember(node, symbolFlags, symbolExcludes); case 233 /* EnumDeclaration */: return declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes); case 164 /* TypeLiteral */: case 280 /* JSDocTypeLiteral */: case 179 /* ObjectLiteralExpression */: case 231 /* InterfaceDeclaration */: case 258 /* JsxAttributes */: // Interface/Object-types always have their children added to the 'members' of // their container. They are only accessible through an instance of their // container, and are never in scope otherwise (even inside the body of the // object / type / interface declaring them). An exception is type parameters, // which are in scope without qualification (similar to 'locals'). return declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); case 161 /* FunctionType */: case 162 /* ConstructorType */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 277 /* JSDocFunctionType */: case 232 /* TypeAliasDeclaration */: case 173 /* MappedType */: // All the children of these container types are never visible through another // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, // they're only accessed 'lexically' (i.e. from code that exists underneath // their container in the tree). To accomplish this, we simply add their declared // symbol to the 'locals' of the container. These symbols can then be found as // the type checker walks up the containers, checking them for matching names. return declareSymbol(container.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } function declareClassMember(node, symbolFlags, symbolExcludes) { return ts.hasModifier(node, 32 /* Static */) ? declareSymbol(container.symbol.exports, container.symbol, node, symbolFlags, symbolExcludes) : declareSymbol(container.symbol.members, container.symbol, node, symbolFlags, symbolExcludes); } function declareSourceFileMember(node, symbolFlags, symbolExcludes) { return ts.isExternalModule(file) ? declareModuleMember(node, symbolFlags, symbolExcludes) : declareSymbol(file.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } function hasExportDeclarations(node) { var body = node.kind === 269 /* SourceFile */ ? node : node.body; if (body && (body.kind === 269 /* SourceFile */ || body.kind === 235 /* ModuleBlock */)) { for (var _i = 0, _a = body.statements; _i < _a.length; _i++) { var stat = _a[_i]; if (stat.kind === 245 /* ExportDeclaration */ || stat.kind === 244 /* 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 (node.flags & 2097152 /* Ambient */ && !hasExportDeclarations(node)) { node.flags |= 32 /* ExportContext */; } else { node.flags &= ~32 /* ExportContext */; } } function bindModuleDeclaration(node) { setExportContextFlag(node); if (ts.isAmbientModule(node)) { if (ts.hasModifier(node, 1 /* Export */)) { errorOnFirstToken(node, ts.Diagnostics.export_modifier_cannot_be_applied_to_ambient_modules_and_module_augmentations_since_they_are_always_visible); } if (ts.isExternalModuleAugmentation(node)) { declareModuleSymbol(node); } else { var pattern = void 0; if (node.name.kind === 9 /* StringLiteral */) { var text = node.name.text; if (ts.hasZeroOrOneAsteriskCharacter(text)) { pattern = ts.tryParsePattern(text); } else { errorOnFirstToken(node.name, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, text); } } var symbol = declareSymbolAndAddToSymbolTable(node, 512 /* ValueModule */, 106639 /* ValueModuleExcludes */); if (pattern) { (file.patternAmbientModules || (file.patternAmbientModules = [])).push({ pattern: pattern, symbol: symbol }); } } } else { var state = declareModuleSymbol(node); if (state !== 0 /* NonInstantiated */) { var symbol = node.symbol; // if module was already merged with some function, class or non-const enum, treat it as non-const-enum-only symbol.constEnumOnlyModule = (!(symbol.flags & (16 /* Function */ | 32 /* Class */ | 256 /* RegularEnum */))) // Current must be `const enum` only && state === 2 /* ConstEnumOnly */ // Can't have been set to 'false' in a previous merged symbol. ('undefined' OK) && symbol.constEnumOnlyModule !== false; } } } function declareModuleSymbol(node) { var state = getModuleInstanceState(node); var instantiated = state !== 0 /* NonInstantiated */; declareSymbolAndAddToSymbolTable(node, instantiated ? 512 /* ValueModule */ : 1024 /* NamespaceModule */, instantiated ? 106639 /* ValueModuleExcludes */ : 0 /* NamespaceModuleExcludes */); return state; } function bindFunctionOrConstructorType(node) { // For a given function symbol "<...>(...) => T" we want to generate a symbol identical // to the one we would get for: { <...>(...): T } // // We do that by making an anonymous type literal symbol, and then setting the function // symbol as its sole member. To the rest of the system, this symbol will be indistinguishable // from an actual type literal symbol you would have gotten had you used the long form. var symbol = createSymbol(131072 /* Signature */, getDeclarationName(node)); addDeclarationToSymbol(symbol, node, 131072 /* Signature */); var typeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */); addDeclarationToSymbol(typeLiteralSymbol, node, 2048 /* TypeLiteral */); typeLiteralSymbol.members = ts.createSymbolTable(); typeLiteralSymbol.members.set(symbol.escapedName, symbol); } function bindObjectLiteralExpression(node) { var ElementKind; (function (ElementKind) { ElementKind[ElementKind["Property"] = 1] = "Property"; ElementKind[ElementKind["Accessor"] = 2] = "Accessor"; })(ElementKind || (ElementKind = {})); if (inStrictMode) { var seen = ts.createUnderscoreEscapedMap(); for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; if (prop.kind === 267 /* SpreadAssignment */ || prop.name.kind !== 71 /* Identifier */) { continue; } var identifier = prop.name; // ECMA-262 11.1.5 Object Initializer // If previous is not undefined then throw a SyntaxError exception if any of the following conditions are true // a.This production is contained in strict code and IsDataDescriptor(previous) is true and // IsDataDescriptor(propId.descriptor) is true. // b.IsDataDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true. // c.IsAccessorDescriptor(previous) is true and IsDataDescriptor(propId.descriptor) is true. // d.IsAccessorDescriptor(previous) is true and IsAccessorDescriptor(propId.descriptor) is true // and either both previous and propId.descriptor have[[Get]] fields or both previous and propId.descriptor have[[Set]] fields var currentKind = prop.kind === 265 /* PropertyAssignment */ || prop.kind === 266 /* ShorthandPropertyAssignment */ || prop.kind === 152 /* MethodDeclaration */ ? 1 /* Property */ : 2 /* Accessor */; var existingKind = seen.get(identifier.escapedText); if (!existingKind) { seen.set(identifier.escapedText, currentKind); continue; } if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) { var span_1 = ts.getErrorSpanForNode(file, identifier); file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_1.start, span_1.length, ts.Diagnostics.An_object_literal_cannot_have_multiple_properties_with_the_same_name_in_strict_mode)); } } } return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__object" /* Object */); } function bindJsxAttributes(node) { return bindAnonymousDeclaration(node, 4096 /* ObjectLiteral */, "__jsxAttributes" /* JSXAttributes */); } function bindJsxAttribute(node, symbolFlags, symbolExcludes) { return declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } function bindAnonymousDeclaration(node, symbolFlags, name) { var symbol = createSymbol(symbolFlags, name); if (symbolFlags & (8 /* EnumMember */ | 106500 /* ClassMember */)) { symbol.parent = container.symbol; } addDeclarationToSymbol(symbol, node, symbolFlags); } function bindBlockScopedDeclaration(node, symbolFlags, symbolExcludes) { switch (blockScopeContainer.kind) { case 234 /* ModuleDeclaration */: declareModuleMember(node, symbolFlags, symbolExcludes); break; case 269 /* SourceFile */: if (ts.isExternalModule(container)) { declareModuleMember(node, symbolFlags, symbolExcludes); break; } // falls through default: if (!blockScopeContainer.locals) { blockScopeContainer.locals = ts.createSymbolTable(); addToContainerChain(blockScopeContainer); } declareSymbol(blockScopeContainer.locals, /*parent*/ undefined, node, symbolFlags, symbolExcludes); } } function bindBlockScopedVariableDeclaration(node) { bindBlockScopedDeclaration(node, 2 /* BlockScopedVariable */, 107455 /* BlockScopedVariableExcludes */); } // The binder visits every node in the syntax tree so it is a convenient place to perform a single localized // check for reserved words used as identifiers in strict mode code. function checkStrictModeIdentifier(node) { if (inStrictMode && node.originalKeywordKind >= 108 /* FirstFutureReservedWord */ && node.originalKeywordKind <= 116 /* LastFutureReservedWord */ && !ts.isIdentifierName(node) && !(node.flags & 2097152 /* Ambient */)) { // Report error only if there are no parse errors in file if (!file.parseDiagnostics.length) { file.bindDiagnostics.push(createDiagnosticForNode(node, getStrictModeIdentifierMessage(node), ts.declarationNameToString(node))); } } } function getStrictModeIdentifierMessage(node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. if (ts.getContainingClass(node)) { return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode; } if (file.externalModuleIndicator) { return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode_Modules_are_automatically_in_strict_mode; } return ts.Diagnostics.Identifier_expected_0_is_a_reserved_word_in_strict_mode; } function checkStrictModeBinaryExpression(node) { if (inStrictMode && ts.isLeftHandSideExpression(node.left) && ts.isAssignmentOperator(node.operatorToken.kind)) { // ECMA 262 (Annex C) The identifier eval or arguments may not appear as the LeftHandSideExpression of an // Assignment operator(11.13) or of a PostfixExpression(11.3) checkStrictModeEvalOrArguments(node, node.left); } } function checkStrictModeCatchClause(node) { // It is a SyntaxError if a TryStatement with a Catch occurs within strict code and the Identifier of the // Catch production is eval or arguments if (inStrictMode && node.variableDeclaration) { checkStrictModeEvalOrArguments(node, node.variableDeclaration.name); } } function checkStrictModeDeleteExpression(node) { // Grammar checking if (inStrictMode && node.expression.kind === 71 /* Identifier */) { // When a delete operator occurs within strict mode code, a SyntaxError is thrown if its // UnaryExpression is a direct reference to a variable, function argument, or function name var span_2 = ts.getErrorSpanForNode(file, node.expression); file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_2.start, span_2.length, ts.Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode)); } } function isEvalOrArgumentsIdentifier(node) { return ts.isIdentifier(node) && (node.escapedText === "eval" || node.escapedText === "arguments"); } function checkStrictModeEvalOrArguments(contextNode, name) { if (name && name.kind === 71 /* Identifier */) { var identifier = name; if (isEvalOrArgumentsIdentifier(identifier)) { // We check first if the name is inside class declaration or class expression; if so give explicit message // otherwise report generic error message. var span_3 = ts.getErrorSpanForNode(file, name); file.bindDiagnostics.push(ts.createFileDiagnostic(file, span_3.start, span_3.length, getStrictModeEvalOrArgumentsMessage(contextNode), ts.idText(identifier))); } } } function getStrictModeEvalOrArgumentsMessage(node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. if (ts.getContainingClass(node)) { return ts.Diagnostics.Invalid_use_of_0_Class_definitions_are_automatically_in_strict_mode; } if (file.externalModuleIndicator) { return ts.Diagnostics.Invalid_use_of_0_Modules_are_automatically_in_strict_mode; } return ts.Diagnostics.Invalid_use_of_0_in_strict_mode; } function checkStrictModeFunctionName(node) { if (inStrictMode) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a strict mode FunctionDeclaration or FunctionExpression (13.1)) checkStrictModeEvalOrArguments(node, node.name); } } function getStrictModeBlockScopeFunctionDeclarationMessage(node) { // Provide specialized messages to help the user understand why we think they're in // strict mode. if (ts.getContainingClass(node)) { return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Class_definitions_are_automatically_in_strict_mode; } if (file.externalModuleIndicator) { return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5_Modules_are_automatically_in_strict_mode; } return ts.Diagnostics.Function_declarations_are_not_allowed_inside_blocks_in_strict_mode_when_targeting_ES3_or_ES5; } function checkStrictModeFunctionDeclaration(node) { if (languageVersion < 2 /* ES2015 */) { // Report error if function is not top level function declaration if (blockScopeContainer.kind !== 269 /* SourceFile */ && blockScopeContainer.kind !== 234 /* ModuleDeclaration */ && !ts.isFunctionLike(blockScopeContainer)) { // We check first if the name is inside class declaration or class expression; if so give explicit message // otherwise report generic error message. var errorSpan = ts.getErrorSpanForNode(file, node); file.bindDiagnostics.push(ts.createFileDiagnostic(file, errorSpan.start, errorSpan.length, getStrictModeBlockScopeFunctionDeclarationMessage(node))); } } } function checkStrictModeNumericLiteral(node) { if (inStrictMode && node.numericLiteralFlags & 32 /* Octal */) { file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Octal_literals_are_not_allowed_in_strict_mode)); } } function checkStrictModePostfixUnaryExpression(node) { // Grammar checking // The identifier eval or arguments may not appear as the LeftHandSideExpression of an // Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression // operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator. if (inStrictMode) { checkStrictModeEvalOrArguments(node, node.operand); } } function checkStrictModePrefixUnaryExpression(node) { // Grammar checking if (inStrictMode) { if (node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) { checkStrictModeEvalOrArguments(node, node.operand); } } } function checkStrictModeWithStatement(node) { // Grammar checking for withStatement if (inStrictMode) { errorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_strict_mode); } } function errorOnFirstToken(node, message, arg0, arg1, arg2) { var span = ts.getSpanOfTokenAtPosition(file, node.pos); file.bindDiagnostics.push(ts.createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); } function bind(node) { if (!node) { return; } node.parent = parent; var saveInStrictMode = inStrictMode; // Even though in the AST the jsdoc @typedef node belongs to the current node, // its symbol might be in the same scope with the current node's symbol. Consider: // // /** @typedef {string | number} MyType */ // function foo(); // // Here the current node is "foo", which is a container, but the scope of "MyType" should // not be inside "foo". Therefore we always bind @typedef before bind the parent node, // and skip binding this tag later when binding all the other jsdoc tags. if (ts.isInJavaScriptFile(node)) bindJSDocTypedefTagIfAny(node); // First we bind declaration nodes to a symbol if possible. We'll both create a symbol // and then potentially add the symbol to an appropriate symbol table. Possible // destination symbol tables are: // // 1) The 'exports' table of the current container's symbol. // 2) The 'members' table of the current container's symbol. // 3) The 'locals' table of the current container. // // However, not all symbols will end up in any of these tables. 'Anonymous' symbols // (like TypeLiterals for example) will not be put in any table. bindWorker(node); // Then we recurse into the children of the node to bind them as well. For certain // symbols we do specialized work when we recurse. For example, we'll keep track of // the current 'container' node when it changes. This helps us know which symbol table // a local should go into for example. Since terminal nodes are known not to have // children, as an optimization we don't process those. if (node.kind > 143 /* LastToken */) { var saveParent = parent; parent = node; var containerFlags = getContainerFlags(node); if (containerFlags === 0 /* None */) { bindChildren(node); } else { bindContainer(node, containerFlags); } parent = saveParent; } else if (!skipTransformFlagAggregation && (node.transformFlags & 536870912 /* HasComputedFlags */) === 0) { subtreeTransformFlags |= computeTransformFlagsForNode(node, 0); } inStrictMode = saveInStrictMode; } function bindJSDocTypedefTagIfAny(node) { if (!ts.hasJSDocNodes(node)) { return; } for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) { var jsDoc = _a[_i]; if (!jsDoc.tags) { continue; } for (var _b = 0, _c = jsDoc.tags; _b < _c.length; _b++) { var tag = _c[_b]; if (tag.kind === 288 /* JSDocTypedefTag */) { var savedParent = parent; parent = jsDoc; bind(tag); parent = savedParent; } } } } function updateStrictModeStatementList(statements) { if (!inStrictMode) { for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) { var statement = statements_1[_i]; if (!ts.isPrologueDirective(statement)) { return; } if (isUseStrictPrologueDirective(statement)) { inStrictMode = true; return; } } } } /// Should be called only on prologue directives (isPrologueDirective(node) should be true) function isUseStrictPrologueDirective(node) { var nodeText = ts.getTextOfNodeFromSourceText(file.text, node.expression); // Note: the node text must be exactly "use strict" or 'use strict'. It is not ok for the // string to contain unicode escapes (as per ES5). return nodeText === '"use strict"' || nodeText === "'use strict'"; } function bindWorker(node) { switch (node.kind) { /* Strict mode checks */ case 71 /* Identifier */: // for typedef type names with namespaces, bind the new jsdoc type symbol here // because it requires all containing namespaces to be in effect, namely the // current "blockScopeContainer" needs to be set to its immediate namespace parent. if (node.isInJSDocNamespace) { var parentNode = node.parent; while (parentNode && parentNode.kind !== 288 /* JSDocTypedefTag */) { parentNode = parentNode.parent; } bindBlockScopedDeclaration(parentNode, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */); break; } // falls through case 99 /* ThisKeyword */: if (currentFlow && (ts.isExpression(node) || parent.kind === 266 /* ShorthandPropertyAssignment */)) { node.flowNode = currentFlow; } return checkStrictModeIdentifier(node); case 180 /* PropertyAccessExpression */: if (currentFlow && isNarrowableReference(node)) { node.flowNode = currentFlow; } if (ts.isSpecialPropertyDeclaration(node)) { bindSpecialPropertyDeclaration(node); } break; case 195 /* BinaryExpression */: var specialKind = ts.getSpecialPropertyAssignmentKind(node); switch (specialKind) { case 1 /* ExportsProperty */: bindExportsPropertyAssignment(node); break; case 2 /* ModuleExports */: bindModuleExportsAssignment(node); break; case 3 /* PrototypeProperty */: bindPrototypePropertyAssignment(node); break; case 4 /* ThisProperty */: bindThisPropertyAssignment(node); break; case 5 /* Property */: bindStaticPropertyAssignment(node); break; case 0 /* None */: // Nothing to do break; default: ts.Debug.fail("Unknown special property assignment kind"); } return checkStrictModeBinaryExpression(node); case 264 /* CatchClause */: return checkStrictModeCatchClause(node); case 189 /* DeleteExpression */: return checkStrictModeDeleteExpression(node); case 8 /* NumericLiteral */: return checkStrictModeNumericLiteral(node); case 194 /* PostfixUnaryExpression */: return checkStrictModePostfixUnaryExpression(node); case 193 /* PrefixUnaryExpression */: return checkStrictModePrefixUnaryExpression(node); case 221 /* WithStatement */: return checkStrictModeWithStatement(node); case 170 /* ThisType */: seenThisKeyword = true; return; case 159 /* TypePredicate */: return checkTypePredicate(node); case 146 /* TypeParameter */: return declareSymbolAndAddToSymbolTable(node, 262144 /* TypeParameter */, 530920 /* TypeParameterExcludes */); case 147 /* Parameter */: return bindParameter(node); case 227 /* VariableDeclaration */: return bindVariableDeclarationOrBindingElement(node); case 177 /* BindingElement */: node.flowNode = currentFlow; return bindVariableDeclarationOrBindingElement(node); case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return bindPropertyWorker(node); case 265 /* PropertyAssignment */: case 266 /* ShorthandPropertyAssignment */: return bindPropertyOrMethodOrAccessor(node, 4 /* Property */, 0 /* PropertyExcludes */); case 268 /* EnumMember */: return bindPropertyOrMethodOrAccessor(node, 8 /* EnumMember */, 900095 /* EnumMemberExcludes */); case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: return declareSymbolAndAddToSymbolTable(node, 131072 /* Signature */, 0 /* None */); case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: // If this is an ObjectLiteralExpression method, then it sits in the same space // as other properties in the object literal. So we use SymbolFlags.PropertyExcludes // so that it will conflict with any other object literal members with the same // name. return bindPropertyOrMethodOrAccessor(node, 8192 /* Method */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), ts.isObjectLiteralMethod(node) ? 0 /* PropertyExcludes */ : 99263 /* MethodExcludes */); case 229 /* FunctionDeclaration */: return bindFunctionDeclaration(node); case 153 /* Constructor */: return declareSymbolAndAddToSymbolTable(node, 16384 /* Constructor */, /*symbolExcludes:*/ 0 /* None */); case 154 /* GetAccessor */: return bindPropertyOrMethodOrAccessor(node, 32768 /* GetAccessor */, 41919 /* GetAccessorExcludes */); case 155 /* SetAccessor */: return bindPropertyOrMethodOrAccessor(node, 65536 /* SetAccessor */, 74687 /* SetAccessorExcludes */); case 161 /* FunctionType */: case 277 /* JSDocFunctionType */: case 162 /* ConstructorType */: return bindFunctionOrConstructorType(node); case 164 /* TypeLiteral */: case 280 /* JSDocTypeLiteral */: case 173 /* MappedType */: return bindAnonymousTypeWorker(node); case 179 /* ObjectLiteralExpression */: return bindObjectLiteralExpression(node); case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return bindFunctionExpression(node); case 182 /* CallExpression */: if (ts.isInJavaScriptFile(node)) { bindCallExpression(node); } break; // Members of classes, interfaces, and modules case 200 /* ClassExpression */: case 230 /* ClassDeclaration */: // All classes are automatically in strict mode in ES6. inStrictMode = true; return bindClassLikeDeclaration(node); case 231 /* InterfaceDeclaration */: return bindBlockScopedDeclaration(node, 64 /* Interface */, 792968 /* InterfaceExcludes */); case 232 /* TypeAliasDeclaration */: return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */); case 233 /* EnumDeclaration */: return bindEnumDeclaration(node); case 234 /* ModuleDeclaration */: return bindModuleDeclaration(node); // Jsx-attributes case 258 /* JsxAttributes */: return bindJsxAttributes(node); case 257 /* JsxAttribute */: return bindJsxAttribute(node, 4 /* Property */, 0 /* PropertyExcludes */); // Imports and exports case 238 /* ImportEqualsDeclaration */: case 241 /* NamespaceImport */: case 243 /* ImportSpecifier */: case 247 /* ExportSpecifier */: return declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */); case 237 /* NamespaceExportDeclaration */: return bindNamespaceExportDeclaration(node); case 240 /* ImportClause */: return bindImportClause(node); case 245 /* ExportDeclaration */: return bindExportDeclaration(node); case 244 /* ExportAssignment */: return bindExportAssignment(node); case 269 /* SourceFile */: updateStrictModeStatementList(node.statements); return bindSourceFileIfExternalModule(); case 208 /* Block */: if (!ts.isFunctionLike(node.parent)) { return; } // falls through case 235 /* ModuleBlock */: return updateStrictModeStatementList(node.statements); case 284 /* JSDocParameterTag */: if (node.parent.kind !== 280 /* JSDocTypeLiteral */) { break; } // falls through case 289 /* JSDocPropertyTag */: var propTag = node; var flags = propTag.isBracketed || propTag.typeExpression && propTag.typeExpression.type.kind === 276 /* JSDocOptionalType */ ? 4 /* Property */ | 16777216 /* Optional */ : 4 /* Property */; return declareSymbolAndAddToSymbolTable(propTag, flags, 0 /* PropertyExcludes */); case 288 /* JSDocTypedefTag */: { var fullName = node.fullName; if (!fullName || fullName.kind === 71 /* Identifier */) { return bindBlockScopedDeclaration(node, 524288 /* TypeAlias */, 793064 /* TypeAliasExcludes */); } break; } } } function bindPropertyWorker(node) { return bindPropertyOrMethodOrAccessor(node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */); } function bindAnonymousTypeWorker(node) { return bindAnonymousDeclaration(node, 2048 /* TypeLiteral */, "__type" /* Type */); } function checkTypePredicate(node) { var parameterName = node.parameterName, type = node.type; if (parameterName && parameterName.kind === 71 /* Identifier */) { checkStrictModeIdentifier(parameterName); } if (parameterName && parameterName.kind === 170 /* ThisType */) { seenThisKeyword = true; } bind(type); } function bindSourceFileIfExternalModule() { setExportContextFlag(file); if (ts.isExternalModule(file)) { bindSourceFileAsExternalModule(); } } function bindSourceFileAsExternalModule() { bindAnonymousDeclaration(file, 512 /* ValueModule */, "\"" + ts.removeFileExtension(file.fileName) + "\""); } function bindExportAssignment(node) { if (!container.symbol || !container.symbol.exports) { // Export assignment in some sort of block construct bindAnonymousDeclaration(node, 2097152 /* Alias */, getDeclarationName(node)); } else { var flags = node.kind === 244 /* ExportAssignment */ && ts.exportAssignmentIsAlias(node) // An export default clause with an EntityNameExpression exports all meanings of that identifier ? 2097152 /* Alias */ // An export default clause with any other expression exports a value : 4 /* Property */; // If there is an `export default x;` alias declaration, can't `export default` anything else. // (In contrast, you can still have `export default function f() {}` and `export default interface I {}`.) declareSymbol(container.symbol.exports, container.symbol, node, flags, 67108863 /* All */); } } function bindNamespaceExportDeclaration(node) { if (node.modifiers && node.modifiers.length) { file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Modifiers_cannot_appear_here)); } if (node.parent.kind !== 269 /* SourceFile */) { file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_at_top_level)); return; } else { var parent_1 = node.parent; if (!ts.isExternalModule(parent_1)) { file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_module_files)); return; } if (!parent_1.isDeclarationFile) { file.bindDiagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.Global_module_exports_may_only_appear_in_declaration_files)); return; } } file.symbol.globalExports = file.symbol.globalExports || ts.createSymbolTable(); declareSymbol(file.symbol.globalExports, file.symbol, node, 2097152 /* Alias */, 2097152 /* AliasExcludes */); } function bindExportDeclaration(node) { if (!container.symbol || !container.symbol.exports) { // Export * in some sort of block construct bindAnonymousDeclaration(node, 8388608 /* ExportStar */, getDeclarationName(node)); } else if (!node.exportClause) { // All export * declarations are collected in an __export symbol declareSymbol(container.symbol.exports, container.symbol, node, 8388608 /* ExportStar */, 0 /* None */); } } function bindImportClause(node) { if (node.name) { declareSymbolAndAddToSymbolTable(node, 2097152 /* Alias */, 2097152 /* AliasExcludes */); } } function setCommonJsModuleIndicator(node) { if (!file.commonJsModuleIndicator) { file.commonJsModuleIndicator = node; if (!file.externalModuleIndicator) { bindSourceFileAsExternalModule(); } } } function bindExportsPropertyAssignment(node) { // When we create a property via 'exports.foo = bar', the 'exports.foo' property access // expression is the declaration setCommonJsModuleIndicator(node); declareSymbol(file.symbol.exports, file.symbol, node.left, 4 /* Property */ | 1048576 /* ExportValue */, 0 /* None */); } function isExportsOrModuleExportsOrAlias(node) { return ts.isExportsIdentifier(node) || ts.isModuleExportsPropertyAccessExpression(node) || ts.isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node); } function isNameOfExportsOrModuleExportsAliasDeclaration(node) { var symbol = lookupSymbolForName(node.escapedText); return symbol && symbol.valueDeclaration && ts.isVariableDeclaration(symbol.valueDeclaration) && symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer); } function isExportsOrModuleExportsOrAliasOrAssignment(node) { return isExportsOrModuleExportsOrAlias(node) || (ts.isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right))); } function bindModuleExportsAssignment(node) { // A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports' // is still pointing to 'module.exports'. // We do not want to consider this as 'export=' since a module can have only one of these. // Similarly we do not want to treat 'module.exports = exports' as an 'export='. var assignedExpression = ts.getRightMostAssignedExpression(node.right); if (ts.isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) { // Mark it as a module in case there are no other exports in the file setCommonJsModuleIndicator(node); return; } // 'module.exports = expr' assignment setCommonJsModuleIndicator(node); declareSymbol(file.symbol.exports, file.symbol, node, 4 /* Property */ | 1048576 /* ExportValue */ | 512 /* ValueModule */, 0 /* None */); } function bindThisPropertyAssignment(node) { ts.Debug.assert(ts.isInJavaScriptFile(node)); var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); switch (container.kind) { case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: // Declare a 'member' if the container is an ES5 class or ES6 constructor container.symbol.members = container.symbol.members || ts.createSymbolTable(); // It's acceptable for multiple 'this' assignments of the same identifier to occur declareSymbol(container.symbol.members, container.symbol, node, 4 /* Property */, 0 /* PropertyExcludes */ & ~4 /* Property */); break; case 153 /* Constructor */: case 150 /* PropertyDeclaration */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: // this.foo assignment in a JavaScript class // Bind this property to the containing class var containingClass = container.parent; var symbolTable = ts.hasModifier(container, 32 /* Static */) ? containingClass.symbol.exports : containingClass.symbol.members; declareSymbol(symbolTable, containingClass.symbol, node, 4 /* Property */, 0 /* None */, /*isReplaceableByMethod*/ true); break; } } function bindSpecialPropertyDeclaration(node) { ts.Debug.assert(ts.isInJavaScriptFile(node)); if (node.expression.kind === 99 /* ThisKeyword */) { bindThisPropertyAssignment(node); } else if ((node.expression.kind === 71 /* Identifier */ || node.expression.kind === 180 /* PropertyAccessExpression */) && node.parent.parent.kind === 269 /* SourceFile */) { bindStaticPropertyAssignment(node); } } function bindPrototypePropertyAssignment(node) { // We saw a node of the form 'x.prototype.y = z'. Declare a 'member' y on x if x is a function or class, or not declared. // Look up the function in the local scope, since prototype assignments should // follow the function declaration var leftSideOfAssignment = node.left; var classPrototype = leftSideOfAssignment.expression; var constructorFunction = classPrototype.expression; // Fix up parent pointers since we're going to use these nodes before we bind into them leftSideOfAssignment.parent = node; constructorFunction.parent = classPrototype; classPrototype.parent = leftSideOfAssignment; bindPropertyAssignment(constructorFunction.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ true); } /** * For nodes like `x.y = z`, declare a member 'y' on 'x' if x is a function or class, or not declared. * Also works for expression statements preceded by JSDoc, like / ** @type number * / x.y; */ function bindStaticPropertyAssignment(node) { // Look up the function in the local scope, since static assignments should // follow the function declaration var leftSideOfAssignment = node.kind === 180 /* PropertyAccessExpression */ ? node : node.left; var target = leftSideOfAssignment.expression; if (ts.isIdentifier(target)) { // Fix up parent pointers since we're going to use these nodes before we bind into them target.parent = leftSideOfAssignment; if (node.kind === 195 /* BinaryExpression */) { leftSideOfAssignment.parent = node; } if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) { // This can be an alias for the 'exports' or 'module.exports' names, e.g. // var util = module.exports; // util.property = function ... bindExportsPropertyAssignment(node); } else { bindPropertyAssignment(target.escapedText, leftSideOfAssignment, /*isPrototypeProperty*/ false); } } } function lookupSymbolForName(name) { var local = container.locals && container.locals.get(name); if (local) { return local.exportSymbol || local; } return container.symbol && container.symbol.exports && container.symbol.exports.get(name); } function bindPropertyAssignment(functionName, propertyAccess, isPrototypeProperty) { var symbol = lookupSymbolForName(functionName); var targetSymbol = symbol && ts.isDeclarationOfFunctionOrClassExpression(symbol) ? symbol.valueDeclaration.initializer.symbol : symbol; ts.Debug.assert(propertyAccess.parent.kind === 195 /* BinaryExpression */ || propertyAccess.parent.kind === 211 /* ExpressionStatement */); var isLegalPosition; if (propertyAccess.parent.kind === 195 /* BinaryExpression */) { var initializerKind = propertyAccess.parent.right.kind; isLegalPosition = (initializerKind === 200 /* ClassExpression */ || initializerKind === 187 /* FunctionExpression */) && propertyAccess.parent.parent.parent.kind === 269 /* SourceFile */; } else { isLegalPosition = propertyAccess.parent.parent.kind === 269 /* SourceFile */; } if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & 1920 /* Namespace */)) && isLegalPosition) { ts.Debug.assert(ts.isIdentifier(propertyAccess.expression)); var identifier = propertyAccess.expression; var flags = 1536 /* Module */ | 67108864 /* JSContainer */; var excludeFlags = 106639 /* ValueModuleExcludes */ & ~67108864 /* JSContainer */; if (targetSymbol) { addDeclarationToSymbol(symbol, identifier, flags); } else { targetSymbol = declareSymbol(container.locals, /*parent*/ undefined, identifier, flags, excludeFlags); } } if (!targetSymbol || !(targetSymbol.flags & (16 /* Function */ | 32 /* Class */ | 1024 /* NamespaceModule */))) { return; } // Set up the members collection if it doesn't exist already var symbolTable = isPrototypeProperty ? (targetSymbol.members || (targetSymbol.members = ts.createSymbolTable())) : (targetSymbol.exports || (targetSymbol.exports = ts.createSymbolTable())); // Declare the method/property declareSymbol(symbolTable, targetSymbol, propertyAccess, 4 /* Property */, 0 /* PropertyExcludes */); } function bindCallExpression(node) { // We're only inspecting call expressions to detect CommonJS modules, so we can skip // this check if we've already seen the module indicator if (!file.commonJsModuleIndicator && ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ false)) { setCommonJsModuleIndicator(node); } } function bindClassLikeDeclaration(node) { if (node.kind === 230 /* ClassDeclaration */) { bindBlockScopedDeclaration(node, 32 /* Class */, 899519 /* ClassExcludes */); } else { var bindingName = node.name ? node.name.escapedText : "__class" /* Class */; bindAnonymousDeclaration(node, 32 /* Class */, bindingName); // Add name of class expression into the map for semantic classifier if (node.name) { classifiableNames.set(node.name.escapedText, true); } } var symbol = node.symbol; // TypeScript 1.0 spec (April 2014): 8.4 // Every class automatically contains a static property member named 'prototype', the // type of which is an instantiation of the class type with type Any supplied as a type // argument for each type parameter. It is an error to explicitly declare a static // property member with the name 'prototype'. // // Note: we check for this here because this class may be merging into a module. The // module might have an exported variable called 'prototype'. We can't allow that as // that would clash with the built-in 'prototype' for the class. var prototypeSymbol = createSymbol(4 /* Property */ | 4194304 /* Prototype */, "prototype"); var symbolExport = symbol.exports.get(prototypeSymbol.escapedName); if (symbolExport) { if (node.name) { node.name.parent = node; } file.bindDiagnostics.push(createDiagnosticForNode(symbolExport.declarations[0], ts.Diagnostics.Duplicate_identifier_0, ts.symbolName(prototypeSymbol))); } symbol.exports.set(prototypeSymbol.escapedName, prototypeSymbol); prototypeSymbol.parent = symbol; } function bindEnumDeclaration(node) { return ts.isConst(node) ? bindBlockScopedDeclaration(node, 128 /* ConstEnum */, 899967 /* ConstEnumExcludes */) : bindBlockScopedDeclaration(node, 256 /* RegularEnum */, 899327 /* RegularEnumExcludes */); } function bindVariableDeclarationOrBindingElement(node) { if (inStrictMode) { checkStrictModeEvalOrArguments(node, node.name); } if (!ts.isBindingPattern(node.name)) { if (ts.isBlockOrCatchScoped(node)) { bindBlockScopedVariableDeclaration(node); } else if (ts.isParameterDeclaration(node)) { // It is safe to walk up parent chain to find whether the node is a destructing parameter declaration // because its parent chain has already been set up, since parents are set before descending into children. // // If node is a binding element in parameter declaration, we need to use ParameterExcludes. // Using ParameterExcludes flag allows the compiler to report an error on duplicate identifiers in Parameter Declaration // For example: // function foo([a,a]) {} // Duplicate Identifier error // function bar(a,a) {} // Duplicate Identifier error, parameter declaration in this case is handled in bindParameter // // which correctly set excluded symbols declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); } else { declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107454 /* FunctionScopedVariableExcludes */); } } } function bindParameter(node) { if (inStrictMode && !(node.flags & 2097152 /* Ambient */)) { // It is a SyntaxError if the identifier eval or arguments appears within a FormalParameterList of a // strict mode FunctionLikeDeclaration or FunctionExpression(13.1) checkStrictModeEvalOrArguments(node, node.name); } if (ts.isBindingPattern(node.name)) { bindAnonymousDeclaration(node, 1 /* FunctionScopedVariable */, "__" + ts.indexOf(node.parent.parameters, node)); } else { declareSymbolAndAddToSymbolTable(node, 1 /* FunctionScopedVariable */, 107455 /* ParameterExcludes */); } // If this is a property-parameter, then also declare the property symbol into the // containing class. if (ts.isParameterPropertyDeclaration(node)) { var classDeclaration = node.parent.parent; declareSymbol(classDeclaration.symbol.members, classDeclaration.symbol, node, 4 /* Property */ | (node.questionToken ? 16777216 /* Optional */ : 0 /* None */), 0 /* PropertyExcludes */); } } function bindFunctionDeclaration(node) { if (!file.isDeclarationFile && !(node.flags & 2097152 /* Ambient */)) { if (ts.isAsyncFunction(node)) { emitFlags |= 1024 /* HasAsyncFunctions */; } } checkStrictModeFunctionName(node); if (inStrictMode) { checkStrictModeFunctionDeclaration(node); bindBlockScopedDeclaration(node, 16 /* Function */, 106927 /* FunctionExcludes */); } else { declareSymbolAndAddToSymbolTable(node, 16 /* Function */, 106927 /* FunctionExcludes */); } } function bindFunctionExpression(node) { if (!file.isDeclarationFile && !(node.flags & 2097152 /* Ambient */)) { if (ts.isAsyncFunction(node)) { emitFlags |= 1024 /* HasAsyncFunctions */; } } if (currentFlow) { node.flowNode = currentFlow; } checkStrictModeFunctionName(node); var bindingName = node.name ? node.name.escapedText : "__function" /* Function */; return bindAnonymousDeclaration(node, 16 /* Function */, bindingName); } function bindPropertyOrMethodOrAccessor(node, symbolFlags, symbolExcludes) { if (!file.isDeclarationFile && !(node.flags & 2097152 /* Ambient */) && ts.isAsyncFunction(node)) { emitFlags |= 1024 /* HasAsyncFunctions */; } if (currentFlow && ts.isObjectLiteralOrClassExpressionMethod(node)) { node.flowNode = currentFlow; } return ts.hasDynamicName(node) ? bindAnonymousDeclaration(node, symbolFlags, "__computed" /* Computed */) : declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes); } // reachability checks function shouldReportErrorOnModuleDeclaration(node) { var instanceState = getModuleInstanceState(node); return instanceState === 1 /* Instantiated */ || (instanceState === 2 /* ConstEnumOnly */ && options.preserveConstEnums); } function checkUnreachable(node) { if (!(currentFlow.flags & 1 /* Unreachable */)) { return false; } if (currentFlow === unreachableFlow) { var reportError = // report error on all statements except empty ones (ts.isStatementButNotDeclaration(node) && node.kind !== 210 /* EmptyStatement */) || // report error on class declarations node.kind === 230 /* ClassDeclaration */ || // report error on instantiated modules or const-enums only modules if preserveConstEnums is set (node.kind === 234 /* ModuleDeclaration */ && shouldReportErrorOnModuleDeclaration(node)) || // report error on regular enums and const enums if preserveConstEnums is set (node.kind === 233 /* 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 && !(node.flags & 2097152 /* Ambient */) && (node.kind !== 209 /* VariableStatement */ || ts.getCombinedNodeFlags(node.declarationList) & 3 /* BlockScoped */ || ts.forEach(node.declarationList.declarations, function (d) { return d.initializer; })); if (reportUnreachableCode) { errorOnFirstToken(node, ts.Diagnostics.Unreachable_code_detected); } } } return true; } } /** * Computes the transform flags for a node, given the transform flags of its subtree * * @param node The node to analyze * @param subtreeFlags Transform flags computed for this node's subtree */ function computeTransformFlagsForNode(node, subtreeFlags) { var kind = node.kind; switch (kind) { case 182 /* CallExpression */: return computeCallExpression(node, subtreeFlags); case 183 /* NewExpression */: return computeNewExpression(node, subtreeFlags); case 234 /* ModuleDeclaration */: return computeModuleDeclaration(node, subtreeFlags); case 186 /* ParenthesizedExpression */: return computeParenthesizedExpression(node, subtreeFlags); case 195 /* BinaryExpression */: return computeBinaryExpression(node, subtreeFlags); case 211 /* ExpressionStatement */: return computeExpressionStatement(node, subtreeFlags); case 147 /* Parameter */: return computeParameter(node, subtreeFlags); case 188 /* ArrowFunction */: return computeArrowFunction(node, subtreeFlags); case 187 /* FunctionExpression */: return computeFunctionExpression(node, subtreeFlags); case 229 /* FunctionDeclaration */: return computeFunctionDeclaration(node, subtreeFlags); case 227 /* VariableDeclaration */: return computeVariableDeclaration(node, subtreeFlags); case 228 /* VariableDeclarationList */: return computeVariableDeclarationList(node, subtreeFlags); case 209 /* VariableStatement */: return computeVariableStatement(node, subtreeFlags); case 223 /* LabeledStatement */: return computeLabeledStatement(node, subtreeFlags); case 230 /* ClassDeclaration */: return computeClassDeclaration(node, subtreeFlags); case 200 /* ClassExpression */: return computeClassExpression(node, subtreeFlags); case 263 /* HeritageClause */: return computeHeritageClause(node, subtreeFlags); case 264 /* CatchClause */: return computeCatchClause(node, subtreeFlags); case 202 /* ExpressionWithTypeArguments */: return computeExpressionWithTypeArguments(node, subtreeFlags); case 153 /* Constructor */: return computeConstructor(node, subtreeFlags); case 150 /* PropertyDeclaration */: return computePropertyDeclaration(node, subtreeFlags); case 152 /* MethodDeclaration */: return computeMethod(node, subtreeFlags); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return computeAccessor(node, subtreeFlags); case 238 /* ImportEqualsDeclaration */: return computeImportEquals(node, subtreeFlags); case 180 /* PropertyAccessExpression */: return computePropertyAccess(node, subtreeFlags); default: return computeOther(node, kind, subtreeFlags); } } ts.computeTransformFlagsForNode = computeTransformFlagsForNode; function computeCallExpression(node, subtreeFlags) { var transformFlags = subtreeFlags; var expression = node.expression; var expressionKind = expression.kind; if (node.typeArguments) { transformFlags |= 3 /* AssertTypeScript */; } if (subtreeFlags & 524288 /* ContainsSpread */ || isSuperOrSuperProperty(expression, expressionKind)) { // If the this node contains a SpreadExpression, or is a super call, then it is an ES6 // node. transformFlags |= 192 /* AssertES2015 */; } if (expression.kind === 91 /* ImportKeyword */) { transformFlags |= 67108864 /* ContainsDynamicImport */; // A dynamic 'import()' call that contains a lexical 'this' will // require a captured 'this' when emitting down-level. if (subtreeFlags & 16384 /* ContainsLexicalThis */) { transformFlags |= 32768 /* ContainsCapturedLexicalThis */; } } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */; } function isSuperOrSuperProperty(node, kind) { switch (kind) { case 97 /* SuperKeyword */: return true; case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: var expression = node.expression; var expressionKind = expression.kind; return expressionKind === 97 /* SuperKeyword */; } return false; } function computeNewExpression(node, subtreeFlags) { var transformFlags = subtreeFlags; if (node.typeArguments) { transformFlags |= 3 /* AssertTypeScript */; } if (subtreeFlags & 524288 /* ContainsSpread */) { // If the this node contains a SpreadElementExpression then it is an ES6 // node. transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~537396545 /* ArrayLiteralOrCallOrNewExcludes */; } function computeBinaryExpression(node, subtreeFlags) { var transformFlags = subtreeFlags; var operatorTokenKind = node.operatorToken.kind; var leftKind = node.left.kind; if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 179 /* ObjectLiteralExpression */) { // Destructuring object assignments with are ES2015 syntax // and possibly ESNext if they contain rest transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */; } else if (operatorTokenKind === 58 /* EqualsToken */ && leftKind === 178 /* ArrayLiteralExpression */) { // Destructuring assignments are ES2015 syntax. transformFlags |= 192 /* AssertES2015 */ | 3072 /* AssertDestructuringAssignment */; } else if (operatorTokenKind === 40 /* AsteriskAsteriskToken */ || operatorTokenKind === 62 /* AsteriskAsteriskEqualsToken */) { // Exponentiation is ES2016 syntax. transformFlags |= 32 /* AssertES2016 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeParameter(node, subtreeFlags) { var transformFlags = subtreeFlags; var name = node.name; var initializer = node.initializer; var dotDotDotToken = node.dotDotDotToken; // The '?' token, type annotations, decorators, and 'this' parameters are TypeSCript // syntax. if (node.questionToken || node.type || subtreeFlags & 4096 /* ContainsDecorators */ || ts.isThisIdentifier(name)) { transformFlags |= 3 /* AssertTypeScript */; } // If a parameter has an accessibility modifier, then it is TypeScript syntax. if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { transformFlags |= 3 /* AssertTypeScript */ | 262144 /* ContainsParameterPropertyAssignments */; } // parameters with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // If a parameter has an initializer, a binding pattern or a dotDotDot token, then // it is ES6 syntax and its container must emit default value assignments or parameter destructuring downlevel. if (subtreeFlags & 8388608 /* ContainsBindingPattern */ || initializer || dotDotDotToken) { transformFlags |= 192 /* AssertES2015 */ | 131072 /* ContainsDefaultValueAssignments */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* ParameterExcludes */; } function computeParenthesizedExpression(node, subtreeFlags) { var transformFlags = subtreeFlags; var expression = node.expression; var expressionKind = expression.kind; var expressionTransformFlags = expression.transformFlags; // If the node is synthesized, it means the emitter put the parentheses there, // not the user. If we didn't want them, the emitter would not have put them // there. if (expressionKind === 203 /* AsExpression */ || expressionKind === 185 /* TypeAssertionExpression */) { transformFlags |= 3 /* AssertTypeScript */; } // If the expression of a ParenthesizedExpression is a destructuring assignment, // then the ParenthesizedExpression is a destructuring assignment. if (expressionTransformFlags & 1024 /* DestructuringAssignment */) { transformFlags |= 1024 /* DestructuringAssignment */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeClassDeclaration(node, subtreeFlags) { var transformFlags; if (ts.hasModifier(node, 2 /* Ambient */)) { // An ambient declaration is TypeScript syntax. transformFlags = 3 /* AssertTypeScript */; } else { // A ClassDeclaration is ES6 syntax. transformFlags = subtreeFlags | 192 /* AssertES2015 */; // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. // An exported declaration may be TypeScript syntax, but is handled by the visitor // for a namespace declaration. if ((subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */) || node.typeParameters) { transformFlags |= 3 /* AssertTypeScript */; } if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) { // A computed property name containing `this` might need to be rewritten, // so propagate the ContainsLexicalThis flag upward. transformFlags |= 16384 /* ContainsLexicalThis */; } } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~539358529 /* ClassExcludes */; } function computeClassExpression(node, subtreeFlags) { // A ClassExpression is ES6 syntax. var transformFlags = subtreeFlags | 192 /* AssertES2015 */; // A class with a parameter property assignment, property initializer, or decorator is // TypeScript syntax. if (subtreeFlags & 274432 /* TypeScriptClassSyntaxMask */ || node.typeParameters) { transformFlags |= 3 /* AssertTypeScript */; } if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) { // A computed property name containing `this` might need to be rewritten, // so propagate the ContainsLexicalThis flag upward. transformFlags |= 16384 /* ContainsLexicalThis */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~539358529 /* ClassExcludes */; } function computeHeritageClause(node, subtreeFlags) { var transformFlags = subtreeFlags; switch (node.token) { case 85 /* ExtendsKeyword */: // An `extends` HeritageClause is ES6 syntax. transformFlags |= 192 /* AssertES2015 */; break; case 108 /* ImplementsKeyword */: // An `implements` HeritageClause is TypeScript syntax. transformFlags |= 3 /* AssertTypeScript */; break; default: ts.Debug.fail("Unexpected token for heritage clause"); break; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeCatchClause(node, subtreeFlags) { var transformFlags = subtreeFlags; if (!node.variableDeclaration) { transformFlags |= 8 /* AssertESNext */; } else if (ts.isBindingPattern(node.variableDeclaration.name)) { transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~537920833 /* CatchClauseExcludes */; } function computeExpressionWithTypeArguments(node, subtreeFlags) { // An ExpressionWithTypeArguments is ES6 syntax, as it is used in the // extends clause of a class. var transformFlags = subtreeFlags | 192 /* AssertES2015 */; // If an ExpressionWithTypeArguments contains type arguments, then it // is TypeScript syntax. if (node.typeArguments) { transformFlags |= 3 /* AssertTypeScript */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeConstructor(node, subtreeFlags) { var transformFlags = subtreeFlags; // TypeScript-specific modifiers and overloads are TypeScript syntax if (ts.hasModifier(node, 2270 /* TypeScriptModifier */) || !node.body) { transformFlags |= 3 /* AssertTypeScript */; } // function declarations with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601015617 /* ConstructorExcludes */; } function computeMethod(node, subtreeFlags) { // A MethodDeclaration is ES6 syntax. var transformFlags = subtreeFlags | 192 /* AssertES2015 */; // Decorators, TypeScript-specific modifiers, type parameters, type annotations, and // overloads are TypeScript syntax. if (node.decorators || ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.typeParameters || node.type || (node.name && ts.isComputedPropertyName(node.name)) // While computed method names aren't typescript, the TS transform must visit them to emit property declarations correctly || !node.body) { transformFlags |= 3 /* AssertTypeScript */; } // function declarations with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // An async method declaration is ES2017 syntax. if (ts.hasModifier(node, 256 /* Async */)) { transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */; } if (node.asteriskToken) { transformFlags |= 768 /* AssertGenerator */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601015617 /* MethodOrAccessorExcludes */; } function computeAccessor(node, subtreeFlags) { var transformFlags = subtreeFlags; // Decorators, TypeScript-specific modifiers, type annotations, and overloads are // TypeScript syntax. if (node.decorators || ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.type || (node.name && ts.isComputedPropertyName(node.name)) // While computed accessor names aren't typescript, the TS transform must visit them to emit property declarations correctly || !node.body) { transformFlags |= 3 /* AssertTypeScript */; } // function declarations with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601015617 /* MethodOrAccessorExcludes */; } function computePropertyDeclaration(node, subtreeFlags) { // A PropertyDeclaration is TypeScript syntax. var transformFlags = subtreeFlags | 3 /* AssertTypeScript */; // If the PropertyDeclaration has an initializer, we need to inform its ancestor // so that it handle the transformation. if (node.initializer) { transformFlags |= 8192 /* ContainsPropertyInitializer */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeFunctionDeclaration(node, subtreeFlags) { var transformFlags; var modifierFlags = ts.getModifierFlags(node); var body = node.body; if (!body || (modifierFlags & 2 /* Ambient */)) { // An ambient declaration is TypeScript syntax. // A FunctionDeclaration without a body is an overload and is TypeScript syntax. transformFlags = 3 /* AssertTypeScript */; } else { transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */; // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript // syntax. if (modifierFlags & 2270 /* TypeScriptModifier */ || node.typeParameters || node.type) { transformFlags |= 3 /* AssertTypeScript */; } // An async function declaration is ES2017 syntax. if (modifierFlags & 256 /* Async */) { transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */; } // function declarations with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // If a FunctionDeclaration's subtree has marked the container as needing to capture the // lexical this, or the function contains parameters with initializers, then this node is // ES6 syntax. if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) { transformFlags |= 192 /* AssertES2015 */; } // If a FunctionDeclaration is generator function and is the body of a // transformed async function, then this node can be transformed to a // down-level generator. // Currently we do not support transforming any other generator fucntions // down level. if (node.asteriskToken) { transformFlags |= 768 /* AssertGenerator */; } } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601281857 /* FunctionExcludes */; } function computeFunctionExpression(node, subtreeFlags) { var transformFlags = subtreeFlags; // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript // syntax. if (ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.typeParameters || node.type) { transformFlags |= 3 /* AssertTypeScript */; } // An async function expression is ES2017 syntax. if (ts.hasModifier(node, 256 /* Async */)) { transformFlags |= node.asteriskToken ? 8 /* AssertESNext */ : 16 /* AssertES2017 */; } // function expressions with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // If a FunctionExpression's subtree has marked the container as needing to capture the // lexical this, or the function contains parameters with initializers, then this node is // ES6 syntax. if (subtreeFlags & 163840 /* ES2015FunctionSyntaxMask */) { transformFlags |= 192 /* AssertES2015 */; } // If a FunctionExpression is generator function and is the body of a // transformed async function, then this node can be transformed to a // down-level generator. if (node.asteriskToken) { transformFlags |= 768 /* AssertGenerator */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601281857 /* FunctionExcludes */; } function computeArrowFunction(node, subtreeFlags) { // An ArrowFunction is ES6 syntax, and excludes markers that should not escape the scope of an ArrowFunction. var transformFlags = subtreeFlags | 192 /* AssertES2015 */; // TypeScript-specific modifiers, type parameters, and type annotations are TypeScript // syntax. if (ts.hasModifier(node, 2270 /* TypeScriptModifier */) || node.typeParameters || node.type) { transformFlags |= 3 /* AssertTypeScript */; } // An async arrow function is ES2017 syntax. if (ts.hasModifier(node, 256 /* Async */)) { transformFlags |= 16 /* AssertES2017 */; } // arrow functions with object rest destructuring are ES Next syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // If an ArrowFunction contains a lexical this, its container must capture the lexical this. if (subtreeFlags & 16384 /* ContainsLexicalThis */) { transformFlags |= 32768 /* ContainsCapturedLexicalThis */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~601249089 /* ArrowFunctionExcludes */; } function computePropertyAccess(node, subtreeFlags) { var transformFlags = subtreeFlags; var expression = node.expression; var expressionKind = expression.kind; // If a PropertyAccessExpression starts with a super keyword, then it is // ES6 syntax, and requires a lexical `this` binding. if (expressionKind === 97 /* SuperKeyword */) { transformFlags |= 16384 /* ContainsLexicalThis */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeVariableDeclaration(node, subtreeFlags) { var transformFlags = subtreeFlags; transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */; // A VariableDeclaration containing ObjectRest is ESNext syntax if (subtreeFlags & 1048576 /* ContainsObjectRest */) { transformFlags |= 8 /* AssertESNext */; } // Type annotations are TypeScript syntax. if (node.type) { transformFlags |= 3 /* AssertTypeScript */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeVariableStatement(node, subtreeFlags) { var transformFlags; var declarationListTransformFlags = node.declarationList.transformFlags; // An ambient declaration is TypeScript syntax. if (ts.hasModifier(node, 2 /* Ambient */)) { transformFlags = 3 /* AssertTypeScript */; } else { transformFlags = subtreeFlags; if (declarationListTransformFlags & 8388608 /* ContainsBindingPattern */) { transformFlags |= 192 /* AssertES2015 */; } } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeLabeledStatement(node, subtreeFlags) { var transformFlags = subtreeFlags; // A labeled statement containing a block scoped binding *may* need to be transformed from ES6. if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */ && ts.isIterationStatement(node, /*lookInLabeledStatements*/ true)) { transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeImportEquals(node, subtreeFlags) { var transformFlags = subtreeFlags; // An ImportEqualsDeclaration with a namespace reference is TypeScript. if (!ts.isExternalModuleImportEqualsDeclaration(node)) { transformFlags |= 3 /* AssertTypeScript */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeExpressionStatement(node, subtreeFlags) { var transformFlags = subtreeFlags; // If the expression of an expression statement is a destructuring assignment, // then we treat the statement as ES6 so that we can indicate that we do not // need to hold on to the right-hand side. if (node.expression.transformFlags & 1024 /* DestructuringAssignment */) { transformFlags |= 192 /* AssertES2015 */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~536872257 /* NodeExcludes */; } function computeModuleDeclaration(node, subtreeFlags) { var transformFlags = 3 /* AssertTypeScript */; var modifierFlags = ts.getModifierFlags(node); if ((modifierFlags & 2 /* Ambient */) === 0) { transformFlags |= subtreeFlags; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~574674241 /* ModuleExcludes */; } function computeVariableDeclarationList(node, subtreeFlags) { var transformFlags = subtreeFlags | 33554432 /* ContainsHoistedDeclarationOrCompletion */; if (subtreeFlags & 8388608 /* ContainsBindingPattern */) { transformFlags |= 192 /* AssertES2015 */; } // If a VariableDeclarationList is `let` or `const`, then it is ES6 syntax. if (node.flags & 3 /* BlockScoped */) { transformFlags |= 192 /* AssertES2015 */ | 4194304 /* ContainsBlockScopedBinding */; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~546309441 /* VariableDeclarationListExcludes */; } function computeOther(node, kind, subtreeFlags) { // Mark transformations needed for each node var transformFlags = subtreeFlags; var excludeFlags = 536872257 /* NodeExcludes */; switch (kind) { case 120 /* AsyncKeyword */: case 192 /* AwaitExpression */: // async/await is ES2017 syntax, but may be ESNext syntax (for async generators) transformFlags |= 8 /* AssertESNext */ | 16 /* AssertES2017 */; break; case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 117 /* AbstractKeyword */: case 124 /* DeclareKeyword */: case 76 /* ConstKeyword */: case 233 /* EnumDeclaration */: case 268 /* EnumMember */: case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: case 204 /* NonNullExpression */: case 131 /* ReadonlyKeyword */: // These nodes are TypeScript syntax. transformFlags |= 3 /* AssertTypeScript */; break; case 250 /* JsxElement */: case 251 /* JsxSelfClosingElement */: case 252 /* JsxOpeningElement */: case 10 /* JsxText */: case 253 /* JsxClosingElement */: case 254 /* JsxFragment */: case 255 /* JsxOpeningFragment */: case 256 /* JsxClosingFragment */: case 257 /* JsxAttribute */: case 258 /* JsxAttributes */: case 259 /* JsxSpreadAttribute */: case 260 /* JsxExpression */: // These nodes are Jsx syntax. transformFlags |= 4 /* AssertJsx */; break; case 13 /* NoSubstitutionTemplateLiteral */: case 14 /* TemplateHead */: case 15 /* TemplateMiddle */: case 16 /* TemplateTail */: case 197 /* TemplateExpression */: case 184 /* TaggedTemplateExpression */: case 266 /* ShorthandPropertyAssignment */: case 115 /* StaticKeyword */: case 205 /* MetaProperty */: // These nodes are ES6 syntax. transformFlags |= 192 /* AssertES2015 */; break; case 9 /* StringLiteral */: if (node.hasExtendedUnicodeEscape) { transformFlags |= 192 /* AssertES2015 */; } break; case 8 /* NumericLiteral */: if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) { transformFlags |= 192 /* AssertES2015 */; } break; case 217 /* ForOfStatement */: // This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of). if (node.awaitModifier) { transformFlags |= 8 /* AssertESNext */; } transformFlags |= 192 /* AssertES2015 */; break; case 198 /* YieldExpression */: // This node is either ES2015 syntax (in a generator) or ES2017 syntax (in an async // generator). transformFlags |= 8 /* AssertESNext */ | 192 /* AssertES2015 */ | 16777216 /* ContainsYield */; break; case 119 /* AnyKeyword */: case 133 /* NumberKeyword */: case 130 /* NeverKeyword */: case 134 /* ObjectKeyword */: case 136 /* StringKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: case 105 /* VoidKeyword */: case 146 /* TypeParameter */: case 149 /* PropertySignature */: case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 159 /* TypePredicate */: case 160 /* TypeReference */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 163 /* TypeQuery */: case 164 /* TypeLiteral */: case 165 /* ArrayType */: case 166 /* TupleType */: case 167 /* UnionType */: case 168 /* IntersectionType */: case 169 /* ParenthesizedType */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 170 /* ThisType */: case 171 /* TypeOperator */: case 172 /* IndexedAccessType */: case 173 /* MappedType */: case 174 /* LiteralType */: case 237 /* NamespaceExportDeclaration */: // Types and signatures are TypeScript syntax, and exclude all other facts. transformFlags = 3 /* AssertTypeScript */; excludeFlags = -3 /* TypeExcludes */; break; case 145 /* ComputedPropertyName */: // Even though computed property names are ES6, we don't treat them as such. // This is so that they can flow through PropertyName transforms unaffected. // Instead, we mark the container as ES6, so that it can properly handle the transform. transformFlags |= 2097152 /* ContainsComputedPropertyName */; if (subtreeFlags & 16384 /* ContainsLexicalThis */) { // A computed method name like `[this.getName()](x: string) { ... }` needs to // distinguish itself from the normal case of a method body containing `this`: // `this` inside a method doesn't need to be rewritten (the method provides `this`), // whereas `this` inside a computed name *might* need to be rewritten if the class/object // is inside an arrow function: // `_this = this; () => class K { [_this.getName()]() { ... } }` // To make this distinction, use ContainsLexicalThisInComputedPropertyName // instead of ContainsLexicalThis for computed property names transformFlags |= 65536 /* ContainsLexicalThisInComputedPropertyName */; } break; case 199 /* SpreadElement */: transformFlags |= 192 /* AssertES2015 */ | 524288 /* ContainsSpread */; break; case 267 /* SpreadAssignment */: transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectSpread */; break; case 97 /* SuperKeyword */: // This node is ES6 syntax. transformFlags |= 192 /* AssertES2015 */; break; case 99 /* ThisKeyword */: // Mark this node and its ancestors as containing a lexical `this` keyword. transformFlags |= 16384 /* ContainsLexicalThis */; break; case 175 /* ObjectBindingPattern */: transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */; if (subtreeFlags & 524288 /* ContainsRest */) { transformFlags |= 8 /* AssertESNext */ | 1048576 /* ContainsObjectRest */; } excludeFlags = 537396545 /* BindingPatternExcludes */; break; case 176 /* ArrayBindingPattern */: transformFlags |= 192 /* AssertES2015 */ | 8388608 /* ContainsBindingPattern */; excludeFlags = 537396545 /* BindingPatternExcludes */; break; case 177 /* BindingElement */: transformFlags |= 192 /* AssertES2015 */; if (node.dotDotDotToken) { transformFlags |= 524288 /* ContainsRest */; } break; case 148 /* Decorator */: // This node is TypeScript syntax, and marks its container as also being TypeScript syntax. transformFlags |= 3 /* AssertTypeScript */ | 4096 /* ContainsDecorators */; break; case 179 /* ObjectLiteralExpression */: excludeFlags = 540087617 /* ObjectLiteralExcludes */; if (subtreeFlags & 2097152 /* ContainsComputedPropertyName */) { // If an ObjectLiteralExpression contains a ComputedPropertyName, then it // is an ES6 node. transformFlags |= 192 /* AssertES2015 */; } if (subtreeFlags & 65536 /* ContainsLexicalThisInComputedPropertyName */) { // A computed property name containing `this` might need to be rewritten, // so propagate the ContainsLexicalThis flag upward. transformFlags |= 16384 /* ContainsLexicalThis */; } if (subtreeFlags & 1048576 /* ContainsObjectSpread */) { // If an ObjectLiteralExpression contains a spread element, then it // is an ES next node. transformFlags |= 8 /* AssertESNext */; } break; case 178 /* ArrayLiteralExpression */: case 183 /* NewExpression */: excludeFlags = 537396545 /* ArrayLiteralOrCallOrNewExcludes */; if (subtreeFlags & 524288 /* ContainsSpread */) { // If the this node contains a SpreadExpression, then it is an ES6 // node. transformFlags |= 192 /* AssertES2015 */; } break; case 213 /* DoStatement */: case 214 /* WhileStatement */: case 215 /* ForStatement */: case 216 /* ForInStatement */: // A loop containing a block scoped binding *may* need to be transformed from ES6. if (subtreeFlags & 4194304 /* ContainsBlockScopedBinding */) { transformFlags |= 192 /* AssertES2015 */; } break; case 269 /* SourceFile */: if (subtreeFlags & 32768 /* ContainsCapturedLexicalThis */) { transformFlags |= 192 /* AssertES2015 */; } break; case 220 /* ReturnStatement */: case 218 /* ContinueStatement */: case 219 /* BreakStatement */: transformFlags |= 33554432 /* ContainsHoistedDeclarationOrCompletion */; break; } node.transformFlags = transformFlags | 536870912 /* HasComputedFlags */; return transformFlags & ~excludeFlags; } /** * Gets the transform flags to exclude when unioning the transform flags of a subtree. * * NOTE: This needs to be kept up-to-date with the exclusions used in `computeTransformFlagsForNode`. * For performance reasons, `computeTransformFlagsForNode` uses local constant values rather * than calling this function. */ /* @internal */ function getTransformFlagsSubtreeExclusions(kind) { if (kind >= 159 /* FirstTypeNode */ && kind <= 174 /* LastTypeNode */) { return -3 /* TypeExcludes */; } switch (kind) { case 182 /* CallExpression */: case 183 /* NewExpression */: case 178 /* ArrayLiteralExpression */: return 537396545 /* ArrayLiteralOrCallOrNewExcludes */; case 234 /* ModuleDeclaration */: return 574674241 /* ModuleExcludes */; case 147 /* Parameter */: return 536872257 /* ParameterExcludes */; case 188 /* ArrowFunction */: return 601249089 /* ArrowFunctionExcludes */; case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: return 601281857 /* FunctionExcludes */; case 228 /* VariableDeclarationList */: return 546309441 /* VariableDeclarationListExcludes */; case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return 539358529 /* ClassExcludes */; case 153 /* Constructor */: return 601015617 /* ConstructorExcludes */; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return 601015617 /* MethodOrAccessorExcludes */; case 119 /* AnyKeyword */: case 133 /* NumberKeyword */: case 130 /* NeverKeyword */: case 136 /* StringKeyword */: case 134 /* ObjectKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: case 105 /* VoidKeyword */: case 146 /* TypeParameter */: case 149 /* PropertySignature */: case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: return -3 /* TypeExcludes */; case 179 /* ObjectLiteralExpression */: return 540087617 /* ObjectLiteralExcludes */; case 264 /* CatchClause */: return 537920833 /* CatchClauseExcludes */; case 175 /* ObjectBindingPattern */: case 176 /* ArrayBindingPattern */: return 537396545 /* BindingPatternExcludes */; default: return 536872257 /* NodeExcludes */; } } ts.getTransformFlagsSubtreeExclusions = getTransformFlagsSubtreeExclusions; /** * "Binds" JSDoc nodes in TypeScript code. * Since we will never create symbols for JSDoc, we just set parent pointers instead. */ function setParentPointers(parent, child) { child.parent = parent; ts.forEachChild(child, function (childsChild) { return setParentPointers(child, childsChild); }); } })(ts || (ts = {})); /** @internal */ var ts; (function (ts) { function createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier) { return getSymbolWalker; function getSymbolWalker(accept) { if (accept === void 0) { accept = function () { return true; }; } var visitedTypes = []; // Sparse array from id to type var visitedSymbols = []; // Sparse array from id to symbol return { walkType: function (type) { try { visitType(type); return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) }; } finally { ts.clear(visitedTypes); ts.clear(visitedSymbols); } }, walkSymbol: function (symbol) { try { visitSymbol(symbol); return { visitedTypes: ts.getOwnValues(visitedTypes), visitedSymbols: ts.getOwnValues(visitedSymbols) }; } finally { ts.clear(visitedTypes); ts.clear(visitedSymbols); } }, }; function visitType(type) { if (!type) { return; } if (visitedTypes[type.id]) { return; } visitedTypes[type.id] = type; // Reuse visitSymbol to visit the type's symbol, // but be sure to bail on recuring into the type if accept declines the symbol. var shouldBail = visitSymbol(type.symbol); if (shouldBail) return; // Visit the type's related types, if any if (type.flags & 65536 /* Object */) { var objectType = type; var objectFlags = objectType.objectFlags; if (objectFlags & 4 /* Reference */) { visitTypeReference(type); } if (objectFlags & 32 /* Mapped */) { visitMappedType(type); } if (objectFlags & (1 /* Class */ | 2 /* Interface */)) { visitInterfaceType(type); } if (objectFlags & (8 /* Tuple */ | 16 /* Anonymous */)) { visitObjectType(objectType); } } if (type.flags & 32768 /* TypeParameter */) { visitTypeParameter(type); } if (type.flags & 393216 /* UnionOrIntersection */) { visitUnionOrIntersectionType(type); } if (type.flags & 524288 /* Index */) { visitIndexType(type); } if (type.flags & 1048576 /* IndexedAccess */) { visitIndexedAccessType(type); } } function visitTypeReference(type) { visitType(type.target); ts.forEach(type.typeArguments, visitType); } function visitTypeParameter(type) { visitType(getConstraintFromTypeParameter(type)); } function visitUnionOrIntersectionType(type) { ts.forEach(type.types, visitType); } function visitIndexType(type) { visitType(type.type); } function visitIndexedAccessType(type) { visitType(type.objectType); visitType(type.indexType); visitType(type.constraint); } function visitMappedType(type) { visitType(type.typeParameter); visitType(type.constraintType); visitType(type.templateType); visitType(type.modifiersType); } function visitSignature(signature) { if (signature.typePredicate) { visitType(signature.typePredicate.type); } ts.forEach(signature.typeParameters, visitType); for (var _i = 0, _a = signature.parameters; _i < _a.length; _i++) { var parameter = _a[_i]; visitSymbol(parameter); } visitType(getRestTypeOfSignature(signature)); visitType(getReturnTypeOfSignature(signature)); } function visitInterfaceType(interfaceT) { visitObjectType(interfaceT); ts.forEach(interfaceT.typeParameters, visitType); ts.forEach(getBaseTypes(interfaceT), visitType); visitType(interfaceT.thisType); } function visitObjectType(type) { var stringIndexType = getIndexTypeOfStructuredType(type, 0 /* String */); visitType(stringIndexType); var numberIndexType = getIndexTypeOfStructuredType(type, 1 /* Number */); visitType(numberIndexType); // The two checks above *should* have already resolved the type (if needed), so this should be cached var resolved = resolveStructuredTypeMembers(type); for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) { var signature = _a[_i]; visitSignature(signature); } for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) { var signature = _c[_b]; visitSignature(signature); } for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) { var p = _e[_d]; visitSymbol(p); } } function visitSymbol(symbol) { if (!symbol) { return; } var symbolId = ts.getSymbolId(symbol); if (visitedSymbols[symbolId]) { return; } visitedSymbols[symbolId] = symbol; if (!accept(symbol)) { return true; } var t = getTypeOfSymbol(symbol); visitType(t); // Should handle members on classes and such if (symbol.flags & 1952 /* HasExports */) { symbol.exports.forEach(visitSymbol); } ts.forEach(symbol.declarations, function (d) { // Type queries are too far resolved when we just visit the symbol's type // (their type resolved directly to the member deeply referenced) // So to get the intervening symbols, we need to check if there's a type // query node on any of the symbol's declarations and get symbols there if (d.type && d.type.kind === 163 /* TypeQuery */) { var query = d.type; var entity = getResolvedSymbol(getFirstIdentifier(query.exprName)); visitSymbol(entity); } }); } } } ts.createGetSymbolWalker = createGetSymbolWalker; })(ts || (ts = {})); /// /// /// /* @internal */ var ts; (function (ts) { var ambientModuleSymbolRegex = /^".+"$/; var nextSymbolId = 1; var nextNodeId = 1; var nextMergeId = 1; var nextFlowId = 1; function getNodeId(node) { if (!node.id) { node.id = nextNodeId; nextNodeId++; } return node.id; } ts.getNodeId = getNodeId; function getSymbolId(symbol) { if (!symbol.id) { symbol.id = nextSymbolId; nextSymbolId++; } return symbol.id; } ts.getSymbolId = getSymbolId; function isInstantiatedModule(node, preserveConstEnums) { var moduleState = ts.getModuleInstanceState(node); return moduleState === 1 /* Instantiated */ || (preserveConstEnums && moduleState === 2 /* ConstEnumOnly */); } ts.isInstantiatedModule = isInstantiatedModule; function createTypeChecker(host, produceDiagnostics) { // Cancellation that controls whether or not we can cancel in the middle of type checking. // In general cancelling is *not* safe for the type checker. We might be in the middle of // computing something, and we will leave our internals in an inconsistent state. Callers // who set the cancellation token should catch if a cancellation exception occurs, and // should throw away and create a new TypeChecker. // // Currently we only support setting the cancellation token when getting diagnostics. This // is because diagnostics can be quite expensive, and we want to allow hosts to bail out if // they no longer need the information (for example, if the user started editing again). var cancellationToken; var requestedExternalEmitHelpers; var externalHelpersModule; // tslint:disable variable-name var Symbol = ts.objectAllocator.getSymbolConstructor(); var Type = ts.objectAllocator.getTypeConstructor(); var Signature = ts.objectAllocator.getSignatureConstructor(); // tslint:enable variable-name var typeCount = 0; var symbolCount = 0; var enumCount = 0; var symbolInstantiationDepth = 0; var emptySymbols = ts.createSymbolTable(); var identityMapper = ts.identity; var compilerOptions = host.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var modulekind = ts.getEmitModuleKind(compilerOptions); var noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters; var allowSyntheticDefaultImports = ts.getAllowSyntheticDefaultImports(compilerOptions); var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks"); var strictFunctionTypes = ts.getStrictOptionValue(compilerOptions, "strictFunctionTypes"); var strictPropertyInitialization = ts.getStrictOptionValue(compilerOptions, "strictPropertyInitialization"); var noImplicitAny = ts.getStrictOptionValue(compilerOptions, "noImplicitAny"); var noImplicitThis = ts.getStrictOptionValue(compilerOptions, "noImplicitThis"); var emitResolver = createResolver(); var nodeBuilder = createNodeBuilder(); var undefinedSymbol = createSymbol(4 /* Property */, "undefined"); undefinedSymbol.declarations = []; var argumentsSymbol = createSymbol(4 /* Property */, "arguments"); /** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */ var apparentArgumentCount; // for public members that accept a Node or one of its subtypes, we must guard against // synthetic nodes created during transformations by calling `getParseTreeNode`. // for most of these, we perform the guard only on `checker` to avoid any possible // extra cost of calling `getParseTreeNode` when calling these functions from inside the // checker. var checker = { getNodeCount: function () { return ts.sum(host.getSourceFiles(), "nodeCount"); }, getIdentifierCount: function () { return ts.sum(host.getSourceFiles(), "identifierCount"); }, getSymbolCount: function () { return ts.sum(host.getSourceFiles(), "symbolCount") + symbolCount; }, getTypeCount: function () { return typeCount; }, isUndefinedSymbol: function (symbol) { return symbol === undefinedSymbol; }, isArgumentsSymbol: function (symbol) { return symbol === argumentsSymbol; }, isUnknownSymbol: function (symbol) { return symbol === unknownSymbol; }, getMergedSymbol: getMergedSymbol, getDiagnostics: getDiagnostics, getGlobalDiagnostics: getGlobalDiagnostics, getTypeOfSymbolAtLocation: function (symbol, location) { location = ts.getParseTreeNode(location); return location ? getTypeOfSymbolAtLocation(symbol, location) : unknownType; }, getSymbolsOfParameterPropertyDeclaration: function (parameter, parameterName) { parameter = ts.getParseTreeNode(parameter, ts.isParameter); ts.Debug.assert(parameter !== undefined, "Cannot get symbols of a synthetic parameter that cannot be resolved to a parse-tree node."); return getSymbolsOfParameterPropertyDeclaration(parameter, ts.escapeLeadingUnderscores(parameterName)); }, getDeclaredTypeOfSymbol: getDeclaredTypeOfSymbol, getPropertiesOfType: getPropertiesOfType, getPropertyOfType: function (type, name) { return getPropertyOfType(type, ts.escapeLeadingUnderscores(name)); }, getIndexInfoOfType: getIndexInfoOfType, getSignaturesOfType: getSignaturesOfType, getIndexTypeOfType: getIndexTypeOfType, getBaseTypes: getBaseTypes, getBaseTypeOfLiteralType: getBaseTypeOfLiteralType, getWidenedType: getWidenedType, getTypeFromTypeNode: function (node) { node = ts.getParseTreeNode(node, ts.isTypeNode); return node ? getTypeFromTypeNode(node) : unknownType; }, getParameterType: getTypeAtPosition, getReturnTypeOfSignature: getReturnTypeOfSignature, getNullableType: getNullableType, getNonNullableType: getNonNullableType, typeToTypeNode: nodeBuilder.typeToTypeNode, indexInfoToIndexSignatureDeclaration: nodeBuilder.indexInfoToIndexSignatureDeclaration, signatureToSignatureDeclaration: nodeBuilder.signatureToSignatureDeclaration, getSymbolsInScope: function (location, meaning) { location = ts.getParseTreeNode(location); return location ? getSymbolsInScope(location, meaning) : []; }, getSymbolAtLocation: function (node) { node = ts.getParseTreeNode(node); return node ? getSymbolAtLocation(node) : undefined; }, getShorthandAssignmentValueSymbol: function (node) { node = ts.getParseTreeNode(node); return node ? getShorthandAssignmentValueSymbol(node) : undefined; }, getExportSpecifierLocalTargetSymbol: function (node) { node = ts.getParseTreeNode(node, ts.isExportSpecifier); return node ? getExportSpecifierLocalTargetSymbol(node) : undefined; }, getExportSymbolOfSymbol: function (symbol) { return getMergedSymbol(symbol.exportSymbol || symbol); }, getTypeAtLocation: function (node) { node = ts.getParseTreeNode(node); return node ? getTypeOfNode(node) : unknownType; }, getPropertySymbolOfDestructuringAssignment: function (location) { location = ts.getParseTreeNode(location, ts.isIdentifier); return location ? getPropertySymbolOfDestructuringAssignment(location) : undefined; }, signatureToString: function (signature, enclosingDeclaration, flags, kind) { return signatureToString(signature, ts.getParseTreeNode(enclosingDeclaration), flags, kind); }, typeToString: function (type, enclosingDeclaration, flags) { return typeToString(type, ts.getParseTreeNode(enclosingDeclaration), flags); }, getSymbolDisplayBuilder: getSymbolDisplayBuilder, symbolToString: function (symbol, enclosingDeclaration, meaning) { return symbolToString(symbol, ts.getParseTreeNode(enclosingDeclaration), meaning); }, getAugmentedPropertiesOfType: getAugmentedPropertiesOfType, getRootSymbols: getRootSymbols, getContextualType: function (node) { node = ts.getParseTreeNode(node, ts.isExpression); return node ? getContextualType(node) : undefined; }, getFullyQualifiedName: getFullyQualifiedName, getResolvedSignature: function (node, candidatesOutArray, theArgumentCount) { node = ts.getParseTreeNode(node, ts.isCallLikeExpression); apparentArgumentCount = theArgumentCount; var res = node ? getResolvedSignature(node, candidatesOutArray) : undefined; apparentArgumentCount = undefined; return res; }, getConstantValue: function (node) { node = ts.getParseTreeNode(node, canHaveConstantValue); return node ? getConstantValue(node) : undefined; }, isValidPropertyAccess: function (node, propertyName) { node = ts.getParseTreeNode(node, ts.isPropertyAccessOrQualifiedName); return node ? isValidPropertyAccess(node, ts.escapeLeadingUnderscores(propertyName)) : false; }, getSignatureFromDeclaration: function (declaration) { declaration = ts.getParseTreeNode(declaration, ts.isFunctionLike); return declaration ? getSignatureFromDeclaration(declaration) : undefined; }, isImplementationOfOverload: function (node) { var parsed = ts.getParseTreeNode(node, ts.isFunctionLike); return parsed ? isImplementationOfOverload(parsed) : undefined; }, getImmediateAliasedSymbol: function (symbol) { ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here."); var links = getSymbolLinks(symbol); if (!links.immediateTarget) { var node = getDeclarationOfAliasSymbol(symbol); ts.Debug.assert(!!node); links.immediateTarget = getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true); } return links.immediateTarget; }, getAliasedSymbol: resolveAlias, getEmitResolver: getEmitResolver, getExportsOfModule: getExportsOfModuleAsArray, getExportsAndPropertiesOfModule: getExportsAndPropertiesOfModule, getSymbolWalker: ts.createGetSymbolWalker(getRestTypeOfSignature, getReturnTypeOfSignature, getBaseTypes, resolveStructuredTypeMembers, getTypeOfSymbol, getResolvedSymbol, getIndexTypeOfStructuredType, getConstraintFromTypeParameter, getFirstIdentifier), getAmbientModules: getAmbientModules, getAllAttributesTypeFromJsxOpeningLikeElement: function (node) { node = ts.getParseTreeNode(node, ts.isJsxOpeningLikeElement); return node ? getAllAttributesTypeFromJsxOpeningLikeElement(node) : undefined; }, getJsxIntrinsicTagNames: getJsxIntrinsicTagNames, isOptionalParameter: function (node) { node = ts.getParseTreeNode(node, ts.isParameter); return node ? isOptionalParameter(node) : false; }, tryGetMemberInModuleExports: function (name, symbol) { return tryGetMemberInModuleExports(ts.escapeLeadingUnderscores(name), symbol); }, tryGetMemberInModuleExportsAndProperties: function (name, symbol) { return tryGetMemberInModuleExportsAndProperties(ts.escapeLeadingUnderscores(name), symbol); }, tryFindAmbientModuleWithoutAugmentations: function (moduleName) { // we deliberately exclude augmentations // since we are only interested in declarations of the module itself return tryFindAmbientModule(moduleName, /*withAugmentations*/ false); }, getApparentType: getApparentType, getUnionType: getUnionType, createAnonymousType: createAnonymousType, createSignature: createSignature, createSymbol: createSymbol, createIndexInfo: createIndexInfo, getAnyType: function () { return anyType; }, getStringType: function () { return stringType; }, getNumberType: function () { return numberType; }, createPromiseType: createPromiseType, createArrayType: createArrayType, getBooleanType: function () { return booleanType; }, getVoidType: function () { return voidType; }, getUndefinedType: function () { return undefinedType; }, getNullType: function () { return nullType; }, getESSymbolType: function () { return esSymbolType; }, getNeverType: function () { return neverType; }, isSymbolAccessible: isSymbolAccessible, isArrayLikeType: isArrayLikeType, getAllPossiblePropertiesOfTypes: getAllPossiblePropertiesOfTypes, getSuggestionForNonexistentProperty: function (node, type) { return getSuggestionForNonexistentProperty(node, type); }, getSuggestionForNonexistentSymbol: function (location, name, meaning) { return getSuggestionForNonexistentSymbol(location, ts.escapeLeadingUnderscores(name), meaning); }, getBaseConstraintOfType: getBaseConstraintOfType, getDefaultFromTypeParameter: function (type) { return type && type.flags & 32768 /* TypeParameter */ ? getDefaultFromTypeParameter(type) : undefined; }, resolveName: function (name, location, meaning) { return resolveName(location, ts.escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); }, getJsxNamespace: function () { return ts.unescapeLeadingUnderscores(getJsxNamespace()); }, getAccessibleSymbolChain: getAccessibleSymbolChain, }; var tupleTypes = []; var unionTypes = ts.createMap(); var intersectionTypes = ts.createMap(); var literalTypes = ts.createMap(); var indexedAccessTypes = ts.createMap(); var evolvingArrayTypes = []; var undefinedProperties = ts.createMap(); var unknownSymbol = createSymbol(4 /* Property */, "unknown"); var resolvingSymbol = createSymbol(0, "__resolving__" /* Resolving */); var anyType = createIntrinsicType(1 /* Any */, "any"); var autoType = createIntrinsicType(1 /* Any */, "any"); var unknownType = createIntrinsicType(1 /* Any */, "unknown"); var undefinedType = createIntrinsicType(4096 /* Undefined */, "undefined"); var undefinedWideningType = strictNullChecks ? undefinedType : createIntrinsicType(4096 /* Undefined */ | 4194304 /* ContainsWideningType */, "undefined"); var nullType = createIntrinsicType(8192 /* Null */, "null"); var nullWideningType = strictNullChecks ? nullType : createIntrinsicType(8192 /* Null */ | 4194304 /* ContainsWideningType */, "null"); var stringType = createIntrinsicType(2 /* String */, "string"); var numberType = createIntrinsicType(4 /* Number */, "number"); var trueType = createIntrinsicType(128 /* BooleanLiteral */, "true"); var falseType = createIntrinsicType(128 /* BooleanLiteral */, "false"); var booleanType = createBooleanType([trueType, falseType]); var esSymbolType = createIntrinsicType(512 /* ESSymbol */, "symbol"); var voidType = createIntrinsicType(2048 /* Void */, "void"); var neverType = createIntrinsicType(16384 /* Never */, "never"); var silentNeverType = createIntrinsicType(16384 /* Never */, "never"); var implicitNeverType = createIntrinsicType(16384 /* Never */, "never"); var nonPrimitiveType = createIntrinsicType(33554432 /* NonPrimitive */, "object"); var emptyObjectType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); var emptyTypeLiteralSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */); emptyTypeLiteralSymbol.members = ts.createSymbolTable(); var emptyTypeLiteralType = createAnonymousType(emptyTypeLiteralSymbol, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); var emptyGenericType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); emptyGenericType.instantiations = ts.createMap(); var anyFunctionType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); // The anyFunctionType contains the anyFunctionType by definition. The flag is further propagated // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. anyFunctionType.flags |= 16777216 /* ContainsAnyFunctionType */; var noConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); var circularConstraintType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); var resolvingDefaultType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); var markerSuperType = createType(32768 /* TypeParameter */); var markerSubType = createType(32768 /* TypeParameter */); markerSubType.constraint = markerSuperType; var markerOtherType = createType(32768 /* TypeParameter */); var anySignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); var unknownSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); var resolvingSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); var silentNeverSignature = createSignature(undefined, undefined, undefined, ts.emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); var enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); var jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); var globals = ts.createSymbolTable(); var ambientModulesCache; /** * List of every ambient module with a "*" wildcard. * Unlike other ambient modules, these can't be stored in `globals` because symbol tables only deal with exact matches. * This is only used if there is no exact match. */ var patternAmbientModules; var globalObjectType; var globalFunctionType; var globalArrayType; var globalReadonlyArrayType; var globalStringType; var globalNumberType; var globalBooleanType; var globalRegExpType; var globalThisType; var anyArrayType; var autoArrayType; var anyReadonlyArrayType; // The library files are only loaded when the feature is used. // This allows users to just specify library files they want to used through --lib // and they will not get an error from not having unrelated library files var deferredGlobalESSymbolConstructorSymbol; var deferredGlobalESSymbolType; var deferredGlobalTypedPropertyDescriptorType; var deferredGlobalPromiseType; var deferredGlobalPromiseConstructorSymbol; var deferredGlobalPromiseConstructorLikeType; var deferredGlobalIterableType; var deferredGlobalIteratorType; var deferredGlobalIterableIteratorType; var deferredGlobalAsyncIterableType; var deferredGlobalAsyncIteratorType; var deferredGlobalAsyncIterableIteratorType; var deferredGlobalTemplateStringsArrayType; var deferredJsxElementClassType; var deferredJsxElementType; var deferredJsxStatelessElementType; var deferredNodes; var deferredUnusedIdentifierNodes; var flowLoopStart = 0; var flowLoopCount = 0; var sharedFlowCount = 0; var flowAnalysisDisabled = false; var emptyStringType = getLiteralType(""); var zeroType = getLiteralType(0); var resolutionTargets = []; var resolutionResults = []; var resolutionPropertyNames = []; var suggestionCount = 0; var maximumSuggestionCount = 10; var mergedSymbols = []; var symbolLinks = []; var nodeLinks = []; var flowLoopCaches = []; var flowLoopNodes = []; var flowLoopKeys = []; var flowLoopTypes = []; var sharedFlowNodes = []; var sharedFlowTypes = []; var potentialThisCollisions = []; var potentialNewTargetCollisions = []; var awaitedTypeStack = []; var diagnostics = ts.createDiagnosticCollection(); var TypeFacts; (function (TypeFacts) { TypeFacts[TypeFacts["None"] = 0] = "None"; TypeFacts[TypeFacts["TypeofEQString"] = 1] = "TypeofEQString"; TypeFacts[TypeFacts["TypeofEQNumber"] = 2] = "TypeofEQNumber"; TypeFacts[TypeFacts["TypeofEQBoolean"] = 4] = "TypeofEQBoolean"; TypeFacts[TypeFacts["TypeofEQSymbol"] = 8] = "TypeofEQSymbol"; TypeFacts[TypeFacts["TypeofEQObject"] = 16] = "TypeofEQObject"; TypeFacts[TypeFacts["TypeofEQFunction"] = 32] = "TypeofEQFunction"; TypeFacts[TypeFacts["TypeofEQHostObject"] = 64] = "TypeofEQHostObject"; TypeFacts[TypeFacts["TypeofNEString"] = 128] = "TypeofNEString"; TypeFacts[TypeFacts["TypeofNENumber"] = 256] = "TypeofNENumber"; TypeFacts[TypeFacts["TypeofNEBoolean"] = 512] = "TypeofNEBoolean"; TypeFacts[TypeFacts["TypeofNESymbol"] = 1024] = "TypeofNESymbol"; TypeFacts[TypeFacts["TypeofNEObject"] = 2048] = "TypeofNEObject"; TypeFacts[TypeFacts["TypeofNEFunction"] = 4096] = "TypeofNEFunction"; TypeFacts[TypeFacts["TypeofNEHostObject"] = 8192] = "TypeofNEHostObject"; TypeFacts[TypeFacts["EQUndefined"] = 16384] = "EQUndefined"; TypeFacts[TypeFacts["EQNull"] = 32768] = "EQNull"; TypeFacts[TypeFacts["EQUndefinedOrNull"] = 65536] = "EQUndefinedOrNull"; TypeFacts[TypeFacts["NEUndefined"] = 131072] = "NEUndefined"; TypeFacts[TypeFacts["NENull"] = 262144] = "NENull"; TypeFacts[TypeFacts["NEUndefinedOrNull"] = 524288] = "NEUndefinedOrNull"; TypeFacts[TypeFacts["Truthy"] = 1048576] = "Truthy"; TypeFacts[TypeFacts["Falsy"] = 2097152] = "Falsy"; TypeFacts[TypeFacts["Discriminatable"] = 4194304] = "Discriminatable"; TypeFacts[TypeFacts["All"] = 8388607] = "All"; // The following members encode facts about particular kinds of types for use in the getTypeFacts function. // The presence of a particular fact means that the given test is true for some (and possibly all) values // of that kind of type. TypeFacts[TypeFacts["BaseStringStrictFacts"] = 933633] = "BaseStringStrictFacts"; TypeFacts[TypeFacts["BaseStringFacts"] = 3145473] = "BaseStringFacts"; TypeFacts[TypeFacts["StringStrictFacts"] = 4079361] = "StringStrictFacts"; TypeFacts[TypeFacts["StringFacts"] = 4194049] = "StringFacts"; TypeFacts[TypeFacts["EmptyStringStrictFacts"] = 3030785] = "EmptyStringStrictFacts"; TypeFacts[TypeFacts["EmptyStringFacts"] = 3145473] = "EmptyStringFacts"; TypeFacts[TypeFacts["NonEmptyStringStrictFacts"] = 1982209] = "NonEmptyStringStrictFacts"; TypeFacts[TypeFacts["NonEmptyStringFacts"] = 4194049] = "NonEmptyStringFacts"; TypeFacts[TypeFacts["BaseNumberStrictFacts"] = 933506] = "BaseNumberStrictFacts"; TypeFacts[TypeFacts["BaseNumberFacts"] = 3145346] = "BaseNumberFacts"; TypeFacts[TypeFacts["NumberStrictFacts"] = 4079234] = "NumberStrictFacts"; TypeFacts[TypeFacts["NumberFacts"] = 4193922] = "NumberFacts"; TypeFacts[TypeFacts["ZeroStrictFacts"] = 3030658] = "ZeroStrictFacts"; TypeFacts[TypeFacts["ZeroFacts"] = 3145346] = "ZeroFacts"; TypeFacts[TypeFacts["NonZeroStrictFacts"] = 1982082] = "NonZeroStrictFacts"; TypeFacts[TypeFacts["NonZeroFacts"] = 4193922] = "NonZeroFacts"; TypeFacts[TypeFacts["BaseBooleanStrictFacts"] = 933252] = "BaseBooleanStrictFacts"; TypeFacts[TypeFacts["BaseBooleanFacts"] = 3145092] = "BaseBooleanFacts"; TypeFacts[TypeFacts["BooleanStrictFacts"] = 4078980] = "BooleanStrictFacts"; TypeFacts[TypeFacts["BooleanFacts"] = 4193668] = "BooleanFacts"; TypeFacts[TypeFacts["FalseStrictFacts"] = 3030404] = "FalseStrictFacts"; TypeFacts[TypeFacts["FalseFacts"] = 3145092] = "FalseFacts"; TypeFacts[TypeFacts["TrueStrictFacts"] = 1981828] = "TrueStrictFacts"; TypeFacts[TypeFacts["TrueFacts"] = 4193668] = "TrueFacts"; TypeFacts[TypeFacts["SymbolStrictFacts"] = 1981320] = "SymbolStrictFacts"; TypeFacts[TypeFacts["SymbolFacts"] = 4193160] = "SymbolFacts"; TypeFacts[TypeFacts["ObjectStrictFacts"] = 6166480] = "ObjectStrictFacts"; TypeFacts[TypeFacts["ObjectFacts"] = 8378320] = "ObjectFacts"; TypeFacts[TypeFacts["FunctionStrictFacts"] = 6164448] = "FunctionStrictFacts"; TypeFacts[TypeFacts["FunctionFacts"] = 8376288] = "FunctionFacts"; TypeFacts[TypeFacts["UndefinedFacts"] = 2457472] = "UndefinedFacts"; TypeFacts[TypeFacts["NullFacts"] = 2340752] = "NullFacts"; })(TypeFacts || (TypeFacts = {})); var typeofEQFacts = ts.createMapFromTemplate({ string: 1 /* TypeofEQString */, number: 2 /* TypeofEQNumber */, boolean: 4 /* TypeofEQBoolean */, symbol: 8 /* TypeofEQSymbol */, undefined: 16384 /* EQUndefined */, object: 16 /* TypeofEQObject */, function: 32 /* TypeofEQFunction */ }); var typeofNEFacts = ts.createMapFromTemplate({ string: 128 /* TypeofNEString */, number: 256 /* TypeofNENumber */, boolean: 512 /* TypeofNEBoolean */, symbol: 1024 /* TypeofNESymbol */, undefined: 131072 /* NEUndefined */, object: 2048 /* TypeofNEObject */, function: 4096 /* TypeofNEFunction */ }); var typeofTypesByName = ts.createMapFromTemplate({ string: stringType, number: numberType, boolean: booleanType, symbol: esSymbolType, undefined: undefinedType }); var typeofType = createTypeofType(); var _jsxNamespace; var _jsxFactoryEntity; var _jsxElementPropertiesName; var _hasComputedJsxElementPropertiesName = false; var _jsxElementChildrenPropertyName; var _hasComputedJsxElementChildrenPropertyName = false; /** Things we lazy load from the JSX namespace */ var jsxTypes = ts.createUnderscoreEscapedMap(); var subtypeRelation = ts.createMap(); var assignableRelation = ts.createMap(); var comparableRelation = ts.createMap(); var identityRelation = ts.createMap(); var enumRelation = ts.createMap(); // This is for caching the result of getSymbolDisplayBuilder. Do not access directly. var _displayBuilder; var TypeSystemPropertyName; (function (TypeSystemPropertyName) { TypeSystemPropertyName[TypeSystemPropertyName["Type"] = 0] = "Type"; TypeSystemPropertyName[TypeSystemPropertyName["ResolvedBaseConstructorType"] = 1] = "ResolvedBaseConstructorType"; TypeSystemPropertyName[TypeSystemPropertyName["DeclaredType"] = 2] = "DeclaredType"; TypeSystemPropertyName[TypeSystemPropertyName["ResolvedReturnType"] = 3] = "ResolvedReturnType"; })(TypeSystemPropertyName || (TypeSystemPropertyName = {})); var CheckMode; (function (CheckMode) { CheckMode[CheckMode["Normal"] = 0] = "Normal"; CheckMode[CheckMode["SkipContextSensitive"] = 1] = "SkipContextSensitive"; CheckMode[CheckMode["Inferential"] = 2] = "Inferential"; })(CheckMode || (CheckMode = {})); var CallbackCheck; (function (CallbackCheck) { CallbackCheck[CallbackCheck["None"] = 0] = "None"; CallbackCheck[CallbackCheck["Bivariant"] = 1] = "Bivariant"; CallbackCheck[CallbackCheck["Strict"] = 2] = "Strict"; })(CallbackCheck || (CallbackCheck = {})); var MappedTypeModifiers; (function (MappedTypeModifiers) { MappedTypeModifiers[MappedTypeModifiers["Readonly"] = 1] = "Readonly"; MappedTypeModifiers[MappedTypeModifiers["Optional"] = 2] = "Optional"; })(MappedTypeModifiers || (MappedTypeModifiers = {})); var ExpandingFlags; (function (ExpandingFlags) { ExpandingFlags[ExpandingFlags["None"] = 0] = "None"; ExpandingFlags[ExpandingFlags["Source"] = 1] = "Source"; ExpandingFlags[ExpandingFlags["Target"] = 2] = "Target"; ExpandingFlags[ExpandingFlags["Both"] = 3] = "Both"; })(ExpandingFlags || (ExpandingFlags = {})); var MembersOrExportsResolutionKind; (function (MembersOrExportsResolutionKind) { MembersOrExportsResolutionKind["resolvedExports"] = "resolvedExports"; MembersOrExportsResolutionKind["resolvedMembers"] = "resolvedMembers"; })(MembersOrExportsResolutionKind || (MembersOrExportsResolutionKind = {})); var builtinGlobals = ts.createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); var isNotOverloadAndNotAccessor = ts.and(isNotOverload, isNotAccessor); initializeTypeChecker(); return checker; function getJsxNamespace() { if (!_jsxNamespace) { _jsxNamespace = "React"; if (compilerOptions.jsxFactory) { _jsxFactoryEntity = ts.parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion); if (_jsxFactoryEntity) { _jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText; } } else if (compilerOptions.reactNamespace) { _jsxNamespace = ts.escapeLeadingUnderscores(compilerOptions.reactNamespace); } } return _jsxNamespace; } function getEmitResolver(sourceFile, cancellationToken) { // Ensure we have all the type information in place for this file so that all the // emitter questions of this resolver will return the right information. getDiagnostics(sourceFile, cancellationToken); return emitResolver; } function error(location, message, arg0, arg1, arg2, arg3) { var diagnostic = location ? ts.createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : ts.createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); diagnostics.add(diagnostic); } function createSymbol(flags, name, checkFlags) { symbolCount++; var symbol = (new Symbol(flags | 33554432 /* Transient */, name)); symbol.checkFlags = checkFlags || 0; return symbol; } function isTransientSymbol(symbol) { return (symbol.flags & 33554432 /* Transient */) !== 0; } function getExcludedSymbolFlags(flags) { var result = 0; if (flags & 2 /* BlockScopedVariable */) result |= 107455 /* BlockScopedVariableExcludes */; if (flags & 1 /* FunctionScopedVariable */) result |= 107454 /* FunctionScopedVariableExcludes */; if (flags & 4 /* Property */) result |= 0 /* PropertyExcludes */; if (flags & 8 /* EnumMember */) result |= 900095 /* EnumMemberExcludes */; if (flags & 16 /* Function */) result |= 106927 /* FunctionExcludes */; if (flags & 32 /* Class */) result |= 899519 /* ClassExcludes */; if (flags & 64 /* Interface */) result |= 792968 /* InterfaceExcludes */; if (flags & 256 /* RegularEnum */) result |= 899327 /* RegularEnumExcludes */; if (flags & 128 /* ConstEnum */) result |= 899967 /* ConstEnumExcludes */; if (flags & 512 /* ValueModule */) result |= 106639 /* ValueModuleExcludes */; if (flags & 8192 /* Method */) result |= 99263 /* MethodExcludes */; if (flags & 32768 /* GetAccessor */) result |= 41919 /* GetAccessorExcludes */; if (flags & 65536 /* SetAccessor */) result |= 74687 /* SetAccessorExcludes */; if (flags & 262144 /* TypeParameter */) result |= 530920 /* TypeParameterExcludes */; if (flags & 524288 /* TypeAlias */) result |= 793064 /* TypeAliasExcludes */; if (flags & 2097152 /* Alias */) result |= 2097152 /* AliasExcludes */; return result; } function recordMergedSymbol(target, source) { if (!source.mergeId) { source.mergeId = nextMergeId; nextMergeId++; } mergedSymbols[source.mergeId] = target; } function cloneSymbol(symbol) { var result = createSymbol(symbol.flags, symbol.escapedName); result.declarations = symbol.declarations ? symbol.declarations.slice() : []; result.parent = symbol.parent; if (symbol.valueDeclaration) result.valueDeclaration = symbol.valueDeclaration; if (symbol.constEnumOnlyModule) result.constEnumOnlyModule = true; if (symbol.members) result.members = ts.cloneMap(symbol.members); if (symbol.exports) result.exports = ts.cloneMap(symbol.exports); recordMergedSymbol(result, symbol); return result; } function mergeSymbol(target, source) { if (!(target.flags & getExcludedSymbolFlags(source.flags)) || source.flags & 67108864 /* JSContainer */ || target.flags & 67108864 /* JSContainer */) { // Javascript static-property-assignment declarations always merge, even though they are also values 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 === 234 /* ModuleDeclaration */ && source.valueDeclaration.kind !== 234 /* ModuleDeclaration */))) { // other kinds of value declarations take precedence over modules target.valueDeclaration = source.valueDeclaration; } ts.addRange(target.declarations, source.declarations); if (source.members) { if (!target.members) target.members = ts.createSymbolTable(); mergeSymbolTable(target.members, source.members); } if (source.exports) { if (!target.exports) target.exports = ts.createSymbolTable(); mergeSymbolTable(target.exports, source.exports); } recordMergedSymbol(target, source); } else if (target.flags & 1024 /* NamespaceModule */) { error(ts.getNameOfDeclaration(source.declarations[0]), ts.Diagnostics.Cannot_augment_module_0_with_value_exports_because_it_resolves_to_a_non_module_entity, symbolToString(target)); } else { var message_2 = target.flags & 2 /* BlockScopedVariable */ || source.flags & 2 /* BlockScopedVariable */ ? ts.Diagnostics.Cannot_redeclare_block_scoped_variable_0 : ts.Diagnostics.Duplicate_identifier_0; ts.forEach(source.declarations, function (node) { error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source)); }); ts.forEach(target.declarations, function (node) { error(ts.getNameOfDeclaration(node) || node, message_2, symbolToString(source)); }); } } function combineSymbolTables(first, second) { if (!first || first.size === 0) return second; if (!second || second.size === 0) return first; var combined = ts.createSymbolTable(); mergeSymbolTable(combined, first); mergeSymbolTable(combined, second); return combined; } function mergeSymbolTable(target, source) { source.forEach(function (sourceSymbol, id) { var targetSymbol = target.get(id); if (!targetSymbol) { target.set(id, sourceSymbol); } else { if (!(targetSymbol.flags & 33554432 /* Transient */)) { targetSymbol = cloneSymbol(targetSymbol); target.set(id, targetSymbol); } mergeSymbol(targetSymbol, sourceSymbol); } }); } function mergeModuleAugmentation(moduleName) { var moduleAugmentation = moduleName.parent; if (moduleAugmentation.symbol.declarations[0] !== moduleAugmentation) { // this is a combined symbol for multiple augmentations within the same file. // its symbol already has accumulated information for all declarations // so we need to add it just once - do the work only for first declaration ts.Debug.assert(moduleAugmentation.symbol.declarations.length > 1); return; } if (ts.isGlobalScopeAugmentation(moduleAugmentation)) { mergeSymbolTable(globals, moduleAugmentation.symbol.exports); } else { // find a module that about to be augmented // do not validate names of augmentations that are defined in ambient context var moduleNotFoundError = !(moduleName.parent.parent.flags & 2097152 /* Ambient */) ? ts.Diagnostics.Invalid_module_name_in_augmentation_module_0_cannot_be_found : undefined; var mainModule = resolveExternalModuleNameWorker(moduleName, moduleName, moduleNotFoundError, /*isForAugmentation*/ true); if (!mainModule) { return; } // obtain item referenced by 'export=' mainModule = resolveExternalModuleSymbol(mainModule); if (mainModule.flags & 1920 /* Namespace */) { // if module symbol has already been merged - it is safe to use it. // otherwise clone it mainModule = mainModule.flags & 33554432 /* Transient */ ? mainModule : cloneSymbol(mainModule); mergeSymbol(mainModule, moduleAugmentation.symbol); } else { // moduleName will be a StringLiteral since this is not `declare global`. error(moduleName, ts.Diagnostics.Cannot_augment_module_0_because_it_resolves_to_a_non_module_entity, moduleName.text); } } } function addToSymbolTable(target, source, message) { source.forEach(function (sourceSymbol, id) { var targetSymbol = target.get(id); if (targetSymbol) { // Error on redeclarations ts.forEach(targetSymbol.declarations, addDeclarationDiagnostic(ts.unescapeLeadingUnderscores(id), message)); } else { target.set(id, sourceSymbol); } }); function addDeclarationDiagnostic(id, message) { return function (declaration) { return diagnostics.add(ts.createDiagnosticForNode(declaration, message, id)); }; } } function getSymbolLinks(symbol) { if (symbol.flags & 33554432 /* Transient */) return symbol; var id = getSymbolId(symbol); return symbolLinks[id] || (symbolLinks[id] = {}); } function getNodeLinks(node) { var nodeId = getNodeId(node); return nodeLinks[nodeId] || (nodeLinks[nodeId] = { flags: 0 }); } function isGlobalSourceFile(node) { return node.kind === 269 /* SourceFile */ && !ts.isExternalOrCommonJsModule(node); } function getSymbol(symbols, name, meaning) { if (meaning) { var symbol = symbols.get(name); if (symbol) { ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here."); if (symbol.flags & meaning) { return symbol; } if (symbol.flags & 2097152 /* Alias */) { var target = resolveAlias(symbol); // Unknown symbol means an error occurred in alias resolution, treat it as positive answer to avoid cascading errors if (target === unknownSymbol || target.flags & meaning) { return symbol; } } } } // return undefined if we can't find a symbol. } /** * Get symbols that represent parameter-property-declaration as parameter and as property declaration * @param parameter a parameterDeclaration node * @param parameterName a name of the parameter to get the symbols for. * @return a tuple of two symbols */ function getSymbolsOfParameterPropertyDeclaration(parameter, parameterName) { var constructorDeclaration = parameter.parent; var classDeclaration = parameter.parent.parent; var parameterSymbol = getSymbol(constructorDeclaration.locals, parameterName, 107455 /* Value */); var propertySymbol = getSymbol(getMembersOfSymbol(classDeclaration.symbol), parameterName, 107455 /* Value */); if (parameterSymbol && propertySymbol) { return [parameterSymbol, propertySymbol]; } ts.Debug.fail("There should exist two symbols, one as property declaration and one as parameter declaration"); } function isBlockScopedNameDeclaredBeforeUse(declaration, usage) { var declarationFile = ts.getSourceFileOfNode(declaration); var useFile = ts.getSourceFileOfNode(usage); if (declarationFile !== useFile) { if ((modulekind && (declarationFile.externalModuleIndicator || useFile.externalModuleIndicator)) || (!compilerOptions.outFile && !compilerOptions.out) || isInTypeQuery(usage) || declaration.flags & 2097152 /* Ambient */) { // nodes are in different files and order cannot be determined return true; } // declaration is after usage // can be legal if usage is deferred (i.e. inside function or in initializer of instance property) if (isUsedInFunctionOrInstanceProperty(usage, declaration)) { return true; } var sourceFiles = host.getSourceFiles(); return ts.indexOf(sourceFiles, declarationFile) <= ts.indexOf(sourceFiles, useFile); } if (declaration.pos <= usage.pos) { // declaration is before usage if (declaration.kind === 177 /* BindingElement */) { // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2]) var errorBindingElement = ts.getAncestor(usage, 177 /* BindingElement */); if (errorBindingElement) { return ts.findAncestor(errorBindingElement, ts.isBindingElement) !== ts.findAncestor(declaration, ts.isBindingElement) || declaration.pos < errorBindingElement.pos; } // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a) return isBlockScopedNameDeclaredBeforeUse(ts.getAncestor(declaration, 227 /* VariableDeclaration */), usage); } else if (declaration.kind === 227 /* VariableDeclaration */) { // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a) return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage); } return true; } // declaration is after usage, but it can still be legal if usage is deferred: // 1. inside an export specifier // 2. inside a function // 3. inside an instance property initializer, a reference to a non-instance property // 4. inside a static property initializer, a reference to a static method in the same class // 5. inside a TS export= declaration (since we will move the export statement during emit to avoid TDZ) // or if usage is in a type context: // 1. inside a type query (typeof in type position) if (usage.parent.kind === 247 /* ExportSpecifier */ || (usage.parent.kind === 244 /* ExportAssignment */ && usage.parent.isExportEquals)) { // export specifiers do not use the variable, they only make it available for use return true; } // When resolving symbols for exports, the `usage` location passed in can be the export site directly if (usage.kind === 244 /* ExportAssignment */ && usage.isExportEquals) { return true; } var container = ts.getEnclosingBlockScopeContainer(declaration); return isInTypeQuery(usage) || isUsedInFunctionOrInstanceProperty(usage, declaration, container); function isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration, usage) { var container = ts.getEnclosingBlockScopeContainer(declaration); switch (declaration.parent.parent.kind) { case 209 /* VariableStatement */: case 215 /* ForStatement */: case 217 /* ForOfStatement */: // variable statement/for/for-of statement case, // use site should not be inside variable declaration (initializer of declaration or binding element) if (isSameScopeDescendentOf(usage, declaration, container)) { return true; } break; } // ForIn/ForOf case - use site should not be used in expression part return ts.isForInOrOfStatement(declaration.parent.parent) && isSameScopeDescendentOf(usage, declaration.parent.parent.expression, container); } function isUsedInFunctionOrInstanceProperty(usage, declaration, container) { return !!ts.findAncestor(usage, function (current) { if (current === container) { return "quit"; } if (ts.isFunctionLike(current)) { return true; } var initializerOfProperty = current.parent && current.parent.kind === 150 /* PropertyDeclaration */ && current.parent.initializer === current; if (initializerOfProperty) { if (ts.hasModifier(current.parent, 32 /* Static */)) { if (declaration.kind === 152 /* MethodDeclaration */) { return true; } } else { var isDeclarationInstanceProperty = declaration.kind === 150 /* PropertyDeclaration */ && !ts.hasModifier(declaration, 32 /* Static */); if (!isDeclarationInstanceProperty || ts.getContainingClass(usage) !== ts.getContainingClass(declaration)) { return true; } } } }); } } /** * Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and * the nameNotFoundMessage argument is not undefined. Returns the resolved symbol, or undefined if no symbol with * the given name can be found. * * @param isUse If true, this will count towards --noUnusedLocals / --noUnusedParameters. */ function resolveName(location, name, meaning, nameNotFoundMessage, nameArg, isUse, suggestedNameNotFoundMessage) { return resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, getSymbol, suggestedNameNotFoundMessage); } function resolveNameHelper(location, name, meaning, nameNotFoundMessage, nameArg, isUse, lookup, suggestedNameNotFoundMessage) { var originalLocation = location; // needed for did-you-mean error reporting, which gathers candidates starting from the original location var result; var lastLocation; var lastNonBlockLocation; var propertyWithInvalidInitializer; var errorLocation = location; var grandparent; var isInExternalModule = false; loop: while (location) { // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { if (result = lookup(location.locals, name, meaning)) { var useResult = true; if (ts.isFunctionLike(location) && lastLocation && lastLocation !== location.body) { // symbol lookup restrictions for function-like declarations // - Type parameters of a function are in scope in the entire function declaration, including the parameter // list and return type. However, local types are only in scope in the function body. // - parameters are only in the scope of function body // This restriction does not apply to JSDoc comment types because they are parented // at a higher level than type parameters would normally be if (meaning & result.flags & 793064 /* Type */ && lastLocation.kind !== 279 /* JSDocComment */) { useResult = result.flags & 262144 /* TypeParameter */ // type parameters are visible in parameter list, return type and type parameter list ? lastLocation === location.type || lastLocation.kind === 147 /* Parameter */ || lastLocation.kind === 146 /* TypeParameter */ // local types not visible outside the function body : false; } if (meaning & 107455 /* Value */ && result.flags & 1 /* FunctionScopedVariable */) { // parameters are visible only inside function body, parameter list and return type // technically for parameter list case here we might mix parameters and variables declared in function, // however it is detected separately when checking initializers of parameters // to make sure that they reference no variables declared after them. useResult = lastLocation.kind === 147 /* Parameter */ || (lastLocation === location.type && result.valueDeclaration.kind === 147 /* Parameter */); } } if (useResult) { break loop; } else { result = undefined; } } } switch (location.kind) { case 269 /* SourceFile */: if (!ts.isExternalOrCommonJsModule(location)) break; isInExternalModule = true; // falls through case 234 /* ModuleDeclaration */: var moduleExports = getSymbolOfNode(location).exports; if (location.kind === 269 /* SourceFile */ || ts.isAmbientModule(location)) { // It's an external module. First see if the module has an export default and if the local // name of that export default matches. if (result = moduleExports.get("default")) { var localSymbol = ts.getLocalSymbolForExportDefault(result); if (localSymbol && (result.flags & meaning) && localSymbol.escapedName === name) { break loop; } result = undefined; } // Because of module/namespace merging, a module's exports are in scope, // yet we never want to treat an export specifier as putting a member in scope. // Therefore, if the name we find is purely an export specifier, it is not actually considered in scope. // Two things to note about this: // 1. We have to check this without calling getSymbol. The problem with calling getSymbol // on an export specifier is that it might find the export specifier itself, and try to // resolve it as an alias. This will cause the checker to consider the export specifier // a circular alias reference when it might not be. // 2. We check === SymbolFlags.Alias in order to check that the symbol is *purely* // an alias. If we used &, we'd be throwing out symbols that have non alias aspects, // which is not the desired behavior. var moduleExport = moduleExports.get(name); if (moduleExport && moduleExport.flags === 2097152 /* Alias */ && ts.getDeclarationOfKind(moduleExport, 247 /* ExportSpecifier */)) { break; } } if (result = lookup(moduleExports, name, meaning & 2623475 /* ModuleMember */)) { break loop; } break; case 233 /* EnumDeclaration */: if (result = lookup(getSymbolOfNode(location).exports, name, meaning & 8 /* EnumMember */)) { break loop; } break; case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: // TypeScript 1.0 spec (April 2014): 8.4.1 // Initializer expressions for instance member variables are evaluated in the scope // of the class constructor body but are not permitted to reference parameters or // local variables of the constructor. This effectively means that entities from outer scopes // by the same name as a constructor parameter or local variable are inaccessible // in initializer expressions for instance member variables. if (ts.isClassLike(location.parent) && !ts.hasModifier(location, 32 /* Static */)) { var ctor = findConstructorDeclaration(location.parent); if (ctor && ctor.locals) { if (lookup(ctor.locals, name, meaning & 107455 /* Value */)) { // Remember the property node, it will be used later to report appropriate error propertyWithInvalidInitializer = location; } } } break; case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: if (result = lookup(getMembersOfSymbol(getSymbolOfNode(location)), name, meaning & 793064 /* Type */)) { if (!isTypeParameterSymbolDeclaredInContainer(result, location)) { // ignore type parameters not declared in this container result = undefined; break; } if (lastLocation && ts.hasModifier(lastLocation, 32 /* Static */)) { // TypeScript 1.0 spec (April 2014): 3.4.1 // The scope of a type parameter extends over the entire declaration with which the type // parameter list is associated, with the exception of static member declarations in classes. error(errorLocation, ts.Diagnostics.Static_members_cannot_reference_class_type_parameters); return undefined; } break loop; } if (location.kind === 200 /* ClassExpression */ && meaning & 32 /* Class */) { var className = location.name; if (className && name === className.escapedText) { result = location.symbol; break loop; } } break; case 202 /* ExpressionWithTypeArguments */: // The type parameters of a class are not in scope in the base class expression. if (lastLocation === location.expression && location.parent.token === 85 /* ExtendsKeyword */) { var container = location.parent.parent; if (ts.isClassLike(container) && (result = lookup(getSymbolOfNode(container).members, name, meaning & 793064 /* Type */))) { if (nameNotFoundMessage) { error(errorLocation, ts.Diagnostics.Base_class_expressions_cannot_reference_class_type_parameters); } return undefined; } } break; // It is not legal to reference a class's own type parameters from a computed property name that // belongs to the class. For example: // // function foo() { return '' } // class C { // <-- Class's own type parameter T // [foo()]() { } // <-- Reference to T from class's own computed property // } // case 145 /* ComputedPropertyName */: grandparent = location.parent.parent; if (ts.isClassLike(grandparent) || grandparent.kind === 231 /* InterfaceDeclaration */) { // A reference to this grandparent's type parameters would be an error if (result = lookup(getSymbolOfNode(grandparent).members, name, meaning & 793064 /* Type */)) { error(errorLocation, ts.Diagnostics.A_computed_property_name_cannot_reference_a_type_parameter_from_its_containing_type); return undefined; } } break; case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } break; case 187 /* FunctionExpression */: if (meaning & 3 /* Variable */ && name === "arguments") { result = argumentsSymbol; break loop; } if (meaning & 16 /* Function */) { var functionName = location.name; if (functionName && name === functionName.escapedText) { result = location.symbol; break loop; } } break; case 148 /* 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 === 147 /* Parameter */) { location = location.parent; } // // function y() {} // class C { // @y method(x, y) {} // <-- decorator y should be resolved at the class declaration, not the method. // } // if (location.parent && ts.isClassElement(location.parent)) { location = location.parent; } break; } if (location.kind !== 208 /* Block */) { lastNonBlockLocation = location; } lastLocation = location; location = location.parent; } // We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`. // If `result === lastLocation.symbol`, that means that we are somewhere inside `lastLocation` looking up a name, and resolving to `lastLocation` itself. // That means that this is a self-reference of `lastLocation`, and shouldn't count this when considering whether `lastLocation` is used. if (isUse && result && nameNotFoundMessage && noUnusedIdentifiers && result !== lastNonBlockLocation.symbol) { result.isReferenced = true; } if (!result) { if (lastLocation) { ts.Debug.assert(lastLocation.kind === 269 /* SourceFile */); if (lastLocation.commonJsModuleIndicator && name === "exports") { return lastLocation.symbol; } } result = lookup(globals, name, meaning); } if (!result) { if (nameNotFoundMessage) { if (!errorLocation || !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) && !checkAndReportErrorForExtendingInterface(errorLocation) && !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) && !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) && !checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning)) { var suggestion = void 0; if (suggestedNameNotFoundMessage && suggestionCount < maximumSuggestionCount) { suggestion = getSuggestionForNonexistentSymbol(originalLocation, name, meaning); if (suggestion) { error(errorLocation, suggestedNameNotFoundMessage, diagnosticName(nameArg), suggestion); } } if (!suggestion) { error(errorLocation, nameNotFoundMessage, diagnosticName(nameArg)); } suggestionCount++; } } return undefined; } // Perform extra checks only if error reporting was requested if (nameNotFoundMessage) { if (propertyWithInvalidInitializer) { // We have a match, but the reference occurred within a property initializer and the identifier also binds // to a local variable in the constructor where the code will be emitted. var propertyName = propertyWithInvalidInitializer.name; error(errorLocation, ts.Diagnostics.Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor, ts.declarationNameToString(propertyName), diagnosticName(nameArg)); return undefined; } // Only check for block-scoped variable if we have an error location and are looking for the // name with variable meaning // For example, // declare module foo { // interface bar {} // } // const foo/*1*/: foo/*2*/.bar; // The foo at /*1*/ and /*2*/ will share same symbol with two meanings: // block-scoped variable and namespace module. However, only when we // try to resolve name in /*1*/ which is used in variable position, // we want to check for block-scoped if (errorLocation && (meaning & 2 /* BlockScopedVariable */ || ((meaning & 32 /* Class */ || meaning & 384 /* Enum */) && (meaning & 107455 /* Value */) === 107455 /* Value */))) { var exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); if (exportOrLocalSymbol.flags & 2 /* BlockScopedVariable */ || exportOrLocalSymbol.flags & 32 /* Class */ || exportOrLocalSymbol.flags & 384 /* Enum */) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); } } // If we're in an external module, we can't reference value symbols created from UMD export declarations if (result && isInExternalModule && (meaning & 107455 /* Value */) === 107455 /* Value */) { var decls = result.declarations; if (decls && decls.length === 1 && decls[0].kind === 237 /* NamespaceExportDeclaration */) { error(errorLocation, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead, ts.unescapeLeadingUnderscores(name)); } } } return result; } function diagnosticName(nameArg) { return ts.isString(nameArg) ? ts.unescapeLeadingUnderscores(nameArg) : ts.declarationNameToString(nameArg); } function isTypeParameterSymbolDeclaredInContainer(symbol, container) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; if (decl.kind === 146 /* TypeParameter */ && decl.parent === container) { return true; } } return false; } function checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) { if ((errorLocation.kind === 71 /* Identifier */ && (isTypeReferenceIdentifier(errorLocation)) || isInTypeQuery(errorLocation))) { return false; } var container = ts.getThisContainer(errorLocation, /*includeArrowFunctions*/ true); var location = container; while (location) { if (ts.isClassLike(location.parent)) { var classSymbol = getSymbolOfNode(location.parent); if (!classSymbol) { break; } // Check to see if a static member exists. var constructorType = getTypeOfSymbol(classSymbol); if (getPropertyOfType(constructorType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_static_member_1_0, diagnosticName(nameArg), symbolToString(classSymbol)); return true; } // No static member is present. // Check if we're in an instance method and look for a relevant instance member. if (location === container && !ts.hasModifier(location, 32 /* Static */)) { var instanceType = getDeclaredTypeOfSymbol(classSymbol).thisType; if (getPropertyOfType(instanceType, name)) { error(errorLocation, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0, diagnosticName(nameArg)); return true; } } } location = location.parent; } return false; } function checkAndReportErrorForExtendingInterface(errorLocation) { var expression = getEntityNameForExtendingInterface(errorLocation); var isError = !!(expression && resolveEntityName(expression, 64 /* Interface */, /*ignoreErrors*/ true)); if (isError) { error(errorLocation, ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements, ts.getTextOfNode(expression)); } return isError; } /** * Climbs up parents to an ExpressionWithTypeArguments, and returns its expression, * but returns undefined if that expression is not an EntityNameExpression. */ function getEntityNameForExtendingInterface(node) { switch (node.kind) { case 71 /* Identifier */: case 180 /* PropertyAccessExpression */: return node.parent ? getEntityNameForExtendingInterface(node.parent) : undefined; case 202 /* ExpressionWithTypeArguments */: if (ts.isEntityNameExpression(node.expression)) { return node.expression; } // falls through default: return undefined; } } function checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) { if (meaning === 1920 /* Namespace */) { var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~1920 /* Namespace */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); var parent = errorLocation.parent; if (symbol) { if (ts.isQualifiedName(parent)) { ts.Debug.assert(parent.left === errorLocation, "Should only be resolving left side of qualified name as a namespace"); var propName = parent.right.escapedText; var propType = getPropertyOfType(getDeclaredTypeOfSymbol(symbol), propName); if (propType) { error(parent, ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, ts.unescapeLeadingUnderscores(name), ts.unescapeLeadingUnderscores(propName)); return true; } } error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, ts.unescapeLeadingUnderscores(name)); return true; } } return false; } function checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning) { if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */)) { if (name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never") { error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name)); return true; } var symbol = resolveSymbol(resolveName(errorLocation, name, 793064 /* Type */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol && !(symbol.flags & 1024 /* NamespaceModule */)) { error(errorLocation, ts.Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_value_here, ts.unescapeLeadingUnderscores(name)); return true; } } return false; } function checkAndReportErrorForUsingNamespaceModuleAsValue(errorLocation, name, meaning) { if (meaning & (107455 /* Value */ & ~1024 /* NamespaceModule */ & ~793064 /* Type */)) { var symbol = resolveSymbol(resolveName(errorLocation, name, 1024 /* NamespaceModule */ & ~107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol) { error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_value, ts.unescapeLeadingUnderscores(name)); return true; } } else if (meaning & (793064 /* Type */ & ~1024 /* NamespaceModule */ & ~107455 /* Value */)) { var symbol = resolveSymbol(resolveName(errorLocation, name, (512 /* ValueModule */ | 1024 /* NamespaceModule */) & ~793064 /* Type */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)); if (symbol) { error(errorLocation, ts.Diagnostics.Cannot_use_namespace_0_as_a_type, ts.unescapeLeadingUnderscores(name)); return true; } } return false; } function checkResolvedBlockScopedVariable(result, errorLocation) { ts.Debug.assert(!!(result.flags & 2 /* BlockScopedVariable */ || result.flags & 32 /* Class */ || result.flags & 384 /* Enum */)); // Block-scoped variables cannot be used before their definition var declaration = ts.forEach(result.declarations, function (d) { return ts.isBlockOrCatchScoped(d) || ts.isClassLike(d) || (d.kind === 233 /* EnumDeclaration */) ? d : undefined; }); ts.Debug.assert(declaration !== undefined, "Declaration to checkResolvedBlockScopedVariable is undefined"); if (!(declaration.flags & 2097152 /* Ambient */) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) { if (result.flags & 2 /* BlockScopedVariable */) { error(errorLocation, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration))); } else if (result.flags & 32 /* Class */) { error(errorLocation, ts.Diagnostics.Class_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration))); } else if (result.flags & 256 /* RegularEnum */) { error(errorLocation, ts.Diagnostics.Enum_0_used_before_its_declaration, ts.declarationNameToString(ts.getNameOfDeclaration(declaration))); } } } /* Starting from 'initial' node walk up the parent chain until 'stopAt' node is reached. * If at any point current node is equal to 'parent' node - return true. * Return false if 'stopAt' node is reached or isFunctionLike(current) === true. */ function isSameScopeDescendentOf(initial, parent, stopAt) { return parent && !!ts.findAncestor(initial, function (n) { return n === stopAt || ts.isFunctionLike(n) ? "quit" : n === parent; }); } function getAnyImportSyntax(node) { switch (node.kind) { case 238 /* ImportEqualsDeclaration */: return node; case 240 /* ImportClause */: return node.parent; case 241 /* NamespaceImport */: return node.parent.parent; case 243 /* ImportSpecifier */: return node.parent.parent.parent; default: return undefined; } } function getDeclarationOfAliasSymbol(symbol) { return ts.find(symbol.declarations, ts.isAliasSymbolDeclaration); } function getTargetOfImportEqualsDeclaration(node, dontResolveAlias) { if (node.moduleReference.kind === 249 /* ExternalModuleReference */) { return resolveExternalModuleSymbol(resolveExternalModuleName(node, ts.getExternalModuleImportEqualsDeclarationExpression(node))); } return getSymbolOfPartOfRightHandSideOfImportEquals(node.moduleReference, dontResolveAlias); } function getTargetOfImportClause(node, dontResolveAlias) { var moduleSymbol = resolveExternalModuleName(node, node.parent.moduleSpecifier); if (moduleSymbol) { var exportDefaultSymbol = void 0; if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { exportDefaultSymbol = moduleSymbol; } else { var exportValue = moduleSymbol.exports.get("export="); exportDefaultSymbol = exportValue ? getPropertyOfType(getTypeOfSymbol(exportValue), "default") : resolveSymbol(moduleSymbol.exports.get("default"), dontResolveAlias); } if (!exportDefaultSymbol && !allowSyntheticDefaultImports) { error(node.name, ts.Diagnostics.Module_0_has_no_default_export, symbolToString(moduleSymbol)); } else if (!exportDefaultSymbol && allowSyntheticDefaultImports) { return resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } return exportDefaultSymbol; } } function getTargetOfNamespaceImport(node, dontResolveAlias) { var moduleSpecifier = node.parent.parent.moduleSpecifier; return resolveESModuleSymbol(resolveExternalModuleName(node, moduleSpecifier), moduleSpecifier, dontResolveAlias); } // This function creates a synthetic symbol that combines the value side of one symbol with the // type/namespace side of another symbol. Consider this example: // // declare module graphics { // interface Point { // x: number; // y: number; // } // } // declare var graphics: { // Point: new (x: number, y: number) => graphics.Point; // } // declare module "graphics" { // export = graphics; // } // // An 'import { Point } from "graphics"' needs to create a symbol that combines the value side 'Point' // property with the type/namespace side interface 'Point'. function combineValueAndTypeSymbols(valueSymbol, typeSymbol) { if (valueSymbol === unknownSymbol && typeSymbol === unknownSymbol) { return unknownSymbol; } if (valueSymbol.flags & (793064 /* Type */ | 1920 /* Namespace */)) { return valueSymbol; } var result = createSymbol(valueSymbol.flags | typeSymbol.flags, valueSymbol.escapedName); result.declarations = ts.concatenate(valueSymbol.declarations, typeSymbol.declarations); result.parent = valueSymbol.parent || typeSymbol.parent; if (valueSymbol.valueDeclaration) result.valueDeclaration = valueSymbol.valueDeclaration; if (typeSymbol.members) result.members = typeSymbol.members; if (valueSymbol.exports) result.exports = valueSymbol.exports; return result; } function getExportOfModule(symbol, name, dontResolveAlias) { if (symbol.flags & 1536 /* Module */) { return resolveSymbol(getExportsOfSymbol(symbol).get(name), dontResolveAlias); } } function getPropertyOfVariable(symbol, name) { if (symbol.flags & 3 /* Variable */) { var typeAnnotation = symbol.valueDeclaration.type; if (typeAnnotation) { return resolveSymbol(getPropertyOfType(getTypeFromTypeNode(typeAnnotation), name)); } } } function getExternalModuleMember(node, specifier, dontResolveAlias) { var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); var targetSymbol = resolveESModuleSymbol(moduleSymbol, node.moduleSpecifier, dontResolveAlias); if (targetSymbol) { var name = specifier.propertyName || specifier.name; if (name.escapedText) { if (ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { return moduleSymbol; } var symbolFromVariable = void 0; // First check if module was specified with "export=". If so, get the member from the resolved type if (moduleSymbol && moduleSymbol.exports && moduleSymbol.exports.get("export=")) { symbolFromVariable = getPropertyOfType(getTypeOfSymbol(targetSymbol), name.escapedText); } else { symbolFromVariable = getPropertyOfVariable(targetSymbol, name.escapedText); } // if symbolFromVariable is export - get its final target symbolFromVariable = resolveSymbol(symbolFromVariable, dontResolveAlias); var symbolFromModule = getExportOfModule(targetSymbol, name.escapedText, dontResolveAlias); // If the export member we're looking for is default, and there is no real default but allowSyntheticDefaultImports is on, return the entire module as the default if (!symbolFromModule && allowSyntheticDefaultImports && name.escapedText === "default") { symbolFromModule = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) || resolveSymbol(moduleSymbol, dontResolveAlias); } var symbol = symbolFromModule && symbolFromVariable ? combineValueAndTypeSymbols(symbolFromVariable, symbolFromModule) : symbolFromModule || symbolFromVariable; if (!symbol) { error(name, ts.Diagnostics.Module_0_has_no_exported_member_1, getFullyQualifiedName(moduleSymbol), ts.declarationNameToString(name)); } return symbol; } } } function getTargetOfImportSpecifier(node, dontResolveAlias) { return getExternalModuleMember(node.parent.parent.parent, node, dontResolveAlias); } function getTargetOfNamespaceExportDeclaration(node, dontResolveAlias) { return resolveExternalModuleSymbol(node.parent.symbol, dontResolveAlias); } function getTargetOfExportSpecifier(node, meaning, dontResolveAlias) { return node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node, dontResolveAlias) : resolveEntityName(node.propertyName || node.name, meaning, /*ignoreErrors*/ false, dontResolveAlias); } function getTargetOfExportAssignment(node, dontResolveAlias) { return resolveEntityName(node.expression, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias); } function getTargetOfAliasDeclaration(node, dontRecursivelyResolve) { switch (node.kind) { case 238 /* ImportEqualsDeclaration */: return getTargetOfImportEqualsDeclaration(node, dontRecursivelyResolve); case 240 /* ImportClause */: return getTargetOfImportClause(node, dontRecursivelyResolve); case 241 /* NamespaceImport */: return getTargetOfNamespaceImport(node, dontRecursivelyResolve); case 243 /* ImportSpecifier */: return getTargetOfImportSpecifier(node, dontRecursivelyResolve); case 247 /* ExportSpecifier */: return getTargetOfExportSpecifier(node, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, dontRecursivelyResolve); case 244 /* ExportAssignment */: return getTargetOfExportAssignment(node, dontRecursivelyResolve); case 237 /* NamespaceExportDeclaration */: return getTargetOfNamespaceExportDeclaration(node, dontRecursivelyResolve); } } /** * Indicates that a symbol is an alias that does not merge with a local declaration. */ function isNonLocalAlias(symbol, excludes) { if (excludes === void 0) { excludes = 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */; } return symbol && (symbol.flags & (2097152 /* Alias */ | excludes)) === 2097152 /* Alias */; } function resolveSymbol(symbol, dontResolveAlias) { var shouldResolve = !dontResolveAlias && isNonLocalAlias(symbol); return shouldResolve ? resolveAlias(symbol) : symbol; } function resolveAlias(symbol) { ts.Debug.assert((symbol.flags & 2097152 /* Alias */) !== 0, "Should only get Alias here."); var links = getSymbolLinks(symbol); if (!links.target) { links.target = resolvingSymbol; var node = getDeclarationOfAliasSymbol(symbol); ts.Debug.assert(!!node); var target = getTargetOfAliasDeclaration(node); if (links.target === resolvingSymbol) { links.target = target || unknownSymbol; } else { error(node, ts.Diagnostics.Circular_definition_of_import_alias_0, symbolToString(symbol)); } } else if (links.target === resolvingSymbol) { links.target = unknownSymbol; } return links.target; } function markExportAsReferenced(node) { var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target) { var markAlias = target === unknownSymbol || ((target.flags & 107455 /* Value */) && !isConstEnumOrConstEnumOnlyModule(target)); if (markAlias) { markAliasSymbolAsReferenced(symbol); } } } // When an alias symbol is referenced, we need to mark the entity it references as referenced and in turn repeat that until // we reach a non-alias or an exported entity (which is always considered referenced). We do this by checking the target of // the alias as an expression (which recursively takes us back here if the target references another alias). function markAliasSymbolAsReferenced(symbol) { var links = getSymbolLinks(symbol); if (!links.referenced) { links.referenced = true; var node = getDeclarationOfAliasSymbol(symbol); ts.Debug.assert(!!node); if (node.kind === 244 /* ExportAssignment */) { // export default checkExpressionCached(node.expression); } else if (node.kind === 247 /* ExportSpecifier */) { // export { } or export { as foo } checkExpressionCached(node.propertyName || node.name); } else if (ts.isInternalModuleImportEqualsDeclaration(node)) { // import foo = checkExpressionCached(node.moduleReference); } } } // This function is only for imports with entity names function getSymbolOfPartOfRightHandSideOfImportEquals(entityName, dontResolveAlias) { // There are three things we might try to look for. In the following examples, // the search term is enclosed in |...|: // // import a = |b|; // Namespace // import a = |b.c|; // Value, type, namespace // import a = |b.c|.d; // Namespace if (entityName.kind === 71 /* Identifier */ && ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { entityName = entityName.parent; } // Check for case 1 and 3 in the above example if (entityName.kind === 71 /* Identifier */ || entityName.parent.kind === 144 /* QualifiedName */) { return resolveEntityName(entityName, 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias); } else { // Case 2 in above example // entityName.kind could be a QualifiedName or a Missing identifier ts.Debug.assert(entityName.parent.kind === 238 /* ImportEqualsDeclaration */); return resolveEntityName(entityName, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, /*ignoreErrors*/ false, dontResolveAlias); } } function getFullyQualifiedName(symbol) { return symbol.parent ? getFullyQualifiedName(symbol.parent) + "." + symbolToString(symbol) : symbolToString(symbol); } /** * Resolves a qualified name and any involved aliases. */ function resolveEntityName(name, meaning, ignoreErrors, dontResolveAlias, location) { if (ts.nodeIsMissing(name)) { return undefined; } var symbol; if (name.kind === 71 /* Identifier */) { var message = meaning === 1920 /* Namespace */ ? ts.Diagnostics.Cannot_find_namespace_0 : ts.Diagnostics.Cannot_find_name_0; symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors ? undefined : message, name, /*isUse*/ true); if (!symbol) { return undefined; } } else if (name.kind === 144 /* QualifiedName */ || name.kind === 180 /* PropertyAccessExpression */) { var left = void 0; if (name.kind === 144 /* QualifiedName */) { left = name.left; } else if (name.kind === 180 /* PropertyAccessExpression */ && (name.expression.kind === 186 /* ParenthesizedExpression */ || ts.isEntityNameExpression(name.expression))) { left = name.expression; } else { // If the expression in property-access expression is not entity-name or parenthsizedExpression (e.g. it is a call expression), it won't be able to successfully resolve the name. // This is the case when we are trying to do any language service operation in heritage clauses. By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression // will attempt to checkPropertyAccessExpression to resolve symbol. // i.e class C extends foo()./*do language service operation here*/B {} return undefined; } var right = name.kind === 144 /* QualifiedName */ ? name.right : name.name; var namespace = resolveEntityName(left, 1920 /* Namespace */, ignoreErrors, /*dontResolveAlias*/ false, location); if (!namespace || ts.nodeIsMissing(right)) { return undefined; } else if (namespace === unknownSymbol) { return namespace; } if (ts.isInJavaScriptFile(name) && ts.isDeclarationOfFunctionOrClassExpression(namespace)) { namespace = getSymbolOfNode(namespace.valueDeclaration.initializer); } symbol = getSymbol(getExportsOfSymbol(namespace), right.escapedText, meaning); if (!symbol) { if (!ignoreErrors) { error(right, ts.Diagnostics.Namespace_0_has_no_exported_member_1, getFullyQualifiedName(namespace), ts.declarationNameToString(right)); } return undefined; } } else if (name.kind === 186 /* ParenthesizedExpression */) { // If the expression in parenthesizedExpression is not an entity-name (e.g. it is a call expression), it won't be able to successfully resolve the name. // This is the case when we are trying to do any language service operation in heritage clauses. // By return undefined, the getSymbolOfEntityNameOrPropertyAccessExpression will attempt to checkPropertyAccessExpression to resolve symbol. // i.e class C extends foo()./*do language service operation here*/B {} return ts.isEntityNameExpression(name.expression) ? resolveEntityName(name.expression, meaning, ignoreErrors, dontResolveAlias, location) : undefined; } else { ts.Debug.assertNever(name, "Unknown entity name kind."); } ts.Debug.assert((ts.getCheckFlags(symbol) & 1 /* Instantiated */) === 0, "Should never get an instantiated symbol here."); return (symbol.flags & meaning) || dontResolveAlias ? symbol : resolveAlias(symbol); } function resolveExternalModuleName(location, moduleReferenceExpression) { return resolveExternalModuleNameWorker(location, moduleReferenceExpression, ts.Diagnostics.Cannot_find_module_0); } function resolveExternalModuleNameWorker(location, moduleReferenceExpression, moduleNotFoundError, isForAugmentation) { if (isForAugmentation === void 0) { isForAugmentation = false; } if (moduleReferenceExpression.kind !== 9 /* StringLiteral */ && moduleReferenceExpression.kind !== 13 /* NoSubstitutionTemplateLiteral */) { return; } var moduleReferenceLiteral = moduleReferenceExpression; return resolveExternalModule(location, moduleReferenceLiteral.text, moduleNotFoundError, moduleReferenceLiteral, isForAugmentation); } function resolveExternalModule(location, moduleReference, moduleNotFoundError, errorNode, isForAugmentation) { if (isForAugmentation === void 0) { isForAugmentation = false; } if (moduleReference === undefined) { return; } if (ts.startsWith(moduleReference, "@types/")) { var diag = ts.Diagnostics.Cannot_import_type_declaration_files_Consider_importing_0_instead_of_1; var withoutAtTypePrefix = ts.removePrefix(moduleReference, "@types/"); error(errorNode, diag, withoutAtTypePrefix, moduleReference); } var ambientModule = tryFindAmbientModule(moduleReference, /*withAugmentations*/ true); if (ambientModule) { return ambientModule; } var resolvedModule = ts.getResolvedModule(ts.getSourceFileOfNode(location), moduleReference); var resolutionDiagnostic = resolvedModule && ts.getResolutionDiagnostic(compilerOptions, resolvedModule); var sourceFile = resolvedModule && !resolutionDiagnostic && host.getSourceFile(resolvedModule.resolvedFileName); if (sourceFile) { if (sourceFile.symbol) { // merged symbol is module declaration symbol combined with all augmentations return getMergedSymbol(sourceFile.symbol); } if (moduleNotFoundError) { // report errors only if it was requested error(errorNode, ts.Diagnostics.File_0_is_not_a_module, sourceFile.fileName); } return undefined; } if (patternAmbientModules) { var pattern = ts.findBestPatternMatch(patternAmbientModules, function (_) { return _.pattern; }, moduleReference); if (pattern) { return getMergedSymbol(pattern.symbol); } } // May be an untyped module. If so, ignore resolutionDiagnostic. if (resolvedModule && !ts.extensionIsTypeScript(resolvedModule.extension) && resolutionDiagnostic === undefined || resolutionDiagnostic === ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type) { if (isForAugmentation) { var diag = ts.Diagnostics.Invalid_module_name_in_augmentation_Module_0_resolves_to_an_untyped_module_at_1_which_cannot_be_augmented; error(errorNode, diag, moduleReference, resolvedModule.resolvedFileName); } else if (noImplicitAny && moduleNotFoundError) { var errorInfo = !resolvedModule.isExternalLibraryImport ? undefined : ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0, moduleReference); errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type, moduleReference, resolvedModule.resolvedFileName); diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo)); } // Failed imports and untyped modules are both treated in an untyped manner; only difference is whether we give a diagnostic first. return undefined; } if (moduleNotFoundError) { // report errors only if it was requested if (resolutionDiagnostic) { error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName); } else { var tsExtension = ts.tryExtractTypeScriptExtension(moduleReference); if (tsExtension) { var diag = ts.Diagnostics.An_import_path_cannot_end_with_a_0_extension_Consider_importing_1_instead; error(errorNode, diag, tsExtension, ts.removeExtension(moduleReference, tsExtension)); } else { error(errorNode, moduleNotFoundError, moduleReference); } } } return undefined; } // An external module with an 'export =' declaration resolves to the target of the 'export =' declaration, // and an external module with no 'export =' declaration resolves to the module itself. function resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias) { return moduleSymbol && getMergedSymbol(resolveSymbol(moduleSymbol.exports.get("export=" /* ExportEquals */), dontResolveAlias)) || moduleSymbol; } // An external module with an 'export =' declaration may be referenced as an ES6 module provided the 'export =' // references a symbol that is at least declared as a module or a variable. The target of the 'export =' may // combine other declarations with the module or variable (e.g. a class/module, function/module, interface/variable). function resolveESModuleSymbol(moduleSymbol, moduleReferenceExpression, dontResolveAlias) { var symbol = resolveExternalModuleSymbol(moduleSymbol, dontResolveAlias); if (!dontResolveAlias && symbol && !(symbol.flags & (1536 /* Module */ | 3 /* Variable */))) { error(moduleReferenceExpression, ts.Diagnostics.Module_0_resolves_to_a_non_module_entity_and_cannot_be_imported_using_this_construct, symbolToString(moduleSymbol)); } return symbol; } function hasExportAssignmentSymbol(moduleSymbol) { return moduleSymbol.exports.get("export=" /* ExportEquals */) !== undefined; } function getExportsOfModuleAsArray(moduleSymbol) { return symbolsToArray(getExportsOfModule(moduleSymbol)); } function getExportsAndPropertiesOfModule(moduleSymbol) { var exports = getExportsOfModuleAsArray(moduleSymbol); var exportEquals = resolveExternalModuleSymbol(moduleSymbol); if (exportEquals !== moduleSymbol) { ts.addRange(exports, getPropertiesOfType(getTypeOfSymbol(exportEquals))); } return exports; } function tryGetMemberInModuleExports(memberName, moduleSymbol) { var symbolTable = getExportsOfModule(moduleSymbol); if (symbolTable) { return symbolTable.get(memberName); } } function tryGetMemberInModuleExportsAndProperties(memberName, moduleSymbol) { var symbol = tryGetMemberInModuleExports(memberName, moduleSymbol); if (symbol) { return symbol; } var exportEquals = resolveExternalModuleSymbol(moduleSymbol); if (exportEquals === moduleSymbol) { return undefined; } var type = getTypeOfSymbol(exportEquals); return type.flags & 16382 /* Primitive */ ? undefined : getPropertyOfType(type, memberName); } function getExportsOfSymbol(symbol) { return symbol.flags & 32 /* Class */ ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedExports" /* resolvedExports */) : symbol.flags & 1536 /* Module */ ? getExportsOfModule(symbol) : symbol.exports || emptySymbols; } function getExportsOfModule(moduleSymbol) { var links = getSymbolLinks(moduleSymbol); return links.resolvedExports || (links.resolvedExports = getExportsOfModuleWorker(moduleSymbol)); } /** * Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument * Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables */ function extendExportSymbols(target, source, lookupTable, exportNode) { if (!source) return; source.forEach(function (sourceSymbol, id) { if (id === "default") return; var targetSymbol = target.get(id); if (!targetSymbol) { target.set(id, sourceSymbol); if (lookupTable && exportNode) { lookupTable.set(id, { specifierText: ts.getTextOfNode(exportNode.moduleSpecifier) }); } } else if (lookupTable && exportNode && targetSymbol && resolveSymbol(targetSymbol) !== resolveSymbol(sourceSymbol)) { var collisionTracker = lookupTable.get(id); if (!collisionTracker.exportsWithDuplicate) { collisionTracker.exportsWithDuplicate = [exportNode]; } else { collisionTracker.exportsWithDuplicate.push(exportNode); } } }); } function getExportsOfModuleWorker(moduleSymbol) { var visitedSymbols = []; // A module defined by an 'export=' consists on one export that needs to be resolved moduleSymbol = resolveExternalModuleSymbol(moduleSymbol); return visit(moduleSymbol) || emptySymbols; // The ES6 spec permits export * declarations in a module to circularly reference the module itself. For example, // module 'a' can 'export * from "b"' and 'b' can 'export * from "a"' without error. function visit(symbol) { if (!(symbol && symbol.flags & 1952 /* HasExports */ && ts.pushIfUnique(visitedSymbols, symbol))) { return; } var symbols = ts.cloneMap(symbol.exports); // All export * declarations are collected in an __export symbol by the binder var exportStars = symbol.exports.get("__export" /* ExportStar */); if (exportStars) { var nestedSymbols = ts.createSymbolTable(); var lookupTable_1 = ts.createMap(); for (var _i = 0, _a = exportStars.declarations; _i < _a.length; _i++) { var node = _a[_i]; var resolvedModule = resolveExternalModuleName(node, node.moduleSpecifier); var exportedSymbols = visit(resolvedModule); extendExportSymbols(nestedSymbols, exportedSymbols, lookupTable_1, node); } lookupTable_1.forEach(function (_a, id) { var exportsWithDuplicate = _a.exportsWithDuplicate; // It's not an error if the file with multiple `export *`s with duplicate names exports a member with that name itself if (id === "export=" || !(exportsWithDuplicate && exportsWithDuplicate.length) || symbols.has(id)) { return; } for (var _i = 0, exportsWithDuplicate_1 = exportsWithDuplicate; _i < exportsWithDuplicate_1.length; _i++) { var node = exportsWithDuplicate_1[_i]; diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Module_0_has_already_exported_a_member_named_1_Consider_explicitly_re_exporting_to_resolve_the_ambiguity, lookupTable_1.get(id).specifierText, ts.unescapeLeadingUnderscores(id))); } }); extendExportSymbols(symbols, nestedSymbols); } return symbols; } } function getMergedSymbol(symbol) { var merged; return symbol && symbol.mergeId && (merged = mergedSymbols[symbol.mergeId]) ? merged : symbol; } function getSymbolOfNode(node) { return getMergedSymbol(node.symbol && getLateBoundSymbol(node.symbol)); } function getParentOfSymbol(symbol) { return getMergedSymbol(symbol.parent && getLateBoundSymbol(symbol.parent)); } function getExportSymbolOfValueSymbolIfExported(symbol) { return symbol && (symbol.flags & 1048576 /* ExportValue */) !== 0 ? getMergedSymbol(symbol.exportSymbol) : symbol; } function symbolIsValue(symbol) { return !!(symbol.flags & 107455 /* Value */ || symbol.flags & 2097152 /* Alias */ && resolveAlias(symbol).flags & 107455 /* Value */); } function findConstructorDeclaration(node) { var members = node.members; for (var _i = 0, members_2 = members; _i < members_2.length; _i++) { var member = members_2[_i]; if (member.kind === 153 /* Constructor */ && ts.nodeIsPresent(member.body)) { return member; } } } function createType(flags) { var result = new Type(checker, flags); typeCount++; result.id = typeCount; return result; } function createIntrinsicType(kind, intrinsicName) { var type = createType(kind); type.intrinsicName = intrinsicName; return type; } function createBooleanType(trueFalseTypes) { var type = getUnionType(trueFalseTypes); type.flags |= 8 /* Boolean */; type.intrinsicName = "boolean"; return type; } function createObjectType(objectFlags, symbol) { var type = createType(65536 /* Object */); type.objectFlags = objectFlags; type.symbol = symbol; return type; } function createTypeofType() { return getUnionType(ts.arrayFrom(typeofEQFacts.keys(), getLiteralType)); } // A reserved member name starts with two underscores, but the third character cannot be an underscore // or the @ symbol. A third underscore indicates an escaped form of an identifer that started // with at least two underscores. The @ character indicates that the name is denoted by a well known ES // Symbol instance. function isReservedMemberName(name) { return name.charCodeAt(0) === 95 /* _ */ && name.charCodeAt(1) === 95 /* _ */ && name.charCodeAt(2) !== 95 /* _ */ && name.charCodeAt(2) !== 64 /* at */; } function getNamedMembers(members) { var result; members.forEach(function (symbol, id) { if (!isReservedMemberName(id)) { if (!result) result = []; if (symbolIsValue(symbol)) { result.push(symbol); } } }); return result || ts.emptyArray; } function setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) { type.members = members; type.properties = getNamedMembers(members); type.callSignatures = callSignatures; type.constructSignatures = constructSignatures; if (stringIndexInfo) type.stringIndexInfo = stringIndexInfo; if (numberIndexInfo) type.numberIndexInfo = numberIndexInfo; return type; } function createAnonymousType(symbol, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo) { return setStructuredTypeMembers(createObjectType(16 /* Anonymous */, symbol), members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } function forEachSymbolTableInScope(enclosingDeclaration, callback) { var result; for (var location = enclosingDeclaration; location; location = location.parent) { // Locals of a source file are not in scope (because they get merged into the global symbol table) if (location.locals && !isGlobalSourceFile(location)) { if (result = callback(location.locals)) { return result; } } switch (location.kind) { case 269 /* SourceFile */: if (!ts.isExternalOrCommonJsModule(location)) { break; } // falls through case 234 /* ModuleDeclaration */: if (result = callback(getSymbolOfNode(location).exports)) { return result; } break; } } return callback(globals); } function getQualifiedLeftMeaning(rightMeaning) { // If we are looking in value space, the parent meaning is value, other wise it is namespace return rightMeaning === 107455 /* Value */ ? 107455 /* Value */ : 1920 /* Namespace */; } function getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, useOnlyExternalAliasing) { if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) { return undefined; } var visitedSymbolTables = []; return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable); function getAccessibleSymbolChainFromSymbolTable(symbols) { if (!ts.pushIfUnique(visitedSymbolTables, symbols)) { return undefined; } var result = trySymbolTable(symbols); visitedSymbolTables.pop(); return result; } function canQualifySymbol(symbolFromSymbolTable, meaning) { // If the symbol is equivalent and doesn't need further qualification, this symbol is accessible return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) || // If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too !!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing); } function isAccessible(symbolFromSymbolTable, resolvedAliasSymbol) { return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) && // if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table) // and if symbolFromSymbolTable or alias resolution matches the symbol, // check the symbol can be qualified, it is only then this symbol is accessible !ts.some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) && canQualifySymbol(symbolFromSymbolTable, meaning); } function isUMDExportSymbol(symbol) { return symbol && symbol.declarations && symbol.declarations[0] && ts.isNamespaceExportDeclaration(symbol.declarations[0]); } function trySymbolTable(symbols) { // If symbol is directly available by its name in the symbol table if (isAccessible(symbols.get(symbol.escapedName))) { return [symbol]; } // Check if symbol is any of the alias return ts.forEachEntry(symbols, function (symbolFromSymbolTable) { if (symbolFromSymbolTable.flags & 2097152 /* Alias */ && symbolFromSymbolTable.escapedName !== "export=" && !(isUMDExportSymbol(symbolFromSymbolTable) && enclosingDeclaration && ts.isExternalModule(ts.getSourceFileOfNode(enclosingDeclaration))) // If `!useOnlyExternalAliasing`, we can use any type of alias to get the name && (!useOnlyExternalAliasing || ts.some(symbolFromSymbolTable.declarations, ts.isExternalModuleImportEqualsDeclaration))) { var resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable); if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) { return [symbolFromSymbolTable]; } // Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain // but only if the symbolFromSymbolTable can be qualified var accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTable(resolvedImportedSymbol.exports) : undefined; if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) { return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports); } } }); } } function needsQualification(symbol, enclosingDeclaration, meaning) { var qualify = false; forEachSymbolTableInScope(enclosingDeclaration, function (symbolTable) { // If symbol of this name is not available in the symbol table we are ok var symbolFromSymbolTable = symbolTable.get(symbol.escapedName); if (!symbolFromSymbolTable) { // Continue to the next symbol table return false; } // If the symbol with this name is present it should refer to the symbol if (symbolFromSymbolTable === symbol) { // No need to qualify return true; } // Qualify if the symbol from symbol table has same meaning as expected symbolFromSymbolTable = (symbolFromSymbolTable.flags & 2097152 /* Alias */ && !ts.getDeclarationOfKind(symbolFromSymbolTable, 247 /* 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 150 /* PropertyDeclaration */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: continue; default: return false; } } return true; } return false; } function isTypeSymbolAccessible(typeSymbol, enclosingDeclaration) { var access = isSymbolAccessible(typeSymbol, enclosingDeclaration, 793064 /* Type */, /*shouldComputeAliasesToMakeVisible*/ false); return access.accessibility === 0 /* Accessible */; } /** * Check if the given symbol in given enclosing declaration is accessible and mark all associated alias to be visible if requested * * @param symbol a Symbol to check if accessible * @param enclosingDeclaration a Node containing reference to the symbol * @param meaning a SymbolFlags to check if such meaning of the symbol is accessible * @param shouldComputeAliasToMakeVisible a boolean value to indicate whether to return aliases to be mark visible in case the symbol is accessible */ function isSymbolAccessible(symbol, enclosingDeclaration, meaning, shouldComputeAliasesToMakeVisible) { if (symbol && enclosingDeclaration && !(symbol.flags & 262144 /* TypeParameter */)) { var initialSymbol = symbol; var meaningToLook = meaning; while (symbol) { // Symbol is accessible if it by itself is accessible var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaningToLook, /*useOnlyExternalAliasing*/ false); if (accessibleSymbolChain) { var hasAccessibleDeclarations = hasVisibleDeclarations(accessibleSymbolChain[0], shouldComputeAliasesToMakeVisible); if (!hasAccessibleDeclarations) { return { accessibility: 1 /* NotAccessible */, errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning), errorModuleName: symbol !== initialSymbol ? symbolToString(symbol, enclosingDeclaration, 1920 /* Namespace */) : undefined, }; } return hasAccessibleDeclarations; } // If we haven't got the accessible symbol, it doesn't mean the symbol is actually inaccessible. // It could be a qualified symbol and hence verify the path // e.g.: // module m { // export class c { // } // } // const x: typeof m.c // In the above example when we start with checking if typeof m.c symbol is accessible, // we are going to see if c can be accessed in scope directly. // But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible // It is accessible if the parent m is accessible because then m.c can be accessed through qualification meaningToLook = getQualifiedLeftMeaning(meaning); symbol = getParentOfSymbol(symbol); } // This could be a symbol that is not exported in the external module // or it could be a symbol from different external module that is not aliased and hence cannot be named var symbolExternalModule = ts.forEach(initialSymbol.declarations, getExternalModuleContainer); if (symbolExternalModule) { var enclosingExternalModule = getExternalModuleContainer(enclosingDeclaration); if (symbolExternalModule !== enclosingExternalModule) { // name from different external module that is not visible return { accessibility: 2 /* CannotBeNamed */, errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning), errorModuleName: symbolToString(symbolExternalModule) }; } } // Just a local name that is not accessible return { accessibility: 1 /* NotAccessible */, errorSymbolName: symbolToString(initialSymbol, enclosingDeclaration, meaning), }; } return { accessibility: 0 /* Accessible */ }; function getExternalModuleContainer(declaration) { var node = ts.findAncestor(declaration, hasExternalModuleSymbol); return node && getSymbolOfNode(node); } } function hasExternalModuleSymbol(declaration) { return ts.isAmbientModule(declaration) || (declaration.kind === 269 /* SourceFile */ && ts.isExternalOrCommonJsModule(declaration)); } function hasVisibleDeclarations(symbol, shouldComputeAliasToMakeVisible) { var aliasesToMakeVisible; if (ts.forEach(symbol.declarations, function (declaration) { return !getIsDeclarationVisible(declaration); })) { return undefined; } return { accessibility: 0 /* Accessible */, aliasesToMakeVisible: aliasesToMakeVisible }; function getIsDeclarationVisible(declaration) { if (!isDeclarationVisible(declaration)) { // Mark the unexported alias as visible if its parent is visible // because these kind of aliases can be used to name types in declaration file var anyImportSyntax = getAnyImportSyntax(declaration); if (anyImportSyntax && !ts.hasModifier(anyImportSyntax, 1 /* Export */) && // import clause without export isDeclarationVisible(anyImportSyntax.parent)) { // In function "buildTypeDisplay" where we decide whether to write type-alias or serialize types, // we want to just check if type- alias is accessible or not but we don't care about emitting those alias at that time // since we will do the emitting later in trackSymbol. if (shouldComputeAliasToMakeVisible) { getNodeLinks(declaration).isVisible = true; aliasesToMakeVisible = ts.appendIfUnique(aliasesToMakeVisible, anyImportSyntax); } return true; } // Declaration is not visible return false; } return true; } } function isEntityNameVisible(entityName, enclosingDeclaration) { // get symbol of the first identifier of the entityName var meaning; if (entityName.parent.kind === 163 /* TypeQuery */ || ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) || entityName.parent.kind === 145 /* ComputedPropertyName */) { // Typeof value meaning = 107455 /* Value */ | 1048576 /* ExportValue */; } else if (entityName.kind === 144 /* QualifiedName */ || entityName.kind === 180 /* PropertyAccessExpression */ || entityName.parent.kind === 238 /* ImportEqualsDeclaration */) { // Left identifier from type reference or TypeAlias // Entity name of the import declaration meaning = 1920 /* Namespace */; } else { // Type Reference or TypeAlias entity = Identifier meaning = 793064 /* Type */; } var firstIdentifier = getFirstIdentifier(entityName); var symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); // Verify if the symbol is accessible return (symbol && hasVisibleDeclarations(symbol, /*shouldComputeAliasToMakeVisible*/ true)) || { accessibility: 1 /* NotAccessible */, errorSymbolName: ts.getTextOfNode(firstIdentifier), errorNode: firstIdentifier }; } function writeKeyword(writer, kind) { writer.writeKeyword(ts.tokenToString(kind)); } function writePunctuation(writer, kind) { writer.writePunctuation(ts.tokenToString(kind)); } function writeSpace(writer) { writer.writeSpace(" "); } function symbolToString(symbol, enclosingDeclaration, meaning) { return ts.usingSingleLineStringWriter(function (writer) { getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning); }); } function signatureToString(signature, enclosingDeclaration, flags, kind) { return ts.usingSingleLineStringWriter(function (writer) { getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind); }); } function typeToString(type, enclosingDeclaration, flags) { var typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | ts.NodeBuilderFlags.IgnoreErrors | ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName); ts.Debug.assert(typeNode !== undefined, "should always get typenode"); var options = { removeComments: true }; var writer = ts.createTextWriter(""); var printer = ts.createPrinter(options); var sourceFile = enclosingDeclaration && ts.getSourceFileOfNode(enclosingDeclaration); printer.writeNode(4 /* Unspecified */, typeNode, /*sourceFile*/ sourceFile, writer); var result = writer.getText(); var maxLength = compilerOptions.noErrorTruncation || flags & 8 /* NoTruncation */ ? undefined : 100; if (maxLength && result.length >= maxLength) { return result.substr(0, maxLength - "...".length) + "..."; } return result; function toNodeBuilderFlags(flags) { var result = ts.NodeBuilderFlags.None; if (!flags) { return result; } if (flags & 8 /* NoTruncation */) { result |= ts.NodeBuilderFlags.NoTruncation; } if (flags & 256 /* UseFullyQualifiedType */) { result |= ts.NodeBuilderFlags.UseFullyQualifiedType; } if (flags & 4096 /* SuppressAnyReturnType */) { result |= ts.NodeBuilderFlags.SuppressAnyReturnType; } if (flags & 1 /* WriteArrayAsGenericType */) { result |= ts.NodeBuilderFlags.WriteArrayAsGenericType; } if (flags & 64 /* WriteTypeArgumentsOfSignature */) { result |= ts.NodeBuilderFlags.WriteTypeArgumentsOfSignature; } return result; } } function createNodeBuilder() { return { typeToTypeNode: function (type, enclosingDeclaration, flags) { ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0); var context = createNodeBuilderContext(enclosingDeclaration, flags); var resultingNode = typeToTypeNodeHelper(type, context); var result = context.encounteredError ? undefined : resultingNode; return result; }, indexInfoToIndexSignatureDeclaration: function (indexInfo, kind, enclosingDeclaration, flags) { ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0); var context = createNodeBuilderContext(enclosingDeclaration, flags); var resultingNode = indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context); var result = context.encounteredError ? undefined : resultingNode; return result; }, signatureToSignatureDeclaration: function (signature, kind, enclosingDeclaration, flags) { ts.Debug.assert(enclosingDeclaration === undefined || (enclosingDeclaration.flags & 8 /* Synthesized */) === 0); var context = createNodeBuilderContext(enclosingDeclaration, flags); var resultingNode = signatureToSignatureDeclarationHelper(signature, kind, context); var result = context.encounteredError ? undefined : resultingNode; return result; } }; function createNodeBuilderContext(enclosingDeclaration, flags) { return { enclosingDeclaration: enclosingDeclaration, flags: flags, encounteredError: false, symbolStack: undefined }; } function typeToTypeNodeHelper(type, context) { var inTypeAlias = context.flags & ts.NodeBuilderFlags.InTypeAlias; context.flags &= ~ts.NodeBuilderFlags.InTypeAlias; if (!type) { context.encounteredError = true; return undefined; } if (type.flags & 1 /* Any */) { return ts.createKeywordTypeNode(119 /* AnyKeyword */); } if (type.flags & 2 /* String */) { return ts.createKeywordTypeNode(136 /* StringKeyword */); } if (type.flags & 4 /* Number */) { return ts.createKeywordTypeNode(133 /* NumberKeyword */); } if (type.flags & 8 /* Boolean */) { return ts.createKeywordTypeNode(122 /* BooleanKeyword */); } if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 131072 /* Union */)) { var parentSymbol = getParentOfSymbol(type.symbol); var parentName = symbolToName(parentSymbol, context, 793064 /* Type */, /*expectsIdentifier*/ false); var enumLiteralName = getDeclaredTypeOfSymbol(parentSymbol) === type ? parentName : ts.createQualifiedName(parentName, ts.symbolName(type.symbol)); return ts.createTypeReferenceNode(enumLiteralName, /*typeArguments*/ undefined); } if (type.flags & 272 /* EnumLike */) { var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false); return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (type.flags & (32 /* StringLiteral */)) { return ts.createLiteralTypeNode(ts.setEmitFlags(ts.createLiteral(type.value), 16777216 /* NoAsciiEscaping */)); } if (type.flags & (64 /* NumberLiteral */)) { return ts.createLiteralTypeNode((ts.createLiteral(type.value))); } if (type.flags & 128 /* BooleanLiteral */) { return type.intrinsicName === "true" ? ts.createTrue() : ts.createFalse(); } if (type.flags & 1024 /* UniqueESSymbol */) { return ts.createTypeOperatorNode(140 /* UniqueKeyword */, ts.createKeywordTypeNode(137 /* SymbolKeyword */)); } if (type.flags & 2048 /* Void */) { return ts.createKeywordTypeNode(105 /* VoidKeyword */); } if (type.flags & 4096 /* Undefined */) { return ts.createKeywordTypeNode(139 /* UndefinedKeyword */); } if (type.flags & 8192 /* Null */) { return ts.createKeywordTypeNode(95 /* NullKeyword */); } if (type.flags & 16384 /* Never */) { return ts.createKeywordTypeNode(130 /* NeverKeyword */); } if (type.flags & 512 /* ESSymbol */) { return ts.createKeywordTypeNode(137 /* SymbolKeyword */); } if (type.flags & 33554432 /* NonPrimitive */) { return ts.createKeywordTypeNode(134 /* ObjectKeyword */); } if (type.flags & 32768 /* TypeParameter */ && type.isThisType) { if (context.flags & ts.NodeBuilderFlags.InObjectTypeLiteral) { if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowThisInObjectLiteral)) { context.encounteredError = true; } } return ts.createThis(); } var objectFlags = ts.getObjectFlags(type); if (objectFlags & 4 /* Reference */) { ts.Debug.assert(!!(type.flags & 65536 /* Object */)); return typeReferenceToTypeNode(type); } if (type.flags & 32768 /* TypeParameter */ || objectFlags & 3 /* ClassOrInterface */) { var name = type.symbol ? symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return ts.createTypeReferenceNode(name, /*typeArguments*/ undefined); } if (!inTypeAlias && type.aliasSymbol && isTypeSymbolAccessible(type.aliasSymbol, context.enclosingDeclaration)) { var name = symbolToTypeReferenceName(type.aliasSymbol); var typeArgumentNodes = mapToTypeNodes(type.aliasTypeArguments, context); return ts.createTypeReferenceNode(name, typeArgumentNodes); } if (type.flags & (131072 /* Union */ | 262144 /* Intersection */)) { var types = type.flags & 131072 /* Union */ ? formatUnionTypes(type.types) : type.types; var typeNodes = mapToTypeNodes(types, context); if (typeNodes && typeNodes.length > 0) { var unionOrIntersectionTypeNode = ts.createUnionOrIntersectionTypeNode(type.flags & 131072 /* Union */ ? 167 /* UnionType */ : 168 /* IntersectionType */, typeNodes); return unionOrIntersectionTypeNode; } else { if (!context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowEmptyUnionOrIntersection)) { context.encounteredError = true; } return undefined; } } if (objectFlags & (16 /* Anonymous */ | 32 /* Mapped */)) { ts.Debug.assert(!!(type.flags & 65536 /* Object */)); // The type is an object literal type. return createAnonymousTypeNode(type); } if (type.flags & 524288 /* Index */) { var indexedType = type.type; var indexTypeNode = typeToTypeNodeHelper(indexedType, context); return ts.createTypeOperatorNode(indexTypeNode); } if (type.flags & 1048576 /* IndexedAccess */) { var objectTypeNode = typeToTypeNodeHelper(type.objectType, context); var indexTypeNode = typeToTypeNodeHelper(type.indexType, context); return ts.createIndexedAccessTypeNode(objectTypeNode, indexTypeNode); } ts.Debug.fail("Should be unreachable."); function createMappedTypeNodeFromType(type) { ts.Debug.assert(!!(type.flags & 65536 /* Object */)); var readonlyToken = type.declaration && type.declaration.readonlyToken ? ts.createToken(131 /* ReadonlyKeyword */) : undefined; var questionToken = type.declaration && type.declaration.questionToken ? ts.createToken(55 /* QuestionToken */) : undefined; var typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context); var templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); var mappedTypeNode = ts.createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); return ts.setEmitFlags(mappedTypeNode, 1 /* SingleLine */); } function createAnonymousTypeNode(type) { var symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) || symbol.flags & (384 /* Enum */ | 512 /* ValueModule */) || shouldWriteTypeOfFunctionSymbol()) { return createTypeQueryNodeFromSymbol(symbol, 107455 /* Value */); } else if (ts.contains(context.symbolStack, symbol)) { // If type is an anonymous type literal in a type alias declaration, use type alias name var typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags var entityName = symbolToName(typeAlias, context, 793064 /* Type */, /*expectsIdentifier*/ false); return ts.createTypeReferenceNode(entityName, /*typeArguments*/ undefined); } else { return ts.createKeywordTypeNode(119 /* AnyKeyword */); } } else { // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead // of types allows us to catch circular references to instantiations of the same anonymous type if (!context.symbolStack) { context.symbolStack = []; } context.symbolStack.push(symbol); var result = createTypeNodeFromObjectType(type); context.symbolStack.pop(); return result; } } else { // Anonymous types without a symbol are never circular. return createTypeNodeFromObjectType(type); } function shouldWriteTypeOfFunctionSymbol() { var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && (symbol.parent || // is exported function symbol ts.forEach(symbol.declarations, function (declaration) { return declaration.parent.kind === 269 /* SourceFile */ || declaration.parent.kind === 235 /* ModuleBlock */; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions return ts.contains(context.symbolStack, symbol); // it is type of the symbol uses itself recursively } } } function createTypeNodeFromObjectType(type) { if (isGenericMappedType(type)) { return createMappedTypeNodeFromType(type); } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { return ts.setEmitFlags(ts.createTypeLiteralNode(/*members*/ undefined), 1 /* SingleLine */); } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { var signature = resolved.callSignatures[0]; var signatureNode = signatureToSignatureDeclarationHelper(signature, 161 /* FunctionType */, context); return signatureNode; } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { var signature = resolved.constructSignatures[0]; var signatureNode = signatureToSignatureDeclarationHelper(signature, 162 /* ConstructorType */, context); return signatureNode; } } var savedFlags = context.flags; context.flags |= ts.NodeBuilderFlags.InObjectTypeLiteral; var members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; var typeLiteralNode = ts.createTypeLiteralNode(members); return ts.setEmitFlags(typeLiteralNode, 1 /* SingleLine */); } function createTypeQueryNodeFromSymbol(symbol, symbolFlags) { var entityName = symbolToName(symbol, context, symbolFlags, /*expectsIdentifier*/ false); return ts.createTypeQueryNode(entityName); } function symbolToTypeReferenceName(symbol) { // Unnamed function expressions and arrow functions have reserved names that we don't want to display var entityName = symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName) ? symbolToName(symbol, context, 793064 /* Type */, /*expectsIdentifier*/ false) : ts.createIdentifier(""); return entityName; } function typeReferenceToTypeNode(type) { var typeArguments = type.typeArguments || ts.emptyArray; if (type.target === globalArrayType) { if (context.flags & ts.NodeBuilderFlags.WriteArrayAsGenericType) { var typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context); return ts.createTypeReferenceNode("Array", [typeArgumentNode]); } var elementType = typeToTypeNodeHelper(typeArguments[0], context); return ts.createArrayTypeNode(elementType); } else if (type.target.objectFlags & 8 /* Tuple */) { if (typeArguments.length > 0) { var tupleConstituentNodes = mapToTypeNodes(typeArguments.slice(0, getTypeReferenceArity(type)), context); if (tupleConstituentNodes && tupleConstituentNodes.length > 0) { return ts.createTupleTypeNode(tupleConstituentNodes); } } if (context.encounteredError || (context.flags & ts.NodeBuilderFlags.AllowEmptyTuple)) { return ts.createTupleTypeNode([]); } context.encounteredError = true; return undefined; } else { var outerTypeParameters = type.target.outerTypeParameters; var i = 0; var qualifiedName = void 0; if (outerTypeParameters) { var length_1 = outerTypeParameters.length; while (i < length_1) { // Find group of type arguments for type parameters with the same declaring container. var start = i; var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); do { i++; } while (i < length_1 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { var typeArgumentSlice = mapToTypeNodes(typeArguments.slice(start, i), context); var typeArgumentNodes_1 = typeArgumentSlice && ts.createNodeArray(typeArgumentSlice); var namePart = symbolToTypeReferenceName(parent); (namePart.kind === 71 /* Identifier */ ? namePart : namePart.right).typeArguments = typeArgumentNodes_1; if (qualifiedName) { ts.Debug.assert(!qualifiedName.right); qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, namePart); qualifiedName = ts.createQualifiedName(qualifiedName, /*right*/ undefined); } else { qualifiedName = ts.createQualifiedName(namePart, /*right*/ undefined); } } } } var entityName = undefined; var nameIdentifier = symbolToTypeReferenceName(type.symbol); if (qualifiedName) { ts.Debug.assert(!qualifiedName.right); qualifiedName = addToQualifiedNameMissingRightIdentifier(qualifiedName, nameIdentifier); entityName = qualifiedName; } else { entityName = nameIdentifier; } var typeArgumentNodes = void 0; if (typeArguments.length > 0) { var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length; typeArgumentNodes = mapToTypeNodes(typeArguments.slice(i, typeParameterCount), context); } if (typeArgumentNodes) { var lastIdentifier = entityName.kind === 71 /* Identifier */ ? entityName : entityName.right; lastIdentifier.typeArguments = undefined; } return ts.createTypeReferenceNode(entityName, typeArgumentNodes); } } function addToQualifiedNameMissingRightIdentifier(left, right) { ts.Debug.assert(left.right === undefined); if (right.kind === 71 /* Identifier */) { left.right = right; return left; } var rightPart = right; while (rightPart.left.kind !== 71 /* Identifier */) { rightPart = rightPart.left; } left.right = rightPart.left; rightPart.left = left; return right; } function createTypeNodesFromResolvedType(resolvedType) { var typeElements = []; for (var _i = 0, _a = resolvedType.callSignatures; _i < _a.length; _i++) { var signature = _a[_i]; typeElements.push(signatureToSignatureDeclarationHelper(signature, 156 /* CallSignature */, context)); } for (var _b = 0, _c = resolvedType.constructSignatures; _b < _c.length; _b++) { var signature = _c[_b]; typeElements.push(signatureToSignatureDeclarationHelper(signature, 157 /* ConstructSignature */, context)); } if (resolvedType.stringIndexInfo) { typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, 0 /* String */, context)); } if (resolvedType.numberIndexInfo) { typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, 1 /* Number */, context)); } var properties = resolvedType.properties; if (!properties) { return typeElements; } for (var _d = 0, properties_1 = properties; _d < properties_1.length; _d++) { var propertySymbol = properties_1[_d]; var propertyType = getTypeOfSymbol(propertySymbol); var saveEnclosingDeclaration = context.enclosingDeclaration; context.enclosingDeclaration = undefined; var propertyName = symbolToName(propertySymbol, context, 107455 /* Value */, /*expectsIdentifier*/ true); context.enclosingDeclaration = saveEnclosingDeclaration; var optionalToken = propertySymbol.flags & 16777216 /* Optional */ ? ts.createToken(55 /* QuestionToken */) : undefined; if (propertySymbol.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(propertyType).length) { var signatures = getSignaturesOfType(propertyType, 0 /* Call */); for (var _e = 0, signatures_1 = signatures; _e < signatures_1.length; _e++) { var signature = signatures_1[_e]; var methodDeclaration = signatureToSignatureDeclarationHelper(signature, 151 /* MethodSignature */, context); methodDeclaration.name = propertyName; methodDeclaration.questionToken = optionalToken; typeElements.push(methodDeclaration); } } else { var propertyTypeNode = propertyType ? typeToTypeNodeHelper(propertyType, context) : ts.createKeywordTypeNode(119 /* AnyKeyword */); var modifiers = isReadonlySymbol(propertySymbol) ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined; var propertySignature = ts.createPropertySignature(modifiers, propertyName, optionalToken, propertyTypeNode, /*initializer*/ undefined); typeElements.push(propertySignature); } } return typeElements.length ? typeElements : undefined; } } function mapToTypeNodes(types, context) { if (ts.some(types)) { var result = []; for (var _i = 0, types_1 = types; _i < types_1.length; _i++) { var type = types_1[_i]; var typeNode = typeToTypeNodeHelper(type, context); if (typeNode) { result.push(typeNode); } } return result; } } function indexInfoToIndexSignatureDeclarationHelper(indexInfo, kind, context) { var name = ts.getNameFromIndexInfo(indexInfo) || "x"; var indexerTypeNode = ts.createKeywordTypeNode(kind === 0 /* String */ ? 136 /* StringKeyword */ : 133 /* NumberKeyword */); var indexingParameter = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name, /*questionToken*/ undefined, indexerTypeNode, /*initializer*/ undefined); var typeNode = typeToTypeNodeHelper(indexInfo.type, context); return ts.createIndexSignature( /*decorators*/ undefined, indexInfo.isReadonly ? [ts.createToken(131 /* ReadonlyKeyword */)] : undefined, [indexingParameter], typeNode); } function signatureToSignatureDeclarationHelper(signature, kind, context) { var typeParameters = signature.typeParameters && signature.typeParameters.map(function (parameter) { return typeParameterToDeclaration(parameter, context); }); var parameters = signature.parameters.map(function (parameter) { return symbolToParameterDeclaration(parameter, context); }); if (signature.thisParameter) { var thisParameter = symbolToParameterDeclaration(signature.thisParameter, context); parameters.unshift(thisParameter); } var returnTypeNode; if (signature.typePredicate) { var typePredicate = signature.typePredicate; var parameterName = typePredicate.kind === 1 /* Identifier */ ? ts.setEmitFlags(ts.createIdentifier(typePredicate.parameterName), 16777216 /* NoAsciiEscaping */) : ts.createThisTypeNode(); var typeNode = typeToTypeNodeHelper(typePredicate.type, context); returnTypeNode = ts.createTypePredicateNode(parameterName, typeNode); } else { var returnType = getReturnTypeOfSignature(signature); returnTypeNode = returnType && typeToTypeNodeHelper(returnType, context); } if (context.flags & ts.NodeBuilderFlags.SuppressAnyReturnType) { if (returnTypeNode && returnTypeNode.kind === 119 /* AnyKeyword */) { returnTypeNode = undefined; } } else if (!returnTypeNode) { returnTypeNode = ts.createKeywordTypeNode(119 /* AnyKeyword */); } return ts.createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode); } function typeParameterToDeclaration(type, context) { var name = symbolToName(type.symbol, context, 793064 /* Type */, /*expectsIdentifier*/ true); var constraint = getConstraintFromTypeParameter(type); var constraintNode = constraint && typeToTypeNodeHelper(constraint, context); var defaultParameter = getDefaultFromTypeParameter(type); var defaultParameterNode = defaultParameter && typeToTypeNodeHelper(defaultParameter, context); return ts.createTypeParameterDeclaration(name, constraintNode, defaultParameterNode); } function symbolToParameterDeclaration(parameterSymbol, context) { var parameterDeclaration = ts.getDeclarationOfKind(parameterSymbol, 147 /* Parameter */); ts.Debug.assert(!!parameterDeclaration || isTransientSymbol(parameterSymbol) && !!parameterSymbol.isRestParameter); var parameterType = getTypeOfSymbol(parameterSymbol); if (parameterDeclaration && isRequiredInitializedParameter(parameterDeclaration)) { parameterType = getOptionalType(parameterType); } var parameterTypeNode = typeToTypeNodeHelper(parameterType, context); var modifiers = parameterDeclaration && parameterDeclaration.modifiers && parameterDeclaration.modifiers.map(ts.getSynthesizedClone); var dotDotDotToken = !parameterDeclaration || ts.isRestParameter(parameterDeclaration) ? ts.createToken(24 /* DotDotDotToken */) : undefined; var name = parameterDeclaration ? parameterDeclaration.name ? parameterDeclaration.name.kind === 71 /* Identifier */ ? ts.setEmitFlags(ts.getSynthesizedClone(parameterDeclaration.name), 16777216 /* NoAsciiEscaping */) : cloneBindingName(parameterDeclaration.name) : ts.symbolName(parameterSymbol) : ts.symbolName(parameterSymbol); var questionToken = parameterDeclaration && isOptionalParameter(parameterDeclaration) ? ts.createToken(55 /* QuestionToken */) : undefined; var parameterNode = ts.createParameter( /*decorators*/ undefined, modifiers, dotDotDotToken, name, questionToken, parameterTypeNode, /*initializer*/ undefined); return parameterNode; function cloneBindingName(node) { return elideInitializerAndSetEmitFlags(node); function elideInitializerAndSetEmitFlags(node) { var visited = ts.visitEachChild(node, elideInitializerAndSetEmitFlags, ts.nullTransformationContext, /*nodesVisitor*/ undefined, elideInitializerAndSetEmitFlags); var clone = ts.nodeIsSynthesized(visited) ? visited : ts.getSynthesizedClone(visited); if (clone.kind === 177 /* BindingElement */) { clone.initializer = undefined; } return ts.setEmitFlags(clone, 1 /* SingleLine */ | 16777216 /* NoAsciiEscaping */); } } } function symbolToName(symbol, context, meaning, expectsIdentifier) { // Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration. var chain; var isTypeParameter = symbol.flags & 262144 /* TypeParameter */; if (!isTypeParameter && (context.enclosingDeclaration || context.flags & ts.NodeBuilderFlags.UseFullyQualifiedType)) { chain = getSymbolChain(symbol, meaning, /*endOfChain*/ true); ts.Debug.assert(chain && chain.length > 0); } else { chain = [symbol]; } if (expectsIdentifier && chain.length !== 1 && !context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowQualifedNameInPlaceOfIdentifier)) { context.encounteredError = true; } return createEntityNameFromSymbolChain(chain, chain.length - 1); function createEntityNameFromSymbolChain(chain, index) { ts.Debug.assert(chain && 0 <= index && index < chain.length); var symbol = chain[index]; var typeParameterNodes; if (context.flags & ts.NodeBuilderFlags.WriteTypeParametersInQualifiedName && index > 0) { var parentSymbol = chain[index - 1]; var typeParameters = void 0; if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) { typeParameters = getTypeParametersOfClassOrInterface(parentSymbol); } else { var targetSymbol = getTargetSymbol(parentSymbol); if (targetSymbol.flags & (32 /* Class */ | 64 /* Interface */ | 524288 /* TypeAlias */)) { typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); } } typeParameterNodes = mapToTypeNodes(typeParameters, context); } var identifier = ts.setEmitFlags(ts.createIdentifier(getNameOfSymbolAsWritten(symbol, context), typeParameterNodes), 16777216 /* NoAsciiEscaping */); return index > 0 ? ts.createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1), identifier) : identifier; } /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function getSymbolChain(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/ false); var parentSymbol; if (!accessibleSymbolChain || needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { // Go up and add our parent. var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); if (parent) { var parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); if (parentChain) { parentSymbol = parent; accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]); } } } if (accessibleSymbolChain) { return accessibleSymbolChain; } if ( // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. endOfChain || // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && // If a parent symbol is an anonymous type, don't write it. !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) { return [symbol]; } } } } function typePredicateToString(typePredicate, enclosingDeclaration, flags) { return ts.usingSingleLineStringWriter(function (writer) { getSymbolDisplayBuilder().buildTypePredicateDisplay(typePredicate, writer, enclosingDeclaration, flags); }); } function formatUnionTypes(types) { var result = []; var flags = 0; for (var i = 0; i < types.length; i++) { var t = types[i]; flags |= t.flags; if (!(t.flags & 12288 /* Nullable */)) { if (t.flags & (128 /* BooleanLiteral */ | 256 /* EnumLiteral */)) { var baseType = t.flags & 128 /* BooleanLiteral */ ? booleanType : getBaseTypeOfEnumLiteralType(t); if (baseType.flags & 131072 /* Union */) { var count = baseType.types.length; if (i + count <= types.length && types[i + count - 1] === baseType.types[count - 1]) { result.push(baseType); i += count - 1; continue; } } } result.push(t); } } if (flags & 8192 /* Null */) result.push(nullType); if (flags & 4096 /* Undefined */) result.push(undefinedType); return result || types; } function visibilityToString(flags) { if (flags === 8 /* Private */) { return "private"; } if (flags === 16 /* Protected */) { return "protected"; } return "public"; } function getTypeAliasForTypeLiteral(type) { if (type.symbol && type.symbol.flags & 2048 /* TypeLiteral */) { var node = ts.findAncestor(type.symbol.declarations[0].parent, function (n) { return n.kind !== 169 /* ParenthesizedType */; }); if (node.kind === 232 /* TypeAliasDeclaration */) { return getSymbolOfNode(node); } } return undefined; } function isTopLevelInExternalModuleAugmentation(node) { return node && node.parent && node.parent.kind === 235 /* ModuleBlock */ && ts.isExternalModuleAugmentation(node.parent.parent); } function literalTypeToString(type) { return type.flags & 32 /* StringLiteral */ ? '"' + ts.escapeString(type.value) + '"' : "" + type.value; } /** * Gets a human-readable name for a symbol. * Should *not* be used for the right-hand side of a `.` -- use `symbolName(symbol)` for that instead. * * Unlike `symbolName(symbol)`, this will include quotes if the name is from a string literal. * It will also use a representation of a number as written instead of a decimal form, e.g. `0o11` instead of `9`. */ function getNameOfSymbolAsWritten(symbol, context) { if (symbol.declarations && symbol.declarations.length) { var declaration = symbol.declarations[0]; var name = ts.getNameOfDeclaration(declaration); if (name) { return ts.declarationNameToString(name); } if (declaration.parent && declaration.parent.kind === 227 /* VariableDeclaration */) { return ts.declarationNameToString(declaration.parent.name); } if (context && !context.encounteredError && !(context.flags & ts.NodeBuilderFlags.AllowAnonymousIdentifier)) { context.encounteredError = true; } switch (declaration.kind) { case 200 /* ClassExpression */: return "(Anonymous class)"; case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return "(Anonymous function)"; } } if (symbol.syntheticLiteralTypeOrigin) { var stringValue = symbol.syntheticLiteralTypeOrigin.value; if (!ts.isIdentifierText(stringValue, compilerOptions.target)) { return "\"" + ts.escapeString(stringValue, 34 /* doubleQuote */) + "\""; } } return ts.symbolName(symbol); } function getSymbolDisplayBuilder() { /** * Writes only the name of the symbol out to the writer. Uses the original source text * for the name of the symbol if it is available to match how the user wrote the name. */ function appendSymbolNameOnly(symbol, writer) { writer.writeSymbol(getNameOfSymbolAsWritten(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 = symbol.escapedName === "default" ? "default" : getNameOfSymbolAsWritten(symbol); var firstChar = symbolName.charCodeAt(0); var needsElementAccess = !ts.isIdentifierStart(firstChar, languageVersion); if (needsElementAccess) { if (firstChar !== 91 /* openBracket */) { writePunctuation(writer, 21 /* OpenBracketToken */); } if (ts.isSingleOrDoubleQuote(firstChar)) { writer.writeStringLiteral(symbolName); } else { writer.writeSymbol(symbolName, symbol); } if (firstChar !== 91 /* openBracket */) { writePunctuation(writer, 22 /* CloseBracketToken */); } } else { writePunctuation(writer, 23 /* DotToken */); writer.writeSymbol(symbolName, symbol); } } /** * Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope * Meaning needs to be specified if the enclosing declaration is given */ function buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags, typeFlags) { var parentSymbol; function appendParentTypeArgumentsAndSymbolName(symbol) { if (parentSymbol) { // Write type arguments of instantiated class/interface here if (flags & 1 /* WriteTypeParametersOrArguments */) { if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) { var params = getTypeParametersOfClassOrInterface(parentSymbol.flags & 2097152 /* Alias */ ? resolveAlias(parentSymbol) : parentSymbol); buildDisplayForTypeArgumentsAndDelimiters(params, symbol.mapper, writer, enclosingDeclaration); } else { buildTypeParameterDisplayFromSymbol(parentSymbol, writer, enclosingDeclaration); } } appendPropertyOrElementAccessForSymbol(symbol, writer); } else { appendSymbolNameOnly(symbol, writer); } parentSymbol = symbol; } // Let the writer know we just wrote out a symbol. The declaration emitter writer uses // this to determine if an import it has previously seen (and not written out) needs // to be written to the file once the walk of the tree is complete. // // NOTE(cyrusn): This approach feels somewhat unfortunate. A simple pass over the tree // up front (for example, during checking) could determine if we need to emit the imports // and we could then access that data during declaration emit. writer.trackSymbol(symbol, enclosingDeclaration, meaning); /** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */ function walkSymbol(symbol, meaning, endOfChain) { var accessibleSymbolChain = getAccessibleSymbolChain(symbol, enclosingDeclaration, meaning, !!(flags & 2 /* UseOnlyExternalAliasing */)); if (!accessibleSymbolChain || needsQualification(accessibleSymbolChain[0], enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) { // Go up and add our parent. var parent = getParentOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol); if (parent) { walkSymbol(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false); } } if (accessibleSymbolChain) { for (var _i = 0, accessibleSymbolChain_1 = accessibleSymbolChain; _i < accessibleSymbolChain_1.length; _i++) { var accessibleSymbol = accessibleSymbolChain_1[_i]; appendParentTypeArgumentsAndSymbolName(accessibleSymbol); } } else if ( // If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols. endOfChain || // If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.) !(!parentSymbol && ts.forEach(symbol.declarations, hasExternalModuleSymbol)) && // If a parent symbol is an anonymous type, don't write it. !(symbol.flags & (2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */))) { appendParentTypeArgumentsAndSymbolName(symbol); } } // Get qualified name if the symbol is not a type parameter // and there is an enclosing declaration or we specifically // asked for it var isTypeParameter = symbol.flags & 262144 /* TypeParameter */; var typeFormatFlag = 256 /* UseFullyQualifiedType */ & typeFlags; if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) { walkSymbol(symbol, meaning, /*endOfChain*/ true); } else { appendParentTypeArgumentsAndSymbolName(symbol); } } function buildTypeDisplay(type, writer, enclosingDeclaration, globalFlags, symbolStack) { var globalFlagsToPass = globalFlags & (32 /* WriteOwnNameForAnyLike */ | 16384 /* WriteClassExpressionAsTypeLiteral */); var inObjectTypeLiteral = false; return writeType(type, globalFlags); function writeType(type, flags) { var nextFlags = flags & ~1024 /* InTypeAlias */; // Write undefined/null type as any if (type.flags & 33585807 /* Intrinsic */) { // Special handling for unknown / resolving types, they should show up as any and not unknown or __resolving writer.writeKeyword(!(globalFlags & 32 /* WriteOwnNameForAnyLike */) && isTypeAny(type) ? "any" : type.intrinsicName); } else if (type.flags & 32768 /* TypeParameter */ && type.isThisType) { if (inObjectTypeLiteral) { writer.reportInaccessibleThisError(); } writer.writeKeyword("this"); } else if (ts.getObjectFlags(type) & 4 /* Reference */) { writeTypeReference(type, nextFlags); } else if (type.flags & 256 /* EnumLiteral */ && !(type.flags & 131072 /* Union */)) { var parent = getParentOfSymbol(type.symbol); buildSymbolDisplay(parent, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags); // In a literal enum type with a single member E { A }, E and E.A denote the // same type. We always display this type simply as E. if (getDeclaredTypeOfSymbol(parent) !== type) { writePunctuation(writer, 23 /* DotToken */); appendSymbolNameOnly(type.symbol, writer); } } else if (ts.getObjectFlags(type) & 3 /* ClassOrInterface */ || type.flags & (272 /* EnumLike */ | 32768 /* TypeParameter */)) { // The specified symbol flags need to be reinterpreted as type flags buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, nextFlags); } else if (!(flags & 1024 /* InTypeAlias */) && type.aliasSymbol && ((flags & 65536 /* UseAliasDefinedOutsideCurrentScope */) || isTypeSymbolAccessible(type.aliasSymbol, enclosingDeclaration))) { var typeArguments = type.aliasTypeArguments; writeSymbolTypeReference(type.aliasSymbol, typeArguments, 0, ts.length(typeArguments), nextFlags); } else if (type.flags & 393216 /* UnionOrIntersection */) { writeUnionOrIntersectionType(type, nextFlags); } else if (ts.getObjectFlags(type) & (16 /* Anonymous */ | 32 /* Mapped */)) { writeAnonymousType(type, nextFlags); } else if (type.flags & 1024 /* UniqueESSymbol */) { if (flags & 131072 /* AllowUniqueESSymbolType */) { writeKeyword(writer, 140 /* UniqueKeyword */); writeSpace(writer); } else { writer.reportInaccessibleUniqueSymbolError(); } writeKeyword(writer, 137 /* SymbolKeyword */); } else if (type.flags & 96 /* StringOrNumberLiteral */) { writer.writeStringLiteral(literalTypeToString(type)); } else if (type.flags & 524288 /* Index */) { if (flags & 128 /* InElementType */) { writePunctuation(writer, 19 /* OpenParenToken */); } writer.writeKeyword("keyof"); writeSpace(writer); writeType(type.type, 128 /* InElementType */); if (flags & 128 /* InElementType */) { writePunctuation(writer, 20 /* CloseParenToken */); } } else if (type.flags & 1048576 /* IndexedAccess */) { writeType(type.objectType, 128 /* InElementType */); writePunctuation(writer, 21 /* OpenBracketToken */); writeType(type.indexType, 0 /* None */); writePunctuation(writer, 22 /* CloseBracketToken */); } else { // Should never get here // { ... } writePunctuation(writer, 17 /* OpenBraceToken */); writeSpace(writer); writePunctuation(writer, 24 /* DotDotDotToken */); writeSpace(writer); writePunctuation(writer, 18 /* CloseBraceToken */); } } function writeTypeList(types, delimiter) { for (var i = 0; i < types.length; i++) { if (i > 0) { if (delimiter !== 26 /* CommaToken */) { writeSpace(writer); } writePunctuation(writer, delimiter); writeSpace(writer); } writeType(types[i], delimiter === 26 /* CommaToken */ ? 0 /* None */ : 128 /* InElementType */); } } function writeSymbolTypeReference(symbol, typeArguments, pos, end, flags) { // Unnamed function expressions and arrow functions have reserved names that we don't want to display if (symbol.flags & 32 /* Class */ || !isReservedMemberName(symbol.escapedName)) { buildSymbolDisplay(symbol, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags); } if (pos < end) { writePunctuation(writer, 27 /* LessThanToken */); writeType(typeArguments[pos], 512 /* InFirstTypeArgument */); pos++; while (pos < end) { writePunctuation(writer, 26 /* CommaToken */); writeSpace(writer); writeType(typeArguments[pos], 0 /* None */); pos++; } writePunctuation(writer, 29 /* GreaterThanToken */); } } function writeTypeReference(type, flags) { var typeArguments = type.typeArguments || ts.emptyArray; if (type.target === globalArrayType && !(flags & 1 /* WriteArrayAsGenericType */)) { writeType(typeArguments[0], 128 /* InElementType */ | 32768 /* InArrayType */); writePunctuation(writer, 21 /* OpenBracketToken */); writePunctuation(writer, 22 /* CloseBracketToken */); } else if (type.target.objectFlags & 8 /* Tuple */) { writePunctuation(writer, 21 /* OpenBracketToken */); writeTypeList(type.typeArguments.slice(0, getTypeReferenceArity(type)), 26 /* CommaToken */); writePunctuation(writer, 22 /* CloseBracketToken */); } else if (flags & 16384 /* WriteClassExpressionAsTypeLiteral */ && type.symbol.valueDeclaration && type.symbol.valueDeclaration.kind === 200 /* ClassExpression */) { writeAnonymousType(type, flags); } else { // Write the type reference in the format f.g.C where A and B are type arguments // for outer type parameters, and f and g are the respective declaring containers of those // type parameters. var outerTypeParameters = type.target.outerTypeParameters; var i = 0; if (outerTypeParameters) { var length_2 = outerTypeParameters.length; while (i < length_2) { // Find group of type arguments for type parameters with the same declaring container. var start = i; var parent = getParentSymbolOfTypeParameter(outerTypeParameters[i]); do { i++; } while (i < length_2 && getParentSymbolOfTypeParameter(outerTypeParameters[i]) === parent); // When type parameters are their own type arguments for the whole group (i.e. we have // the default outer type arguments), we don't show the group. if (!ts.rangeEquals(outerTypeParameters, typeArguments, start, i)) { writeSymbolTypeReference(parent, typeArguments, start, i, flags); writePunctuation(writer, 23 /* DotToken */); } } } var typeParameterCount = (type.target.typeParameters || ts.emptyArray).length; writeSymbolTypeReference(type.symbol, typeArguments, i, typeParameterCount, flags); } } function writeUnionOrIntersectionType(type, flags) { if (flags & 128 /* InElementType */) { writePunctuation(writer, 19 /* OpenParenToken */); } if (type.flags & 131072 /* Union */) { writeTypeList(formatUnionTypes(type.types), 49 /* BarToken */); } else { writeTypeList(type.types, 48 /* AmpersandToken */); } if (flags & 128 /* InElementType */) { writePunctuation(writer, 20 /* CloseParenToken */); } } function writeAnonymousType(type, flags) { var symbol = type.symbol; if (symbol) { // Always use 'typeof T' for type of class, enum, and module objects if (symbol.flags & 32 /* Class */ && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === 200 /* ClassExpression */ && flags & 16384 /* WriteClassExpressionAsTypeLiteral */) || symbol.flags & (384 /* Enum */ | 512 /* ValueModule */)) { writeTypeOfSymbol(type.symbol, flags); } else if (shouldWriteTypeOfFunctionSymbol()) { writeTypeOfSymbol(type.symbol, flags); } else if (ts.contains(symbolStack, symbol)) { // If type is an anonymous type literal in a type alias declaration, use type alias name var typeAlias = getTypeAliasForTypeLiteral(type); if (typeAlias) { // The specified symbol flags need to be reinterpreted as type flags buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, 793064 /* Type */, 0 /* None */, flags); } else { // Recursive usage, use any writeKeyword(writer, 119 /* AnyKeyword */); } } else { // Since instantiations of the same anonymous type have the same symbol, tracking symbols instead // of types allows us to catch circular references to instantiations of the same anonymous type // However, in case of class expressions, we want to write both the static side and the instance side. // We skip adding the static side so that the instance side has a chance to be written // before checking for circular references. if (!symbolStack) { symbolStack = []; } var isConstructorObject = type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & 32 /* Class */; if (isConstructorObject) { writeLiteralType(type, flags); } else { symbolStack.push(symbol); writeLiteralType(type, flags); symbolStack.pop(); } } } else { // Anonymous types with no symbol are never circular writeLiteralType(type, flags); } function shouldWriteTypeOfFunctionSymbol() { var isStaticMethodSymbol = !!(symbol.flags & 8192 /* Method */) && // typeof static method ts.some(symbol.declarations, function (declaration) { return ts.hasModifier(declaration, 32 /* Static */); }); var isNonLocalFunctionSymbol = !!(symbol.flags & 16 /* Function */) && (symbol.parent || // is exported function symbol ts.some(symbol.declarations, function (declaration) { return declaration.parent.kind === 269 /* SourceFile */ || declaration.parent.kind === 235 /* ModuleBlock */; })); if (isStaticMethodSymbol || isNonLocalFunctionSymbol) { // typeof is allowed only for static/non local functions return !!(flags & 4 /* UseTypeOfFunction */) || // use typeof if format flags specify it ts.contains(symbolStack, symbol); // it is type of the symbol uses itself recursively } } } function writeTypeOfSymbol(symbol, typeFormatFlags) { if (typeFormatFlags & 32768 /* InArrayType */) { writePunctuation(writer, 19 /* OpenParenToken */); } writeKeyword(writer, 103 /* TypeOfKeyword */); writeSpace(writer); buildSymbolDisplay(symbol, writer, enclosingDeclaration, 107455 /* Value */, 0 /* None */, typeFormatFlags); if (typeFormatFlags & 32768 /* InArrayType */) { writePunctuation(writer, 20 /* CloseParenToken */); } } function writePropertyWithModifiers(prop) { if (isReadonlySymbol(prop)) { writeKeyword(writer, 131 /* ReadonlyKeyword */); writeSpace(writer); } if (ts.getCheckFlags(prop) & 1024 /* Late */) { var decl = ts.firstOrUndefined(prop.declarations); var name = hasLateBindableName(decl) && resolveEntityName(decl.name.expression, 107455 /* Value */); if (name) { writer.trackSymbol(name, enclosingDeclaration, 107455 /* Value */); } } buildSymbolDisplay(prop, writer); if (prop.flags & 16777216 /* Optional */) { writePunctuation(writer, 55 /* QuestionToken */); } } function shouldAddParenthesisAroundFunctionType(callSignature, flags) { if (flags & 128 /* InElementType */) { return true; } else if (flags & 512 /* InFirstTypeArgument */) { // Add parenthesis around function type for the first type argument to avoid ambiguity var typeParameters = callSignature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */) ? callSignature.target.typeParameters : callSignature.typeParameters; return typeParameters && typeParameters.length !== 0; } return false; } function writeLiteralType(type, flags) { if (isGenericMappedType(type)) { writeMappedType(type); return; } var resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { writePunctuation(writer, 17 /* OpenBraceToken */); writePunctuation(writer, 18 /* CloseBraceToken */); return; } if (resolved.callSignatures.length === 1 && !resolved.constructSignatures.length) { var parenthesizeSignature = shouldAddParenthesisAroundFunctionType(resolved.callSignatures[0], flags); if (parenthesizeSignature) { writePunctuation(writer, 19 /* OpenParenToken */); } buildSignatureDisplay(resolved.callSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack); if (parenthesizeSignature) { writePunctuation(writer, 20 /* CloseParenToken */); } return; } if (resolved.constructSignatures.length === 1 && !resolved.callSignatures.length) { if (flags & 128 /* InElementType */) { writePunctuation(writer, 19 /* OpenParenToken */); } writeKeyword(writer, 94 /* NewKeyword */); writeSpace(writer); buildSignatureDisplay(resolved.constructSignatures[0], writer, enclosingDeclaration, globalFlagsToPass | 16 /* WriteArrowStyleSignature */, /*kind*/ undefined, symbolStack); if (flags & 128 /* InElementType */) { writePunctuation(writer, 20 /* CloseParenToken */); } return; } } var saveInObjectTypeLiteral = inObjectTypeLiteral; inObjectTypeLiteral = true; writePunctuation(writer, 17 /* OpenBraceToken */); writer.writeLine(); writer.increaseIndent(); writeObjectLiteralType(resolved); writer.decreaseIndent(); writePunctuation(writer, 18 /* CloseBraceToken */); inObjectTypeLiteral = saveInObjectTypeLiteral; } function writeObjectLiteralType(resolved) { for (var _i = 0, _a = resolved.callSignatures; _i < _a.length; _i++) { var signature = _a[_i]; buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); } for (var _b = 0, _c = resolved.constructSignatures; _b < _c.length; _b++) { var signature = _c[_b]; buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, 1 /* Construct */, symbolStack); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); } buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, 0 /* String */, enclosingDeclaration, globalFlags, symbolStack); buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, 1 /* Number */, enclosingDeclaration, globalFlags, symbolStack); for (var _d = 0, _e = resolved.properties; _d < _e.length; _d++) { var p = _e[_d]; if (globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */) { if (p.flags & 4194304 /* Prototype */) { continue; } if (ts.getDeclarationModifierFlagsFromSymbol(p) & (8 /* Private */ | 16 /* Protected */)) { writer.reportPrivateInBaseOfClassExpression(ts.symbolName(p)); } } var t = getTypeOfSymbol(p); if (p.flags & (16 /* Function */ | 8192 /* Method */) && !getPropertiesOfObjectType(t).length) { var signatures = getSignaturesOfType(t, 0 /* Call */); for (var _f = 0, signatures_2 = signatures; _f < signatures_2.length; _f++) { var signature = signatures_2[_f]; writePropertyWithModifiers(p); buildSignatureDisplay(signature, writer, enclosingDeclaration, globalFlagsToPass, /*kind*/ undefined, symbolStack); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); } } else { writePropertyWithModifiers(p); writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); writeType(t, globalFlags & 16384 /* WriteClassExpressionAsTypeLiteral */); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); } } } function writeMappedType(type) { writePunctuation(writer, 17 /* OpenBraceToken */); writer.writeLine(); writer.increaseIndent(); if (type.declaration.readonlyToken) { writeKeyword(writer, 131 /* ReadonlyKeyword */); writeSpace(writer); } writePunctuation(writer, 21 /* OpenBracketToken */); appendSymbolNameOnly(getTypeParameterFromMappedType(type).symbol, writer); writeSpace(writer); writeKeyword(writer, 92 /* InKeyword */); writeSpace(writer); writeType(getConstraintTypeFromMappedType(type), 0 /* None */); writePunctuation(writer, 22 /* CloseBracketToken */); if (type.declaration.questionToken) { writePunctuation(writer, 55 /* QuestionToken */); } writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); writeType(getTemplateTypeFromMappedType(type), 0 /* None */); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); writer.decreaseIndent(); writePunctuation(writer, 18 /* CloseBraceToken */); } } function buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration, flags) { var targetSymbol = getTargetSymbol(symbol); if (targetSymbol.flags & 32 /* Class */ || targetSymbol.flags & 64 /* Interface */ || targetSymbol.flags & 524288 /* TypeAlias */) { buildDisplayForTypeParametersAndDelimiters(getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol), writer, enclosingDeclaration, flags); } } function buildTypeParameterDisplay(tp, writer, enclosingDeclaration, flags, symbolStack) { appendSymbolNameOnly(tp.symbol, writer); var constraint = getConstraintOfTypeParameter(tp); if (constraint) { writeSpace(writer); writeKeyword(writer, 85 /* ExtendsKeyword */); writeSpace(writer); buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); } var defaultType = getDefaultFromTypeParameter(tp); if (defaultType) { writeSpace(writer); writePunctuation(writer, 58 /* EqualsToken */); writeSpace(writer); buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack); } } function buildParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack) { var parameterNode = p.valueDeclaration; if (parameterNode ? ts.isRestParameter(parameterNode) : isTransientSymbol(p) && p.isRestParameter) { writePunctuation(writer, 24 /* DotDotDotToken */); } if (parameterNode && ts.isBindingPattern(parameterNode.name)) { buildBindingPatternDisplay(parameterNode.name, writer, enclosingDeclaration, flags, symbolStack); } else { appendSymbolNameOnly(p, writer); } if (parameterNode && isOptionalParameter(parameterNode)) { writePunctuation(writer, 55 /* QuestionToken */); } writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); var type = getTypeOfSymbol(p); if (parameterNode && isRequiredInitializedParameter(parameterNode)) { type = getOptionalType(type); } buildTypeDisplay(type, writer, enclosingDeclaration, flags, symbolStack); } function buildBindingPatternDisplay(bindingPattern, writer, enclosingDeclaration, flags, symbolStack) { // We have to explicitly emit square bracket and bracket because these tokens are not stored inside the node. if (bindingPattern.kind === 175 /* ObjectBindingPattern */) { writePunctuation(writer, 17 /* OpenBraceToken */); buildDisplayForCommaSeparatedList(bindingPattern.elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); }); writePunctuation(writer, 18 /* CloseBraceToken */); } else if (bindingPattern.kind === 176 /* ArrayBindingPattern */) { writePunctuation(writer, 21 /* OpenBracketToken */); var elements = bindingPattern.elements; buildDisplayForCommaSeparatedList(elements, writer, function (e) { return buildBindingElementDisplay(e, writer, enclosingDeclaration, flags, symbolStack); }); if (elements && elements.hasTrailingComma) { writePunctuation(writer, 26 /* CommaToken */); } writePunctuation(writer, 22 /* CloseBracketToken */); } } function buildBindingElementDisplay(bindingElement, writer, enclosingDeclaration, flags, symbolStack) { if (ts.isOmittedExpression(bindingElement)) { return; } ts.Debug.assert(bindingElement.kind === 177 /* BindingElement */); if (bindingElement.propertyName) { writer.writeProperty(ts.getTextOfNode(bindingElement.propertyName)); writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); } if (ts.isBindingPattern(bindingElement.name)) { buildBindingPatternDisplay(bindingElement.name, writer, enclosingDeclaration, flags, symbolStack); } else { if (bindingElement.dotDotDotToken) { writePunctuation(writer, 24 /* DotDotDotToken */); } appendSymbolNameOnly(bindingElement.symbol, writer); } } function buildDisplayForTypeParametersAndDelimiters(typeParameters, writer, enclosingDeclaration, flags, symbolStack) { if (typeParameters && typeParameters.length) { writePunctuation(writer, 27 /* LessThanToken */); buildDisplayForCommaSeparatedList(typeParameters, writer, function (p) { return buildTypeParameterDisplay(p, writer, enclosingDeclaration, flags, symbolStack); }); writePunctuation(writer, 29 /* GreaterThanToken */); } } function buildDisplayForCommaSeparatedList(list, writer, action) { for (var i = 0; i < list.length; i++) { if (i > 0) { writePunctuation(writer, 26 /* CommaToken */); writeSpace(writer); } action(list[i]); } } function buildDisplayForTypeArgumentsAndDelimiters(typeParameters, mapper, writer, enclosingDeclaration) { if (typeParameters && typeParameters.length) { writePunctuation(writer, 27 /* LessThanToken */); var flags = 512 /* InFirstTypeArgument */; for (var i = 0; i < typeParameters.length; i++) { if (i > 0) { writePunctuation(writer, 26 /* CommaToken */); writeSpace(writer); flags = 0 /* None */; } buildTypeDisplay(mapper(typeParameters[i]), writer, enclosingDeclaration, flags); } writePunctuation(writer, 29 /* GreaterThanToken */); } } function buildDisplayForParametersAndDelimiters(thisParameter, parameters, writer, enclosingDeclaration, flags, symbolStack) { writePunctuation(writer, 19 /* OpenParenToken */); if (thisParameter) { buildParameterDisplay(thisParameter, writer, enclosingDeclaration, flags, symbolStack); } for (var i = 0; i < parameters.length; i++) { if (i > 0 || thisParameter) { writePunctuation(writer, 26 /* CommaToken */); writeSpace(writer); } buildParameterDisplay(parameters[i], writer, enclosingDeclaration, flags, symbolStack); } writePunctuation(writer, 20 /* CloseParenToken */); } function buildTypePredicateDisplay(predicate, writer, enclosingDeclaration, flags, symbolStack) { if (ts.isIdentifierTypePredicate(predicate)) { writer.writeParameter(predicate.parameterName); } else { writeKeyword(writer, 99 /* ThisKeyword */); } writeSpace(writer); writeKeyword(writer, 126 /* IsKeyword */); writeSpace(writer); buildTypeDisplay(predicate.type, writer, enclosingDeclaration, flags, symbolStack); } function buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack) { var returnType = getReturnTypeOfSignature(signature); if (flags & 4096 /* SuppressAnyReturnType */ && isTypeAny(returnType)) { return; } if (flags & 16 /* WriteArrowStyleSignature */) { writeSpace(writer); writePunctuation(writer, 36 /* EqualsGreaterThanToken */); } else { writePunctuation(writer, 56 /* ColonToken */); } writeSpace(writer); if (signature.typePredicate) { buildTypePredicateDisplay(signature.typePredicate, writer, enclosingDeclaration, flags, symbolStack); } else { buildTypeDisplay(returnType, writer, enclosingDeclaration, flags, symbolStack); } } function buildSignatureDisplay(signature, writer, enclosingDeclaration, flags, kind, symbolStack) { if (kind === 1 /* Construct */) { writeKeyword(writer, 94 /* NewKeyword */); writeSpace(writer); } if (signature.target && (flags & 64 /* WriteTypeArgumentsOfSignature */)) { // Instantiated signature, write type arguments instead // This is achieved by passing in the mapper separately buildDisplayForTypeArgumentsAndDelimiters(signature.target.typeParameters, signature.mapper, writer, enclosingDeclaration); } else { buildDisplayForTypeParametersAndDelimiters(signature.typeParameters, writer, enclosingDeclaration, flags, symbolStack); } buildDisplayForParametersAndDelimiters(signature.thisParameter, signature.parameters, writer, enclosingDeclaration, flags, symbolStack); buildReturnTypeDisplay(signature, writer, enclosingDeclaration, flags, symbolStack); } function buildIndexSignatureDisplay(info, writer, kind, enclosingDeclaration, globalFlags, symbolStack) { if (info) { if (info.isReadonly) { writeKeyword(writer, 131 /* ReadonlyKeyword */); writeSpace(writer); } writePunctuation(writer, 21 /* OpenBracketToken */); writer.writeParameter(info.declaration ? ts.declarationNameToString(info.declaration.parameters[0].name) : "x"); writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); switch (kind) { case 1 /* Number */: writeKeyword(writer, 133 /* NumberKeyword */); break; case 0 /* String */: writeKeyword(writer, 136 /* StringKeyword */); break; } writePunctuation(writer, 22 /* CloseBracketToken */); writePunctuation(writer, 56 /* ColonToken */); writeSpace(writer); buildTypeDisplay(info.type, writer, enclosingDeclaration, globalFlags, symbolStack); writePunctuation(writer, 25 /* SemicolonToken */); writer.writeLine(); } } return _displayBuilder || (_displayBuilder = { buildSymbolDisplay: buildSymbolDisplay, buildTypeDisplay: buildTypeDisplay, buildTypeParameterDisplay: buildTypeParameterDisplay, buildTypePredicateDisplay: buildTypePredicateDisplay, buildParameterDisplay: buildParameterDisplay, buildDisplayForParametersAndDelimiters: buildDisplayForParametersAndDelimiters, buildDisplayForTypeParametersAndDelimiters: buildDisplayForTypeParametersAndDelimiters, buildTypeParameterDisplayFromSymbol: buildTypeParameterDisplayFromSymbol, buildSignatureDisplay: buildSignatureDisplay, buildIndexSignatureDisplay: buildIndexSignatureDisplay, buildReturnTypeDisplay: buildReturnTypeDisplay }); } function isDeclarationVisible(node) { if (node) { var links = getNodeLinks(node); if (links.isVisible === undefined) { links.isVisible = !!determineIfDeclarationIsVisible(); } return links.isVisible; } return false; function determineIfDeclarationIsVisible() { switch (node.kind) { case 177 /* BindingElement */: return isDeclarationVisible(node.parent.parent); case 227 /* VariableDeclaration */: if (ts.isBindingPattern(node.name) && !node.name.elements.length) { // If the binding pattern is empty, this variable declaration is not visible return false; } // falls through case 234 /* ModuleDeclaration */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 229 /* FunctionDeclaration */: case 233 /* EnumDeclaration */: case 238 /* ImportEqualsDeclaration */: // external module augmentation is always visible if (ts.isExternalModuleAugmentation(node)) { return true; } var parent = getDeclarationContainer(node); // If the node is not exported or it is not ambient module element (except import declaration) if (!(ts.getCombinedModifierFlags(node) & 1 /* Export */) && !(node.kind !== 238 /* ImportEqualsDeclaration */ && parent.kind !== 269 /* SourceFile */ && parent.flags & 2097152 /* Ambient */)) { return isGlobalSourceFile(parent); } // Exported members/ambient module elements (exception import declaration) are visible if parent is visible return isDeclarationVisible(parent); case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.hasModifier(node, 8 /* Private */ | 16 /* Protected */)) { // Private/protected properties/methods are not visible return false; } // Public properties/methods are visible if its parents are visible, so: // falls through case 153 /* Constructor */: case 157 /* ConstructSignature */: case 156 /* CallSignature */: case 158 /* IndexSignature */: case 147 /* Parameter */: case 235 /* ModuleBlock */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 164 /* TypeLiteral */: case 160 /* TypeReference */: case 165 /* ArrayType */: case 166 /* TupleType */: case 167 /* UnionType */: case 168 /* IntersectionType */: case 169 /* 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 240 /* ImportClause */: case 241 /* NamespaceImport */: case 243 /* ImportSpecifier */: return false; // Type parameters are always visible case 146 /* TypeParameter */: // Source file and namespace export are always visible case 269 /* SourceFile */: case 237 /* NamespaceExportDeclaration */: return true; // Export assignments do not create name bindings outside the module case 244 /* ExportAssignment */: return false; default: return false; } } } function collectLinkedAliases(node, setVisibility) { var exportSymbol; if (node.parent && node.parent.kind === 244 /* ExportAssignment */) { exportSymbol = resolveName(node, node.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, node, /*isUse*/ false); } else if (node.parent.kind === 247 /* ExportSpecifier */) { exportSymbol = getTargetOfExportSpecifier(node.parent, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */); } var result; if (exportSymbol) { buildVisibleNodeList(exportSymbol.declarations); } return result; function buildVisibleNodeList(declarations) { ts.forEach(declarations, function (declaration) { var resultNode = getAnyImportSyntax(declaration) || declaration; if (setVisibility) { getNodeLinks(declaration).isVisible = true; } else { result = result || []; ts.pushIfUnique(result, resultNode); } if (ts.isInternalModuleImportEqualsDeclaration(declaration)) { // Add the referenced top container visible var internalModuleReference = declaration.moduleReference; var firstIdentifier = getFirstIdentifier(internalModuleReference); var importSymbol = resolveName(declaration, firstIdentifier.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */, undefined, undefined, /*isUse*/ false); if (importSymbol) { buildVisibleNodeList(importSymbol.declarations); } } }); } } /** * Push an entry on the type resolution stack. If an entry with the given target and the given property name * is already on the stack, and no entries in between already have a type, then a circularity has occurred. * In this case, the result values of the existing entry and all entries pushed after it are changed to false, * and the value false is returned. Otherwise, the new entry is just pushed onto the stack, and true is returned. * In order to see if the same query has already been done before, the target object and the propertyName both * must match the one passed in. * * @param target The symbol, type, or signature whose type is being queried * @param propertyName The property name that should be used to query the target for its type */ function pushTypeResolution(target, propertyName) { var resolutionCycleStartIndex = findResolutionCycleStartIndex(target, propertyName); if (resolutionCycleStartIndex >= 0) { // A cycle was found var length_3 = resolutionTargets.length; for (var i = resolutionCycleStartIndex; i < length_3; i++) { resolutionResults[i] = false; } return false; } resolutionTargets.push(target); resolutionResults.push(/*items*/ true); resolutionPropertyNames.push(propertyName); return true; } function findResolutionCycleStartIndex(target, propertyName) { for (var i = resolutionTargets.length - 1; i >= 0; i--) { if (hasType(resolutionTargets[i], resolutionPropertyNames[i])) { return -1; } if (resolutionTargets[i] === target && resolutionPropertyNames[i] === propertyName) { return i; } } return -1; } function hasType(target, propertyName) { if (propertyName === 0 /* Type */) { return getSymbolLinks(target).type; } if (propertyName === 2 /* DeclaredType */) { return getSymbolLinks(target).declaredType; } if (propertyName === 1 /* ResolvedBaseConstructorType */) { return target.resolvedBaseConstructorType; } if (propertyName === 3 /* ResolvedReturnType */) { return target.resolvedReturnType; } ts.Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } // Pop an entry from the type resolution stack and return its associated result value. The result value will // be true if no circularities were detected, or false if a circularity was found. function popTypeResolution() { resolutionTargets.pop(); resolutionPropertyNames.pop(); return resolutionResults.pop(); } function getDeclarationContainer(node) { node = ts.findAncestor(ts.getRootDeclaration(node), function (node) { switch (node.kind) { case 227 /* VariableDeclaration */: case 228 /* VariableDeclarationList */: case 243 /* ImportSpecifier */: case 242 /* NamedImports */: case 241 /* NamespaceImport */: case 240 /* ImportClause */: return false; default: return true; } }); return node && node.parent; } function getTypeOfPrototypeProperty(prototype) { // TypeScript 1.0 spec (April 2014): 8.4 // Every class automatically contains a static property member named 'prototype', // the type of which is an instantiation of the class type with type Any supplied as a type argument for each type parameter. // It is an error to explicitly declare a static property member with the name 'prototype'. var classType = getDeclaredTypeOfSymbol(getParentOfSymbol(prototype)); return classType.typeParameters ? createTypeReference(classType, ts.map(classType.typeParameters, function (_) { return anyType; })) : classType; } // Return the type of the given property in the given type, or undefined if no such property exists function getTypeOfPropertyOfType(type, name) { var prop = getPropertyOfType(type, name); return prop ? getTypeOfSymbol(prop) : undefined; } function isTypeAny(type) { return type && (type.flags & 1 /* Any */) !== 0; } // Return the type of a binding element parent. We check SymbolLinks first to see if a type has been // assigned by contextual typing. function getTypeForBindingElementParent(node) { var symbol = getSymbolOfNode(node); return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node, /*includeOptionality*/ false); } function isComputedNonLiteralName(name) { return name.kind === 145 /* ComputedPropertyName */ && !ts.isStringOrNumericLiteral(name.expression); } function getRestType(source, properties, symbol) { source = filterType(source, function (t) { return !(t.flags & 12288 /* Nullable */); }); if (source.flags & 16384 /* Never */) { return emptyObjectType; } if (source.flags & 131072 /* Union */) { return mapType(source, function (t) { return getRestType(t, properties, symbol); }); } var members = ts.createSymbolTable(); var names = ts.createUnderscoreEscapedMap(); for (var _i = 0, properties_2 = properties; _i < properties_2.length; _i++) { var name = properties_2[_i]; names.set(ts.getTextOfPropertyName(name), true); } for (var _a = 0, _b = getPropertiesOfType(source); _a < _b.length; _a++) { var prop = _b[_a]; var inNamesToRemove = names.has(prop.escapedName); var isPrivate = ts.getDeclarationModifierFlagsFromSymbol(prop) & (8 /* Private */ | 16 /* Protected */); var isSetOnlyAccessor = prop.flags & 65536 /* SetAccessor */ && !(prop.flags & 32768 /* GetAccessor */); if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) { members.set(prop.escapedName, prop); } } var stringIndexInfo = getIndexInfoOfType(source, 0 /* String */); var numberIndexInfo = getIndexInfoOfType(source, 1 /* Number */); return createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo); } /** Return the inferred type for a binding element */ function getTypeForBindingElement(declaration) { var pattern = declaration.parent; var parentType = getTypeForBindingElementParent(pattern.parent); // If parent has the unknown (error) type, then so does this binding element if (parentType === unknownType) { return unknownType; } // If no type was specified or inferred for parent, // infer from the initializer of the binding element if one is present. // Otherwise, go with the undefined type of the parent. if (!parentType) { return declaration.initializer ? checkDeclarationInitializer(declaration) : parentType; } if (isTypeAny(parentType)) { return parentType; } var type; if (pattern.kind === 175 /* ObjectBindingPattern */) { if (declaration.dotDotDotToken) { if (!isValidSpreadType(parentType)) { error(declaration, ts.Diagnostics.Rest_types_may_only_be_created_from_object_types); return unknownType; } var literalMembers = []; for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!element.dotDotDotToken) { literalMembers.push(element.propertyName || element.name); } } type = getRestType(parentType, literalMembers, declaration.symbol); } else { // Use explicitly specified property name ({ p: xxx } form), or otherwise the implied name ({ p } form) var name = declaration.propertyName || declaration.name; if (isComputedNonLiteralName(name)) { // computed properties with non-literal names are treated as 'any' return anyType; } // Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature, // or otherwise the type of the string index signature. var text = ts.getTextOfPropertyName(name); // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation if (strictNullChecks && declaration.flags & 2097152 /* Ambient */ && ts.isParameterDeclaration(declaration)) { parentType = getNonNullableType(parentType); } var declaredType = getTypeOfPropertyOfType(parentType, text); type = declaredType && getFlowTypeOfReference(declaration, declaredType) || isNumericLiteralName(text) && getIndexTypeOfType(parentType, 1 /* Number */) || getIndexTypeOfType(parentType, 0 /* String */); if (!type) { error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(parentType), ts.declarationNameToString(name)); return unknownType; } } } else { // This elementType will be used if the specific property corresponding to this index is not // present (aka the tuple element property). This call also checks that the parentType is in // fact an iterable or array (depending on target language). var elementType = checkIteratedTypeOrElementType(parentType, pattern, /*allowStringInput*/ false, /*allowAsyncIterables*/ false); if (declaration.dotDotDotToken) { // Rest element has an array type with the same element type as the parent type type = createArrayType(elementType); } else { // Use specific property type when parent is a tuple or numeric index type when parent is an array var propName = "" + ts.indexOf(pattern.elements, declaration); type = isTupleLikeType(parentType) ? getTypeOfPropertyOfType(parentType, propName) : elementType; if (!type) { if (isTupleType(parentType)) { error(declaration, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(parentType), getTypeReferenceArity(parentType), pattern.elements.length); } else { error(declaration, ts.Diagnostics.Type_0_has_no_property_1, typeToString(parentType), propName); } return unknownType; } } } // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. if (strictNullChecks && declaration.initializer && !(getFalsyFlags(checkExpressionCached(declaration.initializer)) & 4096 /* Undefined */)) { type = getTypeWithFacts(type, 131072 /* NEUndefined */); } return declaration.initializer ? getUnionType([type, checkExpressionCached(declaration.initializer)], /*subtypeReduction*/ true) : type; } function getTypeForDeclarationFromJSDocComment(declaration) { var jsdocType = ts.getJSDocType(declaration); if (jsdocType) { return getTypeFromTypeNode(jsdocType); } return undefined; } function isNullOrUndefined(node) { var expr = ts.skipParentheses(node); return expr.kind === 95 /* NullKeyword */ || expr.kind === 71 /* Identifier */ && getResolvedSymbol(expr) === undefinedSymbol; } function isEmptyArrayLiteral(node) { var expr = ts.skipParentheses(node); return expr.kind === 178 /* ArrayLiteralExpression */ && expr.elements.length === 0; } function addOptionality(type, optional) { if (optional === void 0) { optional = true; } return strictNullChecks && optional ? getOptionalType(type) : type; } // Return the inferred type for a variable, parameter, or property declaration function getTypeForVariableLikeDeclaration(declaration, includeOptionality) { // A variable declared in a for..in statement is of type string, or of type keyof T when the // right hand expression is of a type parameter type. if (declaration.parent.parent.kind === 216 /* ForInStatement */) { var indexType = getIndexType(checkNonNullExpression(declaration.parent.parent.expression)); return indexType.flags & (32768 /* TypeParameter */ | 524288 /* Index */) ? indexType : stringType; } if (declaration.parent.parent.kind === 217 /* ForOfStatement */) { // checkRightHandSideOfForOf will return undefined if the for-of expression type was // missing properties/signatures required to get its iteratedType (like // [Symbol.iterator] or next). This may be because we accessed properties from anyType, // or it may have led to an error inside getElementTypeOfIterable. var forOfStatement = declaration.parent.parent; return checkRightHandSideOfForOf(forOfStatement.expression, forOfStatement.awaitModifier) || anyType; } if (ts.isBindingPattern(declaration.parent)) { return getTypeForBindingElement(declaration); } // Use type from type annotation if one is present var typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode) { var declaredType = getTypeFromTypeNode(typeNode); return addOptionality(declaredType, /*optional*/ !!declaration.questionToken && includeOptionality); } if ((noImplicitAny || ts.isInJavaScriptFile(declaration)) && declaration.kind === 227 /* VariableDeclaration */ && !ts.isBindingPattern(declaration.name) && !(ts.getCombinedModifierFlags(declaration) & 1 /* Export */) && !(declaration.flags & 2097152 /* Ambient */)) { // If --noImplicitAny is on or the declaration is in a Javascript file, // use control flow tracked 'any' type for non-ambient, non-exported var or let variables with no // initializer or a 'null' or 'undefined' initializer. if (!(ts.getCombinedNodeFlags(declaration) & 2 /* Const */) && (!declaration.initializer || isNullOrUndefined(declaration.initializer))) { return autoType; } // Use control flow tracked 'any[]' type for non-ambient, non-exported variables with an empty array // literal initializer. if (declaration.initializer && isEmptyArrayLiteral(declaration.initializer)) { return autoArrayType; } } if (declaration.kind === 147 /* 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 === 155 /* SetAccessor */ && !hasNonBindableDynamicName(func)) { var getter = ts.getDeclarationOfKind(getSymbolOfNode(declaration.parent), 154 /* GetAccessor */); if (getter) { var getterSignature = getSignatureFromDeclaration(getter); var thisParameter = getAccessorThisParameter(func); if (thisParameter && declaration === thisParameter) { // Use the type from the *getter* ts.Debug.assert(!thisParameter.type); return getTypeOfSymbol(getterSignature.thisParameter); } return getReturnTypeOfSignature(getterSignature); } } // Use contextual parameter type if one is available var type = void 0; if (declaration.symbol.escapedName === "this") { type = getContextualThisParameterType(func); } else { type = getContextuallyTypedParameterType(declaration); } if (type) { return addOptionality(type, /*optional*/ !!declaration.questionToken && includeOptionality); } } // Use the type of the initializer expression if one is present if (declaration.initializer) { var type = checkDeclarationInitializer(declaration); return addOptionality(type, /*optional*/ !!declaration.questionToken && includeOptionality); } if (ts.isJsxAttribute(declaration)) { // if JSX attribute doesn't have initializer, by default the attribute will have boolean value of true. // I.e is sugar for return trueType; } // If it is a short-hand property assignment, use the type of the identifier if (declaration.kind === 266 /* ShorthandPropertyAssignment */) { return checkIdentifier(declaration.name); } // If the declaration specifies a binding pattern, use the type implied by the binding pattern if (ts.isBindingPattern(declaration.name)) { return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true); } // No type specified and nothing can be inferred return undefined; } function getWidenedTypeFromJSSpecialPropertyDeclarations(symbol) { var types = []; var definedInConstructor = false; var definedInMethod = false; var jsDocType; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; var expression = declaration.kind === 195 /* BinaryExpression */ ? declaration : declaration.kind === 180 /* PropertyAccessExpression */ ? ts.getAncestor(declaration, 195 /* BinaryExpression */) : undefined; if (!expression) { return unknownType; } if (ts.isPropertyAccessExpression(expression.left) && expression.left.expression.kind === 99 /* ThisKeyword */) { if (ts.getThisContainer(expression, /*includeArrowFunctions*/ false).kind === 153 /* Constructor */) { definedInConstructor = true; } else { definedInMethod = true; } } // If there is a JSDoc type, use it var type_1 = getTypeForDeclarationFromJSDocComment(expression.parent); if (type_1) { var declarationType = getWidenedType(type_1); if (!jsDocType) { jsDocType = declarationType; } else if (jsDocType !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(jsDocType, declarationType) && !(symbol.flags & 67108864 /* JSContainer */)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(jsDocType, declaration, declarationType); } } else if (!jsDocType) { // If we don't have an explicit JSDoc type, get the type from the expression. types.push(getWidenedLiteralType(checkExpressionCached(expression.right))); } } var type = jsDocType || getUnionType(types, /*subtypeReduction*/ true); return getWidenedType(addOptionality(type, definedInMethod && !definedInConstructor)); } // Return the type implied by a binding pattern element. This is the type of the initializer of the element if // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding // pattern. Otherwise, it is the type any. function getTypeFromBindingElement(element, includePatternInType, reportErrors) { if (element.initializer) { return checkDeclarationInitializer(element); } if (ts.isBindingPattern(element.name)) { return getTypeFromBindingPattern(element.name, includePatternInType, reportErrors); } if (reportErrors && noImplicitAny && !declarationBelongsToPrivateAmbientMember(element)) { reportImplicitAnyError(element, anyType); } return anyType; } // Return the type implied by an object binding pattern function getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) { var members = ts.createSymbolTable(); var stringIndexInfo; var hasComputedProperties = false; ts.forEach(pattern.elements, function (e) { var name = e.propertyName || e.name; if (isComputedNonLiteralName(name)) { // do not include computed properties in the implied type hasComputedProperties = true; return; } if (e.dotDotDotToken) { stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); return; } var text = ts.getTextOfPropertyName(name); var flags = 4 /* Property */ | (e.initializer ? 16777216 /* Optional */ : 0); var symbol = createSymbol(flags, text); symbol.type = getTypeFromBindingElement(e, includePatternInType, reportErrors); symbol.bindingElement = e; members.set(symbol.escapedName, symbol); }); var result = createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined); if (includePatternInType) { result.pattern = pattern; } if (hasComputedProperties) { result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */; } return result; } // Return the type implied by an array binding pattern function getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors) { var elements = pattern.elements; var lastElement = ts.lastOrUndefined(elements); if (elements.length === 0 || (!ts.isOmittedExpression(lastElement) && lastElement.dotDotDotToken)) { return languageVersion >= 2 /* ES2015 */ ? createIterableType(anyType) : anyArrayType; } // If the pattern has at least one element, and no rest element, then it should imply a tuple type. var elementTypes = ts.map(elements, function (e) { return ts.isOmittedExpression(e) ? anyType : getTypeFromBindingElement(e, includePatternInType, reportErrors); }); var result = createTupleType(elementTypes); if (includePatternInType) { result = cloneTypeReference(result); result.pattern = pattern; } return result; } // Return the type implied by a binding pattern. This is the type implied purely by the binding pattern itself // and without regard to its context (i.e. without regard any type annotation or initializer associated with the // declaration in which the binding pattern is contained). For example, the implied type of [x, y] is [any, any] // and the implied type of { x, y: z = 1 } is { x: any; y: number; }. The type implied by a binding pattern is // used as the contextual type of an initializer associated with the binding pattern. Also, for a destructuring // parameter with no type annotation or initializer, the type implied by the binding pattern becomes the type of // the parameter. function getTypeFromBindingPattern(pattern, includePatternInType, reportErrors) { return pattern.kind === 175 /* ObjectBindingPattern */ ? getTypeFromObjectBindingPattern(pattern, includePatternInType, reportErrors) : getTypeFromArrayBindingPattern(pattern, includePatternInType, reportErrors); } // Return the type associated with a variable, parameter, or property declaration. In the simple case this is the type // specified in a type annotation or inferred from an initializer. However, in the case of a destructuring declaration it // is a bit more involved. For example: // // var [x, s = ""] = [1, "one"]; // // Here, the array literal [1, "one"] is contextually typed by the type [any, string], which is the implied type of the // binding pattern [x, s = ""]. Because the contextual type is a tuple type, the resulting type of [1, "one"] is the // tuple type [number, string]. Thus, the type inferred for 'x' is number and the type inferred for 's' is string. function getWidenedTypeForVariableLikeDeclaration(declaration, reportErrors) { var type = getTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); if (type) { if (reportErrors) { reportErrorsFromWidening(declaration, type); } // always widen a 'unique symbol' type if the type was created for a different declaration. if (type.flags & 1024 /* UniqueESSymbol */ && !declaration.type && type.symbol !== getSymbolOfNode(declaration)) { type = esSymbolType; } // 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 === 265 /* PropertyAssignment */) { return type; } return getWidenedType(type); } // Rest parameters default to type any[], other parameters default to type any type = declaration.dotDotDotToken ? anyArrayType : anyType; // Report implicit any errors unless this is a private property within an ambient declaration if (reportErrors && noImplicitAny) { if (!declarationBelongsToPrivateAmbientMember(declaration)) { reportImplicitAnyError(declaration, type); } } return type; } function declarationBelongsToPrivateAmbientMember(declaration) { var root = ts.getRootDeclaration(declaration); var memberDeclaration = root.kind === 147 /* Parameter */ ? root.parent : root; return isPrivateWithinAmbient(memberDeclaration); } function getTypeOfVariableOrParameterOrProperty(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { // Handle prototype property if (symbol.flags & 4194304 /* Prototype */) { return links.type = getTypeOfPrototypeProperty(symbol); } // Handle catch clause variables var declaration = symbol.valueDeclaration; if (ts.isCatchClauseVariableDeclarationOrBindingElement(declaration)) { return links.type = anyType; } // Handle export default expressions if (declaration.kind === 244 /* ExportAssignment */) { return links.type = checkExpression(declaration.expression); } if (ts.isInJavaScriptFile(declaration) && ts.isJSDocPropertyLikeTag(declaration) && declaration.typeExpression) { return links.type = getTypeFromTypeNode(declaration.typeExpression.type); } // Handle variable, parameter or property if (!pushTypeResolution(symbol, 0 /* Type */)) { return unknownType; } var type = void 0; // Handle certain special assignment kinds, which happen to union across multiple declarations: // * module.exports = expr // * exports.p = expr // * this.p = expr // * className.prototype.method = expr if (declaration.kind === 195 /* BinaryExpression */ || declaration.kind === 180 /* PropertyAccessExpression */ && declaration.parent.kind === 195 /* BinaryExpression */) { type = getWidenedTypeFromJSSpecialPropertyDeclarations(symbol); } else { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*reportErrors*/ true); } if (!popTypeResolution()) { type = reportCircularityError(symbol); } links.type = type; } return links.type; } function getAnnotatedAccessorType(accessor) { if (accessor) { if (accessor.kind === 154 /* GetAccessor */) { var getterTypeAnnotation = ts.getEffectiveReturnTypeNode(accessor); return getterTypeAnnotation && getTypeFromTypeNode(getterTypeAnnotation); } else { var setterTypeAnnotation = ts.getEffectiveSetAccessorTypeAnnotationNode(accessor); return setterTypeAnnotation && getTypeFromTypeNode(setterTypeAnnotation); } } return undefined; } function getAnnotatedAccessorThisParameter(accessor) { var parameter = getAccessorThisParameter(accessor); return parameter && parameter.symbol; } function getThisTypeOfDeclaration(declaration) { return getThisTypeOfSignature(getSignatureFromDeclaration(declaration)); } function getTypeOfAccessors(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { var getter = ts.getDeclarationOfKind(symbol, 154 /* GetAccessor */); var setter = ts.getDeclarationOfKind(symbol, 155 /* SetAccessor */); if (getter && ts.isInJavaScriptFile(getter)) { var jsDocType = getTypeForDeclarationFromJSDocComment(getter); if (jsDocType) { return links.type = jsDocType; } } if (!pushTypeResolution(symbol, 0 /* Type */)) { return unknownType; } var type = void 0; // First try to see if the user specified a return type on the get-accessor. var getterReturnType = getAnnotatedAccessorType(getter); if (getterReturnType) { type = getterReturnType; } else { // If the user didn't specify a return type, try to use the set-accessor's parameter type. var setterParameterType = getAnnotatedAccessorType(setter); if (setterParameterType) { type = setterParameterType; } else { // If there are no specified types, try to infer it from the body of the get accessor if it exists. if (getter && getter.body) { type = getReturnTypeFromBody(getter); } else { if (noImplicitAny) { if (setter) { error(setter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation, symbolToString(symbol)); } else { ts.Debug.assert(!!getter, "there must existed getter as we are current checking either setter or getter in this function"); error(getter, ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation, symbolToString(symbol)); } } type = anyType; } } } if (!popTypeResolution()) { type = anyType; if (noImplicitAny) { var getter_1 = ts.getDeclarationOfKind(symbol, 154 /* GetAccessor */); error(getter_1, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol)); } } links.type = type; } return links.type; } function getBaseTypeVariableOfClass(symbol) { var baseConstructorType = getBaseConstructorTypeOfClass(getDeclaredTypeOfClassOrInterface(symbol)); return baseConstructorType.flags & 1081344 /* TypeVariable */ ? baseConstructorType : undefined; } function getTypeOfFuncClassEnumModule(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { if (symbol.flags & 1536 /* Module */ && ts.isShorthandAmbientModuleSymbol(symbol)) { links.type = anyType; } else { var type = createObjectType(16 /* Anonymous */, symbol); if (symbol.flags & 32 /* Class */) { var baseTypeVariable = getBaseTypeVariableOfClass(symbol); links.type = baseTypeVariable ? getIntersectionType([type, baseTypeVariable]) : type; } else { links.type = strictNullChecks && symbol.flags & 16777216 /* Optional */ ? getOptionalType(type) : type; } } } return links.type; } function getTypeOfEnumMember(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { links.type = getDeclaredTypeOfEnumMember(symbol); } return links.type; } function getTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { var targetSymbol = resolveAlias(symbol); // It only makes sense to get the type of a value symbol. If the result of resolving // the alias is not a value, then it has no type. To get the type associated with a // type symbol, call getDeclaredTypeOfSymbol. // This check is important because without it, a call to getTypeOfSymbol could end // up recursively calling getTypeOfAlias, causing a stack overflow. links.type = targetSymbol.flags & 107455 /* Value */ ? getTypeOfSymbol(targetSymbol) : unknownType; } return links.type; } function getTypeOfInstantiatedSymbol(symbol) { var links = getSymbolLinks(symbol); if (!links.type) { if (symbolInstantiationDepth === 100) { error(symbol.valueDeclaration, ts.Diagnostics.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite); links.type = unknownType; } else { if (!pushTypeResolution(symbol, 0 /* Type */)) { return unknownType; } symbolInstantiationDepth++; var type = instantiateType(getTypeOfSymbol(links.target), links.mapper); symbolInstantiationDepth--; if (!popTypeResolution()) { type = reportCircularityError(symbol); } links.type = type; } } return links.type; } function reportCircularityError(symbol) { // Check if variable has type annotation that circularly references the variable itself if (ts.getEffectiveTypeAnnotationNode(symbol.valueDeclaration)) { error(symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_type_annotation, symbolToString(symbol)); return unknownType; } // Otherwise variable has initializer that circularly references the variable itself if (noImplicitAny) { error(symbol.valueDeclaration, ts.Diagnostics._0_implicitly_has_type_any_because_it_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer, symbolToString(symbol)); } return anyType; } function getTypeOfSymbol(symbol) { if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) { return getTypeOfInstantiatedSymbol(symbol); } if (symbol.flags & (3 /* Variable */ | 4 /* Property */)) { return getTypeOfVariableOrParameterOrProperty(symbol); } if (symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 384 /* Enum */ | 512 /* ValueModule */)) { return getTypeOfFuncClassEnumModule(symbol); } if (symbol.flags & 8 /* EnumMember */) { return getTypeOfEnumMember(symbol); } if (symbol.flags & 98304 /* Accessor */) { return getTypeOfAccessors(symbol); } if (symbol.flags & 2097152 /* Alias */) { return getTypeOfAlias(symbol); } return unknownType; } function isReferenceToType(type, target) { return type !== undefined && target !== undefined && (ts.getObjectFlags(type) & 4 /* Reference */) !== 0 && type.target === target; } function getTargetType(type) { return ts.getObjectFlags(type) & 4 /* Reference */ ? type.target : type; } function hasBaseType(type, checkBase) { return check(type); function check(type) { if (ts.getObjectFlags(type) & (3 /* ClassOrInterface */ | 4 /* Reference */)) { var target = getTargetType(type); return target === checkBase || ts.forEach(getBaseTypes(target), check); } else if (type.flags & 262144 /* Intersection */) { return ts.forEach(type.types, check); } } } // Appends the type parameters given by a list of declarations to a set of type parameters and returns the resulting set. // The function allocates a new array if the input type parameter set is undefined, but otherwise it modifies the set // in-place and returns the same array. function appendTypeParameters(typeParameters, declarations) { for (var _i = 0, declarations_2 = declarations; _i < declarations_2.length; _i++) { var declaration = declarations_2[_i]; var tp = getDeclaredTypeOfTypeParameter(getSymbolOfNode(declaration)); typeParameters = ts.appendIfUnique(typeParameters, tp); } return typeParameters; } // Return the outer type parameters of a node or undefined if the node has no outer type parameters. function getOuterTypeParameters(node, includeThisTypes) { while (true) { node = node.parent; if (!node) { return undefined; } switch (node.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 151 /* MethodSignature */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 277 /* JSDocFunctionType */: case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 232 /* TypeAliasDeclaration */: case 287 /* JSDocTemplateTag */: case 173 /* MappedType */: var outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); if (node.kind === 173 /* MappedType */) { return ts.append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter))); } var outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, ts.getEffectiveTypeParameterDeclarations(node) || ts.emptyArray); var thisType = includeThisTypes && (node.kind === 230 /* ClassDeclaration */ || node.kind === 200 /* ClassExpression */ || node.kind === 231 /* InterfaceDeclaration */) && getDeclaredTypeOfClassOrInterface(getSymbolOfNode(node)).thisType; return thisType ? ts.append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; } } } // The outer type parameters are those defined by enclosing generic classes, methods, or functions. function getOuterTypeParametersOfClassOrInterface(symbol) { var declaration = symbol.flags & 32 /* Class */ ? symbol.valueDeclaration : ts.getDeclarationOfKind(symbol, 231 /* InterfaceDeclaration */); return getOuterTypeParameters(declaration); } // The local type parameters are the combined set of type parameters from all declarations of the class, // interface, or type alias. function getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) { var result; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var node = _a[_i]; if (node.kind === 231 /* InterfaceDeclaration */ || node.kind === 230 /* ClassDeclaration */ || node.kind === 200 /* ClassExpression */ || node.kind === 232 /* TypeAliasDeclaration */) { var declaration = node; if (declaration.typeParameters) { result = appendTypeParameters(result, declaration.typeParameters); } } } return result; } // The full set of type parameters for a generic class or interface type consists of its outer type parameters plus // its locally declared type parameters. function getTypeParametersOfClassOrInterface(symbol) { return ts.concatenate(getOuterTypeParametersOfClassOrInterface(symbol), getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol)); } // A type is a mixin constructor if it has a single construct signature taking no type parameters and a single // rest parameter of type any[]. function isMixinConstructorType(type) { var signatures = getSignaturesOfType(type, 1 /* Construct */); if (signatures.length === 1) { var s = signatures[0]; return !s.typeParameters && s.parameters.length === 1 && s.hasRestParameter && getTypeOfParameter(s.parameters[0]) === anyArrayType; } return false; } function isConstructorType(type) { if (isValidBaseType(type) && getSignaturesOfType(type, 1 /* Construct */).length > 0) { return true; } if (type.flags & 1081344 /* TypeVariable */) { var constraint = getBaseConstraintOfType(type); return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint); } return false; } function getBaseTypeNodeOfClass(type) { var decl = type.symbol.valueDeclaration; if (ts.isInJavaScriptFile(decl)) { // Prefer an @augments tag because it may have type parameters. var tag = ts.getJSDocAugmentsTag(decl); if (tag) { return tag.class; } } return ts.getClassExtendsHeritageClauseElement(decl); } function getConstructorsForTypeArguments(type, typeArgumentNodes, location) { var typeArgCount = ts.length(typeArgumentNodes); var isJavaScript = ts.isInJavaScriptFile(location); return ts.filter(getSignaturesOfType(type, 1 /* Construct */), function (sig) { return (isJavaScript || typeArgCount >= getMinTypeArgumentCount(sig.typeParameters)) && typeArgCount <= ts.length(sig.typeParameters); }); } function getInstantiatedConstructorsForTypeArguments(type, typeArgumentNodes, location) { var signatures = getConstructorsForTypeArguments(type, typeArgumentNodes, location); var typeArguments = ts.map(typeArgumentNodes, getTypeFromTypeNode); return ts.sameMap(signatures, function (sig) { return ts.some(sig.typeParameters) ? getSignatureInstantiation(sig, typeArguments, ts.isInJavaScriptFile(location)) : sig; }); } /** * The base constructor of a class can resolve to * * undefinedType if the class has no extends clause, * * unknownType if an error occurred during resolution of the extends expression, * * nullType if the extends expression is the null value, * * anyType if the extends expression has type any, or * * an object type with at least one construct signature. */ function getBaseConstructorTypeOfClass(type) { if (!type.resolvedBaseConstructorType) { var decl = type.symbol.valueDeclaration; var extended = ts.getClassExtendsHeritageClauseElement(decl); var baseTypeNode = getBaseTypeNodeOfClass(type); if (!baseTypeNode) { return type.resolvedBaseConstructorType = undefinedType; } if (!pushTypeResolution(type, 1 /* ResolvedBaseConstructorType */)) { return unknownType; } var baseConstructorType = checkExpression(baseTypeNode.expression); if (extended && baseTypeNode !== extended) { ts.Debug.assert(!extended.typeArguments); // Because this is in a JS file, and baseTypeNode is in an @extends tag checkExpression(extended.expression); } if (baseConstructorType.flags & (65536 /* Object */ | 262144 /* Intersection */)) { // Resolving the members of a class requires us to resolve the base class of that class. // We force resolution here such that we catch circularities now. resolveStructuredTypeMembers(baseConstructorType); } if (!popTypeResolution()) { error(type.symbol.valueDeclaration, ts.Diagnostics._0_is_referenced_directly_or_indirectly_in_its_own_base_expression, symbolToString(type.symbol)); return type.resolvedBaseConstructorType = unknownType; } if (!(baseConstructorType.flags & 1 /* Any */) && baseConstructorType !== nullWideningType && !isConstructorType(baseConstructorType)) { error(baseTypeNode.expression, ts.Diagnostics.Type_0_is_not_a_constructor_function_type, typeToString(baseConstructorType)); return type.resolvedBaseConstructorType = unknownType; } type.resolvedBaseConstructorType = baseConstructorType; } return type.resolvedBaseConstructorType; } function getBaseTypes(type) { if (!type.resolvedBaseTypes) { if (type.objectFlags & 8 /* Tuple */) { type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; } else if (type.symbol.flags & (32 /* Class */ | 64 /* Interface */)) { if (type.symbol.flags & 32 /* Class */) { resolveBaseTypesOfClass(type); } if (type.symbol.flags & 64 /* Interface */) { resolveBaseTypesOfInterface(type); } } else { ts.Debug.fail("type must be class or interface"); } } return type.resolvedBaseTypes; } function resolveBaseTypesOfClass(type) { type.resolvedBaseTypes = ts.emptyArray; var baseConstructorType = getApparentType(getBaseConstructorTypeOfClass(type)); if (!(baseConstructorType.flags & (65536 /* Object */ | 262144 /* Intersection */ | 1 /* Any */))) { return; } var baseTypeNode = getBaseTypeNodeOfClass(type); var typeArgs = typeArgumentsFromTypeReferenceNode(baseTypeNode); var baseType; var originalBaseType = baseConstructorType && baseConstructorType.symbol ? getDeclaredTypeOfSymbol(baseConstructorType.symbol) : undefined; if (baseConstructorType.symbol && baseConstructorType.symbol.flags & 32 /* Class */ && areAllOuterTypeParametersApplied(originalBaseType)) { // When base constructor type is a class with no captured type arguments we know that the constructors all have the same type parameters as the // class and all return the instance type of the class. There is no need for further checks and we can apply the // type arguments in the same manner as a type reference to get the same error reporting experience. baseType = getTypeFromClassOrInterfaceReference(baseTypeNode, baseConstructorType.symbol, typeArgs); } else if (baseConstructorType.flags & 1 /* Any */) { baseType = baseConstructorType; } else { // The class derives from a "class-like" constructor function, check that we have at least one construct signature // with a matching number of type parameters and use the return type of the first instantiated signature. Elsewhere // we check that all instantiated signatures return the same type. var constructors = getInstantiatedConstructorsForTypeArguments(baseConstructorType, baseTypeNode.typeArguments, baseTypeNode); if (!constructors.length) { error(baseTypeNode.expression, ts.Diagnostics.No_base_constructor_has_the_specified_number_of_type_arguments); return; } baseType = getReturnTypeOfSignature(constructors[0]); } if (baseType === unknownType) { return; } if (!isValidBaseType(baseType)) { error(baseTypeNode.expression, ts.Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType)); return; } if (type === baseType || hasBaseType(baseType, type)) { error(type.symbol.valueDeclaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */)); return; } type.resolvedBaseTypes = [baseType]; } function areAllOuterTypeParametersApplied(type) { // An unapplied type parameter has its symbol still the same as the matching argument symbol. // Since parameters are applied outer-to-inner, only the last outer parameter needs to be checked. var outerTypeParameters = type.outerTypeParameters; if (outerTypeParameters) { var last_1 = outerTypeParameters.length - 1; var typeArguments = type.typeArguments; return outerTypeParameters[last_1].symbol !== typeArguments[last_1].symbol; } return true; } // A valid base type is `any`, any non-generic object type or intersection of non-generic // object types. function isValidBaseType(type) { return type.flags & (65536 /* Object */ | 33554432 /* NonPrimitive */ | 1 /* Any */) && !isGenericMappedType(type) || type.flags & 262144 /* Intersection */ && !ts.forEach(type.types, function (t) { return !isValidBaseType(t); }); } function resolveBaseTypesOfInterface(type) { type.resolvedBaseTypes = type.resolvedBaseTypes || ts.emptyArray; for (var _i = 0, _a = type.symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (declaration.kind === 231 /* InterfaceDeclaration */ && ts.getInterfaceBaseTypeNodes(declaration)) { for (var _b = 0, _c = ts.getInterfaceBaseTypeNodes(declaration); _b < _c.length; _b++) { var node = _c[_b]; var baseType = getTypeFromTypeNode(node); if (baseType !== unknownType) { if (isValidBaseType(baseType)) { if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === ts.emptyArray) { type.resolvedBaseTypes = [baseType]; } else { type.resolvedBaseTypes.push(baseType); } } else { error(declaration, ts.Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */)); } } else { error(node, ts.Diagnostics.An_interface_may_only_extend_a_class_or_another_interface); } } } } } } /** * Returns true if the interface given by the symbol is free of "this" references. * * Specifically, the result is true if the interface itself contains no references * to "this" in its body, if all base types are interfaces, * and if none of the base interfaces have a "this" type. */ function isThislessInterface(symbol) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (declaration.kind === 231 /* InterfaceDeclaration */) { if (declaration.flags & 64 /* ContainsThis */) { return false; } var baseTypeNodes = ts.getInterfaceBaseTypeNodes(declaration); if (baseTypeNodes) { for (var _b = 0, baseTypeNodes_1 = baseTypeNodes; _b < baseTypeNodes_1.length; _b++) { var node = baseTypeNodes_1[_b]; if (ts.isEntityNameExpression(node.expression)) { var baseSymbol = resolveEntityName(node.expression, 793064 /* Type */, /*ignoreErrors*/ true); if (!baseSymbol || !(baseSymbol.flags & 64 /* Interface */) || getDeclaredTypeOfClassOrInterface(baseSymbol).thisType) { return false; } } } } } } return true; } function getDeclaredTypeOfClassOrInterface(symbol) { var links = getSymbolLinks(symbol); if (!links.declaredType) { var kind = symbol.flags & 32 /* Class */ ? 1 /* Class */ : 2 /* Interface */; var type = links.declaredType = createObjectType(kind, symbol); var outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); var localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); // A class or interface is generic if it has type parameters or a "this" type. We always give classes a "this" type // because it is not feasible to analyze all members to determine if the "this" type escapes the class (in particular, // property types inferred from initializers and method return types inferred from return statements are very hard // to exhaustively analyze). We give interfaces a "this" type if we can't definitely determine that they are free of // "this" references. if (outerTypeParameters || localTypeParameters || kind === 1 /* Class */ || !isThislessInterface(symbol)) { type.objectFlags |= 4 /* Reference */; type.typeParameters = ts.concatenate(outerTypeParameters, localTypeParameters); type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; type.instantiations = ts.createMap(); type.instantiations.set(getTypeListId(type.typeParameters), type); type.target = type; type.typeArguments = type.typeParameters; type.thisType = createType(32768 /* TypeParameter */); type.thisType.isThisType = true; type.thisType.symbol = symbol; type.thisType.constraint = type; } } return links.declaredType; } function getDeclaredTypeOfTypeAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.declaredType) { // Note that we use the links object as the target here because the symbol object is used as the unique // identity for resolution of the 'type' property in SymbolLinks. if (!pushTypeResolution(symbol, 2 /* DeclaredType */)) { return unknownType; } var declaration = ts.find(symbol.declarations, function (d) { return d.kind === 288 /* JSDocTypedefTag */ || d.kind === 232 /* TypeAliasDeclaration */; }); var typeNode = declaration.kind === 288 /* JSDocTypedefTag */ ? declaration.typeExpression : declaration.type; // If typeNode is missing, we will error in checkJSDocTypedefTag. var type = typeNode ? getTypeFromTypeNode(typeNode) : unknownType; if (popTypeResolution()) { var typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); if (typeParameters) { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; links.instantiations = ts.createMap(); links.instantiations.set(getTypeListId(typeParameters), type); } } else { type = unknownType; error(declaration.name, ts.Diagnostics.Type_alias_0_circularly_references_itself, symbolToString(symbol)); } links.declaredType = type; } return links.declaredType; } function isLiteralEnumMember(member) { var expr = member.initializer; if (!expr) { return !(member.flags & 2097152 /* Ambient */); } switch (expr.kind) { case 9 /* StringLiteral */: case 8 /* NumericLiteral */: return true; case 193 /* PrefixUnaryExpression */: return expr.operator === 38 /* MinusToken */ && expr.operand.kind === 8 /* NumericLiteral */; case 71 /* Identifier */: return ts.nodeIsMissing(expr) || !!getSymbolOfNode(member.parent).exports.get(expr.escapedText); default: return false; } } function getEnumKind(symbol) { var links = getSymbolLinks(symbol); if (links.enumKind !== undefined) { return links.enumKind; } var hasNonLiteralMember = false; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (declaration.kind === 233 /* EnumDeclaration */) { for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) { var member = _c[_b]; if (member.initializer && member.initializer.kind === 9 /* StringLiteral */) { return links.enumKind = 1 /* Literal */; } if (!isLiteralEnumMember(member)) { hasNonLiteralMember = true; } } } } return links.enumKind = hasNonLiteralMember ? 0 /* Numeric */ : 1 /* Literal */; } function getBaseTypeOfEnumLiteralType(type) { return type.flags & 256 /* EnumLiteral */ && !(type.flags & 131072 /* Union */) ? getDeclaredTypeOfSymbol(getParentOfSymbol(type.symbol)) : type; } function getDeclaredTypeOfEnum(symbol) { var links = getSymbolLinks(symbol); if (links.declaredType) { return links.declaredType; } if (getEnumKind(symbol) === 1 /* Literal */) { enumCount++; var memberTypeList = []; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (declaration.kind === 233 /* EnumDeclaration */) { for (var _b = 0, _c = declaration.members; _b < _c.length; _b++) { var member = _c[_b]; var memberType = getLiteralType(getEnumMemberValue(member), enumCount, getSymbolOfNode(member)); getSymbolLinks(getSymbolOfNode(member)).declaredType = memberType; memberTypeList.push(memberType); } } } if (memberTypeList.length) { var enumType_1 = getUnionType(memberTypeList, /*subtypeReduction*/ false, symbol, /*aliasTypeArguments*/ undefined); if (enumType_1.flags & 131072 /* Union */) { enumType_1.flags |= 256 /* EnumLiteral */; enumType_1.symbol = symbol; } return links.declaredType = enumType_1; } } var enumType = createType(16 /* Enum */); enumType.symbol = symbol; return links.declaredType = enumType; } function getDeclaredTypeOfEnumMember(symbol) { var links = getSymbolLinks(symbol); if (!links.declaredType) { var enumType = getDeclaredTypeOfEnum(getParentOfSymbol(symbol)); if (!links.declaredType) { links.declaredType = enumType; } } return links.declaredType; } function getDeclaredTypeOfTypeParameter(symbol) { var links = getSymbolLinks(symbol); if (!links.declaredType) { var type = createType(32768 /* TypeParameter */); type.symbol = symbol; links.declaredType = type; } return links.declaredType; } function getDeclaredTypeOfAlias(symbol) { var links = getSymbolLinks(symbol); if (!links.declaredType) { links.declaredType = getDeclaredTypeOfSymbol(resolveAlias(symbol)); } return links.declaredType; } function getDeclaredTypeOfSymbol(symbol) { return tryGetDeclaredTypeOfSymbol(symbol) || unknownType; } function tryGetDeclaredTypeOfSymbol(symbol) { if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) { return getDeclaredTypeOfClassOrInterface(symbol); } if (symbol.flags & 524288 /* TypeAlias */) { return getDeclaredTypeOfTypeAlias(symbol); } if (symbol.flags & 262144 /* TypeParameter */) { return getDeclaredTypeOfTypeParameter(symbol); } if (symbol.flags & 384 /* Enum */) { return getDeclaredTypeOfEnum(symbol); } if (symbol.flags & 8 /* EnumMember */) { return getDeclaredTypeOfEnumMember(symbol); } if (symbol.flags & 2097152 /* Alias */) { return getDeclaredTypeOfAlias(symbol); } return undefined; } /** * A type is free of this references if it's the any, string, number, boolean, symbol, or void keyword, a string * literal type, an array with an element type that is free of this references, or a type reference that is * free of this references. */ function isThislessType(node) { switch (node.kind) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: case 134 /* ObjectKeyword */: case 105 /* VoidKeyword */: case 139 /* UndefinedKeyword */: case 95 /* NullKeyword */: case 130 /* NeverKeyword */: case 174 /* LiteralType */: return true; case 165 /* ArrayType */: return isThislessType(node.elementType); case 160 /* TypeReference */: return !node.typeArguments || node.typeArguments.every(isThislessType); } return false; } /** A type parameter is thisless if its contraint is thisless, or if it has no constraint. */ function isThislessTypeParameter(node) { return !node.constraint || isThislessType(node.constraint); } /** * A variable-like declaration is free of this references if it has a type annotation * that is thisless, or if it has no type annotation and no initializer (and is thus of type any). */ function isThislessVariableLikeDeclaration(node) { var typeNode = ts.getEffectiveTypeAnnotationNode(node); return typeNode ? isThislessType(typeNode) : !node.initializer; } /** * A function-like declaration is considered free of `this` references if it has a return type * annotation that is free of this references and if each parameter is thisless and if * each type parameter (if present) is thisless. */ function isThislessFunctionLikeDeclaration(node) { var returnType = ts.getEffectiveReturnTypeNode(node); return (node.kind === 153 /* Constructor */ || (returnType && isThislessType(returnType))) && node.parameters.every(isThislessVariableLikeDeclaration) && (!node.typeParameters || node.typeParameters.every(isThislessTypeParameter)); } /** * 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 isThisless(symbol) { if (symbol.declarations && symbol.declarations.length === 1) { var declaration = symbol.declarations[0]; if (declaration) { switch (declaration.kind) { case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return isThislessVariableLikeDeclaration(declaration); case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: return isThislessFunctionLikeDeclaration(declaration); } } } return false; } // The mappingThisOnly flag indicates that the only type parameter being mapped is "this". When the flag is true, // we check symbols to see if we can quickly conclude they are free of "this" references, thus needing no instantiation. function createInstantiatedSymbolTable(symbols, mapper, mappingThisOnly) { var result = ts.createSymbolTable(); for (var _i = 0, symbols_2 = symbols; _i < symbols_2.length; _i++) { var symbol = symbols_2[_i]; result.set(symbol.escapedName, mappingThisOnly && isThisless(symbol) ? symbol : instantiateSymbol(symbol, mapper)); } return result; } function addInheritedMembers(symbols, baseSymbols) { for (var _i = 0, baseSymbols_1 = baseSymbols; _i < baseSymbols_1.length; _i++) { var s = baseSymbols_1[_i]; if (!symbols.has(s.escapedName)) { symbols.set(s.escapedName, s); } } } function resolveDeclaredMembers(type) { if (!type.declaredProperties) { var symbol = type.symbol; var members = getMembersOfSymbol(symbol); type.declaredProperties = getNamedMembers(members); type.declaredCallSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */)); type.declaredConstructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */)); type.declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */); type.declaredNumberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */); } return type; } /** * Indicates whether a type can be used as a late-bound name. */ function isTypeUsableAsLateBoundName(type) { return !!(type.flags & 1120 /* StringOrNumberLiteralOrUnique */); } /** * Indicates whether a declaration name is definitely late-bindable. * A declaration name is only late-bindable if: * - It is a `ComputedPropertyName`. * - Its expression is an `Identifier` or either a `PropertyAccessExpression` an * `ElementAccessExpression` consisting only of these same three types of nodes. * - The type of its expression is a string or numeric literal type, or is a `unique symbol` type. */ function isLateBindableName(node) { return ts.isComputedPropertyName(node) && ts.isEntityNameExpression(node.expression) && isTypeUsableAsLateBoundName(checkComputedPropertyName(node)); } /** * Indicates whether a declaration has a late-bindable dynamic name. */ function hasLateBindableName(node) { var name = ts.getNameOfDeclaration(node); return name && isLateBindableName(name); } /** * Indicates whether a declaration has a dynamic name that cannot be late-bound. */ function hasNonBindableDynamicName(node) { return ts.hasDynamicName(node) && !hasLateBindableName(node); } /** * Indicates whether a declaration name is a dynamic name that cannot be late-bound. */ function isNonBindableDynamicName(node) { return ts.isDynamicName(node) && !isLateBindableName(node); } /** * Gets the symbolic name for a late-bound member from its type. */ function getLateBoundNameFromType(type) { if (type.flags & 1024 /* UniqueESSymbol */) { return "__@" + type.symbol.escapedName + "@" + getSymbolId(type.symbol); } if (type.flags & 96 /* StringOrNumberLiteral */) { return ts.escapeLeadingUnderscores("" + type.value); } } /** * Adds a declaration to a late-bound dynamic member. This performs the same function for * late-bound members that `addDeclarationToSymbol` in binder.ts performs for early-bound * members. */ function addDeclarationToLateBoundSymbol(symbol, member, symbolFlags) { ts.Debug.assert(!!(ts.getCheckFlags(symbol) & 1024 /* Late */), "Expected a late-bound symbol."); symbol.flags |= symbolFlags; getSymbolLinks(member.symbol).lateSymbol = symbol; if (!symbol.declarations) { symbol.declarations = [member]; } else { symbol.declarations.push(member); } if (symbolFlags & 107455 /* Value */) { var valueDeclaration = symbol.valueDeclaration; if (!valueDeclaration || valueDeclaration.kind !== member.kind) { symbol.valueDeclaration = member; } } } /** * Performs late-binding of a dynamic member. This performs the same function for * late-bound members that `declareSymbol` in binder.ts performs for early-bound * members. * * If a symbol is a dynamic name from a computed property, we perform an additional "late" * binding phase to attempt to resolve the name for the symbol from the type of the computed * property's expression. If the type of the expression is a string-literal, numeric-literal, * or unique symbol type, we can use that type as the name of the symbol. * * For example, given: * * const x = Symbol(); * * interface I { * [x]: number; * } * * The binder gives the property `[x]: number` a special symbol with the name "__computed". * In the late-binding phase we can type-check the expression `x` and see that it has a * unique symbol type which we can then use as the name of the member. This allows users * to define custom symbols that can be used in the members of an object type. * * @param parent The containing symbol for the member. * @param earlySymbols The early-bound symbols of the parent. * @param lateSymbols The late-bound symbols of the parent. * @param decl The member to bind. */ function lateBindMember(parent, earlySymbols, lateSymbols, decl) { ts.Debug.assert(!!decl.symbol, "The member is expected to have a symbol."); var links = getNodeLinks(decl); if (!links.resolvedSymbol) { // In the event we attempt to resolve the late-bound name of this member recursively, // fall back to the early-bound name of this member. links.resolvedSymbol = decl.symbol; var type = checkComputedPropertyName(decl.name); if (isTypeUsableAsLateBoundName(type)) { var memberName = getLateBoundNameFromType(type); var symbolFlags = decl.symbol.flags; // Get or add a late-bound symbol for the member. This allows us to merge late-bound accessor declarations. var lateSymbol = lateSymbols.get(memberName); if (!lateSymbol) lateSymbols.set(memberName, lateSymbol = createSymbol(0 /* None */, memberName, 1024 /* Late */)); // Report an error if a late-bound member has the same name as an early-bound member, // or if we have another early-bound symbol declaration with the same name and // conflicting flags. var earlySymbol = earlySymbols && earlySymbols.get(memberName); if (lateSymbol.flags & getExcludedSymbolFlags(symbolFlags) || earlySymbol) { // If we have an existing early-bound member, combine its declarations so that we can // report an error at each declaration. var declarations = earlySymbol ? ts.concatenate(earlySymbol.declarations, lateSymbol.declarations) : lateSymbol.declarations; var name_3 = ts.declarationNameToString(decl.name); ts.forEach(declarations, function (declaration) { return error(ts.getNameOfDeclaration(declaration) || declaration, ts.Diagnostics.Duplicate_declaration_0, name_3); }); error(decl.name || decl, ts.Diagnostics.Duplicate_declaration_0, name_3); lateSymbol = createSymbol(0 /* None */, memberName, 1024 /* Late */); } addDeclarationToLateBoundSymbol(lateSymbol, decl, symbolFlags); lateSymbol.parent = parent; return links.resolvedSymbol = lateSymbol; } } return links.resolvedSymbol; } function getResolvedMembersOrExportsOfSymbol(symbol, resolutionKind) { var links = getSymbolLinks(symbol); if (!links[resolutionKind]) { var isStatic = resolutionKind === "resolvedExports" /* resolvedExports */; var earlySymbols = !isStatic ? symbol.members : symbol.flags & 1536 /* Module */ ? getExportsOfModuleWorker(symbol) : symbol.exports; // In the event we recursively resolve the members/exports of the symbol, we // set the initial value of resolvedMembers/resolvedExports to the early-bound // members/exports of the symbol. links[resolutionKind] = earlySymbols || emptySymbols; // fill in any as-yet-unresolved late-bound members. var lateSymbols = ts.createSymbolTable(); for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; var members = ts.getMembersOfDeclaration(decl); if (members) { for (var _b = 0, members_3 = members; _b < members_3.length; _b++) { var member = members_3[_b]; if (isStatic === ts.hasStaticModifier(member) && hasLateBindableName(member)) { lateBindMember(symbol, earlySymbols, lateSymbols, member); } } } } links[resolutionKind] = combineSymbolTables(earlySymbols, lateSymbols) || emptySymbols; } return links[resolutionKind]; } /** * Gets a SymbolTable containing both the early- and late-bound members of a symbol. * * For a description of late-binding, see `lateBindMember`. */ function getMembersOfSymbol(symbol) { return symbol.flags & 6240 /* LateBindingContainer */ ? getResolvedMembersOrExportsOfSymbol(symbol, "resolvedMembers" /* resolvedMembers */) : symbol.members || emptySymbols; } /** * If a symbol is the dynamic name of the member of an object type, get the late-bound * symbol of the member. * * For a description of late-binding, see `lateBindMember`. */ function getLateBoundSymbol(symbol) { if (symbol.flags & 106500 /* ClassMember */ && symbol.escapedName === "__computed" /* Computed */) { var links = getSymbolLinks(symbol); if (!links.lateSymbol && ts.some(symbol.declarations, hasLateBindableName)) { // force late binding of members/exports. This will set the late-bound symbol if (ts.some(symbol.declarations, ts.hasStaticModifier)) { getExportsOfSymbol(symbol.parent); } else { getMembersOfSymbol(symbol.parent); } } return links.lateSymbol || (links.lateSymbol = symbol); } return symbol; } function getTypeWithThisArgument(type, thisArgument) { if (ts.getObjectFlags(type) & 4 /* Reference */) { var target = type.target; var typeArguments = type.typeArguments; if (ts.length(target.typeParameters) === ts.length(typeArguments)) { return createTypeReference(target, ts.concatenate(typeArguments, [thisArgument || target.thisType])); } } else if (type.flags & 262144 /* Intersection */) { return getIntersectionType(ts.map(type.types, function (t) { return getTypeWithThisArgument(t, thisArgument); })); } return type; } function resolveObjectTypeMembers(type, source, typeParameters, typeArguments) { var mapper; var members; var callSignatures; var constructSignatures; var stringIndexInfo; var numberIndexInfo; if (ts.rangeEquals(typeParameters, typeArguments, 0, typeParameters.length)) { mapper = identityMapper; members = source.symbol ? getMembersOfSymbol(source.symbol) : ts.createSymbolTable(source.declaredProperties); callSignatures = source.declaredCallSignatures; constructSignatures = source.declaredConstructSignatures; stringIndexInfo = source.declaredStringIndexInfo; numberIndexInfo = source.declaredNumberIndexInfo; } else { mapper = createTypeMapper(typeParameters, typeArguments); members = createInstantiatedSymbolTable(source.declaredProperties, mapper, /*mappingThisOnly*/ typeParameters.length === 1); callSignatures = instantiateSignatures(source.declaredCallSignatures, mapper); constructSignatures = instantiateSignatures(source.declaredConstructSignatures, mapper); stringIndexInfo = instantiateIndexInfo(source.declaredStringIndexInfo, mapper); numberIndexInfo = instantiateIndexInfo(source.declaredNumberIndexInfo, mapper); } var baseTypes = getBaseTypes(source); if (baseTypes.length) { if (source.symbol && members === getMembersOfSymbol(source.symbol)) { members = ts.createSymbolTable(source.declaredProperties); } var thisArgument = ts.lastOrUndefined(typeArguments); for (var _i = 0, baseTypes_1 = baseTypes; _i < baseTypes_1.length; _i++) { var baseType = baseTypes_1[_i]; var instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, 0 /* Call */)); constructSignatures = ts.concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, 1 /* Construct */)); if (!stringIndexInfo) { stringIndexInfo = instantiatedBaseType === anyType ? createIndexInfo(anyType, /*isReadonly*/ false) : getIndexInfoOfType(instantiatedBaseType, 0 /* String */); } numberIndexInfo = numberIndexInfo || getIndexInfoOfType(instantiatedBaseType, 1 /* Number */); } } setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } function resolveClassOrInterfaceMembers(type) { resolveObjectTypeMembers(type, resolveDeclaredMembers(type), ts.emptyArray, ts.emptyArray); } function resolveTypeReferenceMembers(type) { var source = resolveDeclaredMembers(type.target); var typeParameters = ts.concatenate(source.typeParameters, [source.thisType]); var typeArguments = type.typeArguments && type.typeArguments.length === typeParameters.length ? type.typeArguments : ts.concatenate(type.typeArguments, [type]); resolveObjectTypeMembers(type, source, typeParameters, typeArguments); } function createSignature(declaration, typeParameters, thisParameter, parameters, resolvedReturnType, typePredicate, minArgumentCount, hasRestParameter, hasLiteralTypes) { var sig = new Signature(checker); sig.declaration = declaration; sig.typeParameters = typeParameters; sig.parameters = parameters; sig.thisParameter = thisParameter; sig.resolvedReturnType = resolvedReturnType; sig.typePredicate = typePredicate; sig.minArgumentCount = minArgumentCount; sig.hasRestParameter = hasRestParameter; sig.hasLiteralTypes = hasLiteralTypes; return sig; } function cloneSignature(sig) { return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes); } function getDefaultConstructSignatures(classType) { var baseConstructorType = getBaseConstructorTypeOfClass(classType); var baseSignatures = getSignaturesOfType(baseConstructorType, 1 /* Construct */); if (baseSignatures.length === 0) { return [createSignature(undefined, classType.localTypeParameters, undefined, ts.emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; } var baseTypeNode = getBaseTypeNodeOfClass(classType); var isJavaScript = ts.isInJavaScriptFile(baseTypeNode); var typeArguments = typeArgumentsFromTypeReferenceNode(baseTypeNode); var typeArgCount = ts.length(typeArguments); var result = []; for (var _i = 0, baseSignatures_1 = baseSignatures; _i < baseSignatures_1.length; _i++) { var baseSig = baseSignatures_1[_i]; var minTypeArgumentCount = getMinTypeArgumentCount(baseSig.typeParameters); var typeParamCount = ts.length(baseSig.typeParameters); if (isJavaScript || (typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount)) { var sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; sig.resolvedReturnType = classType; result.push(sig); } } return result; } function findMatchingSignature(signatureList, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes) { for (var _i = 0, signatureList_1 = signatureList; _i < signatureList_1.length; _i++) { var s = signatureList_1[_i]; if (compareSignaturesIdentical(s, signature, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypesIdentical)) { return s; } } } function findMatchingSignatures(signatureLists, signature, listIndex) { if (signature.typeParameters) { // We require an exact match for generic signatures, so we only return signatures from the first // signature list and only if they have exact matches in the other signature lists. if (listIndex > 0) { return undefined; } for (var i = 1; i < signatureLists.length; i++) { if (!findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false)) { return undefined; } } return [signature]; } var result = undefined; for (var i = 0; i < signatureLists.length; i++) { // Allow matching non-generic signatures to have excess parameters and different return types var match = i === listIndex ? signature : findMatchingSignature(signatureLists[i], signature, /*partialMatch*/ true, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true); if (!match) { return undefined; } result = ts.appendIfUnique(result, match); } return result; } // The signatures of a union type are those signatures that are present in each of the constituent types. // Generic signatures must match exactly, but non-generic signatures are allowed to have extra optional // parameters and may differ in return types. When signatures differ in return types, the resulting return // type is the union of the constituent return types. function getUnionSignatures(types, kind) { var signatureLists = ts.map(types, function (t) { return getSignaturesOfType(t, kind); }); var result = undefined; for (var i = 0; i < signatureLists.length; i++) { for (var _i = 0, _a = signatureLists[i]; _i < _a.length; _i++) { var signature = _a[_i]; // Only process signatures with parameter lists that aren't already in the result list if (!result || !findMatchingSignature(result, signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true)) { var unionSignatures = findMatchingSignatures(signatureLists, signature, i); if (unionSignatures) { var s = signature; // Union the result types when more than one signature matches if (unionSignatures.length > 1) { s = cloneSignature(signature); if (ts.forEach(unionSignatures, function (sig) { return sig.thisParameter; })) { var thisType = getUnionType(ts.map(unionSignatures, function (sig) { return getTypeOfSymbol(sig.thisParameter) || anyType; }), /*subtypeReduction*/ true); s.thisParameter = createSymbolWithType(signature.thisParameter, thisType); } // Clear resolved return type we possibly got from cloneSignature s.resolvedReturnType = undefined; s.unionSignatures = unionSignatures; } (result || (result = [])).push(s); } } } } return result || ts.emptyArray; } function getUnionIndexInfo(types, kind) { var indexTypes = []; var isAnyReadonly = false; for (var _i = 0, types_2 = types; _i < types_2.length; _i++) { var type = types_2[_i]; var indexInfo = getIndexInfoOfType(type, kind); if (!indexInfo) { return undefined; } indexTypes.push(indexInfo.type); isAnyReadonly = isAnyReadonly || indexInfo.isReadonly; } return createIndexInfo(getUnionType(indexTypes, /*subtypeReduction*/ true), isAnyReadonly); } function resolveUnionTypeMembers(type) { // The members and properties collections are empty for union types. To get all properties of a union // type use getPropertiesOfType (only the language service uses this). var callSignatures = getUnionSignatures(type.types, 0 /* Call */); var constructSignatures = getUnionSignatures(type.types, 1 /* Construct */); var stringIndexInfo = getUnionIndexInfo(type.types, 0 /* String */); var numberIndexInfo = getUnionIndexInfo(type.types, 1 /* Number */); setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } function intersectTypes(type1, type2) { return !type1 ? type2 : !type2 ? type1 : getIntersectionType([type1, type2]); } function intersectIndexInfos(info1, info2) { return !info1 ? info2 : !info2 ? info1 : createIndexInfo(getIntersectionType([info1.type, info2.type]), info1.isReadonly && info2.isReadonly); } function unionSpreadIndexInfos(info1, info2) { return info1 && info2 && createIndexInfo(getUnionType([info1.type, info2.type]), info1.isReadonly || info2.isReadonly); } function includeMixinType(type, types, index) { var mixedTypes = []; for (var i = 0; i < types.length; i++) { if (i === index) { mixedTypes.push(type); } else if (isMixinConstructorType(types[i])) { mixedTypes.push(getReturnTypeOfSignature(getSignaturesOfType(types[i], 1 /* Construct */)[0])); } } return getIntersectionType(mixedTypes); } function resolveIntersectionTypeMembers(type) { // The members and properties collections are empty for intersection types. To get all properties of an // intersection type use getPropertiesOfType (only the language service uses this). var callSignatures = ts.emptyArray; var constructSignatures = ts.emptyArray; var stringIndexInfo; var numberIndexInfo; var types = type.types; var mixinCount = ts.countWhere(types, isMixinConstructorType); var _loop_4 = function (i) { var t = type.types[i]; // When an intersection type contains mixin constructor types, the construct signatures from // those types are discarded and their return types are mixed into the return types of all // other construct signatures in the intersection type. For example, the intersection type // '{ new(...args: any[]) => A } & { new(s: string) => B }' has a single construct signature // 'new(s: string) => A & B'. if (mixinCount === 0 || mixinCount === types.length && i === 0 || !isMixinConstructorType(t)) { var signatures = getSignaturesOfType(t, 1 /* Construct */); if (signatures.length && mixinCount > 0) { signatures = ts.map(signatures, function (s) { var clone = cloneSignature(s); clone.resolvedReturnType = includeMixinType(getReturnTypeOfSignature(s), types, i); return clone; }); } constructSignatures = ts.concatenate(constructSignatures, signatures); } callSignatures = ts.concatenate(callSignatures, getSignaturesOfType(t, 0 /* Call */)); stringIndexInfo = intersectIndexInfos(stringIndexInfo, getIndexInfoOfType(t, 0 /* String */)); numberIndexInfo = intersectIndexInfos(numberIndexInfo, getIndexInfoOfType(t, 1 /* Number */)); }; for (var i = 0; i < types.length; i++) { _loop_4(i); } setStructuredTypeMembers(type, emptySymbols, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } /** * Converts an AnonymousType to a ResolvedType. */ function resolveAnonymousTypeMembers(type) { var symbol = type.symbol; if (type.target) { var members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper, /*mappingThisOnly*/ false); var callSignatures = instantiateSignatures(getSignaturesOfType(type.target, 0 /* Call */), type.mapper); var constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, 1 /* Construct */), type.mapper); var stringIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 0 /* String */), type.mapper); var numberIndexInfo = instantiateIndexInfo(getIndexInfoOfType(type.target, 1 /* Number */), type.mapper); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } else if (symbol.flags & 2048 /* TypeLiteral */) { var members = getMembersOfSymbol(symbol); var callSignatures = getSignaturesOfSymbol(members.get("__call" /* Call */)); var constructSignatures = getSignaturesOfSymbol(members.get("__new" /* New */)); var stringIndexInfo = getIndexInfoOfSymbol(symbol, 0 /* String */); var numberIndexInfo = getIndexInfoOfSymbol(symbol, 1 /* Number */); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } else { // Combinations of function, class, enum and module var members = emptySymbols; var stringIndexInfo = undefined; if (symbol.exports) { members = getExportsOfSymbol(symbol); } if (symbol.flags & 32 /* Class */) { var classType = getDeclaredTypeOfClassOrInterface(symbol); var baseConstructorType = getBaseConstructorTypeOfClass(classType); if (baseConstructorType.flags & (65536 /* Object */ | 262144 /* Intersection */ | 1081344 /* TypeVariable */)) { members = ts.createSymbolTable(getNamedMembers(members)); addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } else if (baseConstructorType === anyType) { stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false); } } var numberIndexInfo = symbol.flags & 384 /* Enum */ ? enumNumberIndexInfo : undefined; setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo); // We resolve the members before computing the signatures because a signature may use // typeof with a qualified name expression that circularly references the type we are // in the process of resolving (see issue #6072). The temporarily empty signature list // will never be observed because a qualified name can't reference signatures. if (symbol.flags & (16 /* Function */ | 8192 /* Method */)) { type.callSignatures = getSignaturesOfSymbol(symbol); } // And likewise for construct signatures for classes if (symbol.flags & 32 /* Class */) { var classType = getDeclaredTypeOfClassOrInterface(symbol); var constructSignatures = getSignaturesOfSymbol(symbol.members.get("__constructor" /* Constructor */)); if (!constructSignatures.length) { constructSignatures = getDefaultConstructSignatures(classType); } type.constructSignatures = constructSignatures; } } } /** Resolve the members of a mapped type { [P in K]: T } */ function resolveMappedTypeMembers(type) { var members = ts.createSymbolTable(); var stringIndexInfo; // Resolve upfront such that recursive references see an empty object type. setStructuredTypeMembers(type, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); // In { [P in K]: T }, we refer to P as the type parameter type, K as the constraint type, // and T as the template type. var typeParameter = getTypeParameterFromMappedType(type); var constraintType = getConstraintTypeFromMappedType(type); var templateType = getTemplateTypeFromMappedType(type); var modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' var templateReadonly = !!type.declaration.readonlyToken; var templateOptional = !!type.declaration.questionToken; var constraintDeclaration = type.declaration.typeParameter.constraint; if (constraintDeclaration.kind === 171 /* TypeOperator */ && constraintDeclaration.operator === 127 /* KeyOfKeyword */) { // We have a { [P in keyof T]: X } for (var _i = 0, _a = getPropertiesOfType(modifiersType); _i < _a.length; _i++) { var propertySymbol = _a[_i]; addMemberForKeyType(getLiteralTypeFromPropertyName(propertySymbol), propertySymbol); } if (modifiersType.flags & 1 /* Any */ || getIndexInfoOfType(modifiersType, 0 /* String */)) { addMemberForKeyType(stringType); } } else { // First, if the constraint type is a type parameter, obtain the base constraint. Then, // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X. // Finally, iterate over the constituents of the resulting iteration type. var keyType = constraintType.flags & 1081344 /* TypeVariable */ ? getApparentType(constraintType) : constraintType; var iterationType = keyType.flags & 524288 /* Index */ ? getIndexType(getApparentType(keyType.type)) : keyType; forEachType(iterationType, addMemberForKeyType); } setStructuredTypeMembers(type, members, ts.emptyArray, ts.emptyArray, stringIndexInfo, undefined); function addMemberForKeyType(t, propertySymbolOrIndex) { var propertySymbol; // forEachType delegates to forEach, which calls with a numeric second argument // the type system currently doesn't catch this incompatibility, so we annotate // the function ourselves to indicate the runtime behavior and deal with it here if (typeof propertySymbolOrIndex === "object") { propertySymbol = propertySymbolOrIndex; } // Create a mapper from T to the current iteration type constituent. Then, if the // mapped type is itself an instantiated type, combine the iteration mapper with the // instantiation mapper. var iterationMapper = createTypeMapper([typeParameter], [t]); var templateMapper = type.mapper ? combineTypeMappers(type.mapper, iterationMapper) : iterationMapper; var propType = instantiateType(templateType, templateMapper); // If the current iteration type constituent is a string literal type, create a property. // Otherwise, for type string create a string index signature. if (t.flags & 32 /* StringLiteral */) { var propName = ts.escapeLeadingUnderscores(t.value); var modifiersProp = getPropertyOfType(modifiersType, propName); var isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & 16777216 /* Optional */); var checkFlags = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp) ? 8 /* Readonly */ : 0; var prop = createSymbol(4 /* Property */ | (isOptional ? 16777216 /* Optional */ : 0), propName, checkFlags); prop.type = propType; if (propertySymbol) { prop.syntheticOrigin = propertySymbol; prop.declarations = propertySymbol.declarations; } prop.syntheticLiteralTypeOrigin = t; members.set(propName, prop); } else if (t.flags & (1 /* Any */ | 2 /* String */)) { stringIndexInfo = createIndexInfo(propType, templateReadonly); } } } function getTypeParameterFromMappedType(type) { return type.typeParameter || (type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(type.declaration.typeParameter))); } function getConstraintTypeFromMappedType(type) { return type.constraintType || (type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || unknownType); } function getTemplateTypeFromMappedType(type) { return type.templateType || (type.templateType = type.declaration.type ? instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) : unknownType); } function getModifiersTypeFromMappedType(type) { if (!type.modifiersType) { var constraintDeclaration = type.declaration.typeParameter.constraint; if (constraintDeclaration.kind === 171 /* TypeOperator */ && constraintDeclaration.operator === 127 /* KeyOfKeyword */) { // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves // 'keyof T' to a literal union type and we can't recover T from that type. type.modifiersType = instantiateType(getTypeFromTypeNode(constraintDeclaration.type), type.mapper || identityMapper); } else { // Otherwise, get the declared constraint type, and if the constraint type is a type parameter, // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T', // the modifiers type is T. Otherwise, the modifiers type is {}. var declaredType = getTypeFromMappedTypeNode(type.declaration); var constraint = getConstraintTypeFromMappedType(declaredType); var extendedConstraint = constraint && constraint.flags & 32768 /* TypeParameter */ ? getConstraintOfTypeParameter(constraint) : constraint; type.modifiersType = extendedConstraint && extendedConstraint.flags & 524288 /* Index */ ? instantiateType(extendedConstraint.type, type.mapper || identityMapper) : emptyObjectType; } } return type.modifiersType; } function getMappedTypeModifiers(type) { return (type.declaration.readonlyToken ? 1 /* Readonly */ : 0) | (type.declaration.questionToken ? 2 /* Optional */ : 0); } function getCombinedMappedTypeModifiers(type) { var modifiersType = getModifiersTypeFromMappedType(type); return getMappedTypeModifiers(type) | (isGenericMappedType(modifiersType) ? getMappedTypeModifiers(modifiersType) : 0); } function isPartialMappedType(type) { return ts.getObjectFlags(type) & 32 /* Mapped */ && !!type.declaration.questionToken; } function isGenericMappedType(type) { return ts.getObjectFlags(type) & 32 /* Mapped */ && isGenericIndexType(getConstraintTypeFromMappedType(type)); } function resolveStructuredTypeMembers(type) { if (!type.members) { if (type.flags & 65536 /* Object */) { if (type.objectFlags & 4 /* Reference */) { resolveTypeReferenceMembers(type); } else if (type.objectFlags & 3 /* ClassOrInterface */) { resolveClassOrInterfaceMembers(type); } else if (type.objectFlags & 16 /* Anonymous */) { resolveAnonymousTypeMembers(type); } else if (type.objectFlags & 32 /* Mapped */) { resolveMappedTypeMembers(type); } } else if (type.flags & 131072 /* Union */) { resolveUnionTypeMembers(type); } else if (type.flags & 262144 /* Intersection */) { resolveIntersectionTypeMembers(type); } } return type; } /** Return properties of an object type or an empty array for other types */ function getPropertiesOfObjectType(type) { if (type.flags & 65536 /* Object */) { return resolveStructuredTypeMembers(type).properties; } return ts.emptyArray; } /** If the given type is an object type and that type has a property by the given name, * return the symbol for that property. Otherwise return undefined. */ function getPropertyOfObjectType(type, name) { if (type.flags & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(type); var symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol)) { return symbol; } } } function getPropertiesOfUnionOrIntersectionType(type) { if (!type.resolvedProperties) { var members = ts.createSymbolTable(); for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var current = _a[_i]; for (var _b = 0, _c = getPropertiesOfType(current); _b < _c.length; _b++) { var prop = _c[_b]; if (!members.has(prop.escapedName)) { var combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.escapedName); if (combinedProp) { members.set(prop.escapedName, combinedProp); } } } // The properties of a union type are those that are present in all constituent types, so // we only need to check the properties of the first type if (type.flags & 131072 /* Union */) { break; } } type.resolvedProperties = getNamedMembers(members); } return type.resolvedProperties; } function getPropertiesOfType(type) { type = getApparentType(type); return type.flags & 393216 /* UnionOrIntersection */ ? getPropertiesOfUnionOrIntersectionType(type) : getPropertiesOfObjectType(type); } function getAllPossiblePropertiesOfTypes(types) { var unionType = getUnionType(types); if (!(unionType.flags & 131072 /* Union */)) { return getAugmentedPropertiesOfType(unionType); } var props = ts.createSymbolTable(); for (var _i = 0, types_3 = types; _i < types_3.length; _i++) { var memberType = types_3[_i]; for (var _a = 0, _b = getAugmentedPropertiesOfType(memberType); _a < _b.length; _a++) { var escapedName = _b[_a].escapedName; if (!props.has(escapedName)) { props.set(escapedName, createUnionOrIntersectionProperty(unionType, escapedName)); } } } return ts.arrayFrom(props.values()); } function getConstraintOfType(type) { return type.flags & 32768 /* TypeParameter */ ? getConstraintOfTypeParameter(type) : type.flags & 1048576 /* IndexedAccess */ ? getConstraintOfIndexedAccess(type) : getBaseConstraintOfType(type); } function getConstraintOfTypeParameter(typeParameter) { return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined; } function getConstraintOfIndexedAccess(type) { var transformed = getTransformedIndexedAccessType(type); if (transformed) { return transformed; } var baseObjectType = getBaseConstraintOfType(type.objectType); var baseIndexType = getBaseConstraintOfType(type.indexType); return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined; } function getBaseConstraintOfType(type) { if (type.flags & (1081344 /* TypeVariable */ | 393216 /* UnionOrIntersection */)) { var constraint = getResolvedBaseConstraint(type); if (constraint !== noConstraintType && constraint !== circularConstraintType) { return constraint; } } else if (type.flags & 524288 /* Index */) { return stringType; } return undefined; } function hasNonCircularBaseConstraint(type) { return getResolvedBaseConstraint(type) !== circularConstraintType; } /** * Return the resolved base constraint of a type variable. The noConstraintType singleton is returned if the * type variable has no constraint, and the circularConstraintType singleton is returned if the constraint * circularly references the type variable. */ function getResolvedBaseConstraint(type) { var typeStack; var circular; if (!type.resolvedBaseConstraint) { typeStack = []; var constraint = getBaseConstraint(type); type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type); } return type.resolvedBaseConstraint; function getBaseConstraint(t) { if (ts.contains(typeStack, t)) { circular = true; return undefined; } typeStack.push(t); var result = computeBaseConstraint(t); typeStack.pop(); return result; } function computeBaseConstraint(t) { if (t.flags & 32768 /* TypeParameter */) { var constraint = getConstraintFromTypeParameter(t); return t.isThisType ? constraint : constraint ? getBaseConstraint(constraint) : undefined; } if (t.flags & 393216 /* UnionOrIntersection */) { var types = t.types; var baseTypes = []; for (var _i = 0, types_4 = types; _i < types_4.length; _i++) { var type_2 = types_4[_i]; var baseType = getBaseConstraint(type_2); if (baseType) { baseTypes.push(baseType); } } return t.flags & 131072 /* Union */ && baseTypes.length === types.length ? getUnionType(baseTypes) : t.flags & 262144 /* Intersection */ && baseTypes.length ? getIntersectionType(baseTypes) : undefined; } if (t.flags & 524288 /* Index */) { return stringType; } if (t.flags & 1048576 /* IndexedAccess */) { var transformed = getTransformedIndexedAccessType(t); if (transformed) { return getBaseConstraint(transformed); } var baseObjectType = getBaseConstraint(t.objectType); var baseIndexType = getBaseConstraint(t.indexType); var baseIndexedAccess = baseObjectType && baseIndexType ? getIndexedAccessType(baseObjectType, baseIndexType) : undefined; return baseIndexedAccess && baseIndexedAccess !== unknownType ? getBaseConstraint(baseIndexedAccess) : undefined; } if (isGenericMappedType(t)) { return emptyObjectType; } return t; } } function getApparentTypeOfIntersectionType(type) { return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); } function getResolvedTypeParameterDefault(typeParameter) { if (!typeParameter.default) { if (typeParameter.target) { var targetDefault = getResolvedTypeParameterDefault(typeParameter.target); typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintType; } else { // To block recursion, set the initial value to the resolvingDefaultType. typeParameter.default = resolvingDefaultType; var defaultDeclaration = typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; }); var defaultType = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintType; if (typeParameter.default === resolvingDefaultType) { // If we have not been called recursively, set the correct default type. typeParameter.default = defaultType; } } } else if (typeParameter.default === resolvingDefaultType) { // If we are called recursively for this type parameter, mark the default as circular. typeParameter.default = circularConstraintType; } return typeParameter.default; } /** * Gets the default type for a type parameter. * * If the type parameter is the result of an instantiation, this gets the instantiated * default type of its target. If the type parameter has no default type or the default is * circular, `undefined` is returned. */ function getDefaultFromTypeParameter(typeParameter) { var defaultType = getResolvedTypeParameterDefault(typeParameter); return defaultType !== noConstraintType && defaultType !== circularConstraintType ? defaultType : undefined; } function hasNonCircularTypeParameterDefault(typeParameter) { return getResolvedTypeParameterDefault(typeParameter) !== circularConstraintType; } /** * Indicates whether the declaration of a typeParameter has a default type. */ function hasTypeParameterDefault(typeParameter) { return !!(typeParameter.symbol && ts.forEach(typeParameter.symbol.declarations, function (decl) { return ts.isTypeParameterDeclaration(decl) && decl.default; })); } /** * For a type parameter, return the base constraint of the type parameter. For the string, number, * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the * type itself. Note that the apparent type of a union type is the union type itself. */ function getApparentType(type) { var t = type.flags & 1081344 /* TypeVariable */ ? getBaseConstraintOfType(type) || emptyObjectType : type; return t.flags & 262144 /* Intersection */ ? getApparentTypeOfIntersectionType(t) : t.flags & 524322 /* StringLike */ ? globalStringType : t.flags & 84 /* NumberLike */ ? globalNumberType : t.flags & 136 /* BooleanLike */ ? globalBooleanType : t.flags & 1536 /* ESSymbolLike */ ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= 2 /* ES2015 */) : t.flags & 33554432 /* NonPrimitive */ ? emptyObjectType : t; } function createUnionOrIntersectionProperty(containingType, name) { var props; var types = containingType.types; var isUnion = containingType.flags & 131072 /* Union */; var excludeModifiers = isUnion ? 24 /* NonPublicAccessibilityModifier */ : 0; // Flags we want to propagate to the result if they exist in all source symbols var commonFlags = isUnion ? 0 /* None */ : 16777216 /* Optional */; var syntheticFlag = 4 /* SyntheticMethod */; var checkFlags = 0; for (var _i = 0, types_5 = types; _i < types_5.length; _i++) { var current = types_5[_i]; var type = getApparentType(current); if (type !== unknownType) { var prop = getPropertyOfType(type, name); var modifiers = prop ? ts.getDeclarationModifierFlagsFromSymbol(prop) : 0; if (prop && !(modifiers & excludeModifiers)) { commonFlags &= prop.flags; props = ts.appendIfUnique(props, prop); checkFlags |= (isReadonlySymbol(prop) ? 8 /* Readonly */ : 0) | (!(modifiers & 24 /* NonPublicAccessibilityModifier */) ? 64 /* ContainsPublic */ : 0) | (modifiers & 16 /* Protected */ ? 128 /* ContainsProtected */ : 0) | (modifiers & 8 /* Private */ ? 256 /* ContainsPrivate */ : 0) | (modifiers & 32 /* Static */ ? 512 /* ContainsStatic */ : 0); if (!isMethodLike(prop)) { syntheticFlag = 2 /* SyntheticProperty */; } } else if (isUnion) { checkFlags |= 16 /* Partial */; } } } if (!props) { return undefined; } if (props.length === 1 && !(checkFlags & 16 /* Partial */)) { return props[0]; } var propTypes = []; var declarations = []; var commonType = undefined; for (var _a = 0, props_1 = props; _a < props_1.length; _a++) { var prop = props_1[_a]; if (prop.declarations) { ts.addRange(declarations, prop.declarations); } var type = getTypeOfSymbol(prop); if (!commonType) { commonType = type; } else if (type !== commonType) { checkFlags |= 32 /* HasNonUniformType */; } propTypes.push(type); } var result = createSymbol(4 /* Property */ | commonFlags, name, syntheticFlag | checkFlags); result.containingType = containingType; result.declarations = declarations; result.type = isUnion ? getUnionType(propTypes) : getIntersectionType(propTypes); return result; } // Return the symbol for a given property in a union or intersection type, or undefined if the property // does not exist in any constituent type. Note that the returned property may only be present in some // constituents, in which case the isPartial flag is set when the containing type is union type. We need // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. function getUnionOrIntersectionProperty(type, name) { var properties = type.propertyCache || (type.propertyCache = ts.createSymbolTable()); var property = properties.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name); if (property) { properties.set(name, property); } } return property; } function getPropertyOfUnionOrIntersectionType(type, name) { var property = getUnionOrIntersectionProperty(type, name); // We need to filter out partial properties in union types return property && !(ts.getCheckFlags(property) & 16 /* Partial */) ? property : undefined; } /** * Return the symbol for the property with the given name in the given type. Creates synthetic union properties when * necessary, maps primitive types and type parameters are to their apparent types, and augments with properties from * Object and Function as appropriate. * * @param type a type to look up property from * @param name a name of property to look up in a given type */ function getPropertyOfType(type, name) { type = getApparentType(type); if (type.flags & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(type); var symbol = resolved.members.get(name); if (symbol && symbolIsValue(symbol)) { return symbol; } if (resolved === anyFunctionType || resolved.callSignatures.length || resolved.constructSignatures.length) { var symbol_1 = getPropertyOfObjectType(globalFunctionType, name); if (symbol_1) { return symbol_1; } } return getPropertyOfObjectType(globalObjectType, name); } if (type.flags & 393216 /* UnionOrIntersection */) { return getPropertyOfUnionOrIntersectionType(type, name); } return undefined; } function getSignaturesOfStructuredType(type, kind) { if (type.flags & 458752 /* StructuredType */) { var resolved = resolveStructuredTypeMembers(type); return kind === 0 /* Call */ ? resolved.callSignatures : resolved.constructSignatures; } return ts.emptyArray; } /** * Return the signatures of the given kind in the given type. Creates synthetic union signatures when necessary and * maps primitive types and type parameters are to their apparent types. */ function getSignaturesOfType(type, kind) { return getSignaturesOfStructuredType(getApparentType(type), kind); } function getIndexInfoOfStructuredType(type, kind) { if (type.flags & 458752 /* StructuredType */) { var resolved = resolveStructuredTypeMembers(type); return kind === 0 /* String */ ? resolved.stringIndexInfo : resolved.numberIndexInfo; } } function getIndexTypeOfStructuredType(type, kind) { var info = getIndexInfoOfStructuredType(type, kind); return info && info.type; } // Return the indexing info of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. function getIndexInfoOfType(type, kind) { return getIndexInfoOfStructuredType(getApparentType(type), kind); } // Return the index type of the given kind in the given type. Creates synthetic union index types when necessary and // maps primitive types and type parameters are to their apparent types. function getIndexTypeOfType(type, kind) { return getIndexTypeOfStructuredType(getApparentType(type), kind); } function getImplicitIndexTypeOfType(type, kind) { if (isObjectTypeWithInferableIndex(type)) { var propTypes = []; for (var _i = 0, _a = getPropertiesOfType(type); _i < _a.length; _i++) { var prop = _a[_i]; if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) { propTypes.push(getTypeOfSymbol(prop)); } } if (propTypes.length) { return getUnionType(propTypes, /*subtypeReduction*/ true); } } return undefined; } // Return list of type parameters with duplicates removed (duplicate identifier errors are generated in the actual // type checking functions). function getTypeParametersFromDeclaration(declaration) { var result; ts.forEach(ts.getEffectiveTypeParameterDeclarations(declaration), function (node) { var tp = getDeclaredTypeOfTypeParameter(node.symbol); result = ts.appendIfUnique(result, tp); }); return result; } function symbolsToArray(symbols) { var result = []; symbols.forEach(function (symbol, id) { if (!isReservedMemberName(id)) { result.push(symbol); } }); return result; } function isJSDocOptionalParameter(node) { if (ts.isInJavaScriptFile(node)) { if (node.type && node.type.kind === 276 /* JSDocOptionalType */) { return true; } var paramTags = ts.getJSDocParameterTags(node); if (paramTags) { for (var _i = 0, paramTags_1 = paramTags; _i < paramTags_1.length; _i++) { var paramTag = paramTags_1[_i]; if (paramTag.isBracketed) { return true; } if (paramTag.typeExpression) { return paramTag.typeExpression.type.kind === 276 /* JSDocOptionalType */; } } } } } function tryFindAmbientModule(moduleName, withAugmentations) { if (ts.isExternalModuleNameRelative(moduleName)) { return undefined; } var symbol = getSymbol(globals, '"' + moduleName + '"', 512 /* ValueModule */); // merged symbol is module declaration symbol combined with all augmentations return symbol && withAugmentations ? getMergedSymbol(symbol) : symbol; } function isOptionalParameter(node) { if (ts.hasQuestionToken(node) || isJSDocOptionalParameter(node)) { return true; } if (node.initializer) { var signatureDeclaration = node.parent; var signature = getSignatureFromDeclaration(signatureDeclaration); var parameterIndex = ts.indexOf(signatureDeclaration.parameters, node); ts.Debug.assert(parameterIndex >= 0); return parameterIndex >= signature.minArgumentCount; } var iife = ts.getImmediatelyInvokedFunctionExpression(node.parent); if (iife) { return !node.type && !node.dotDotDotToken && ts.indexOf(node.parent.parameters, node) >= iife.arguments.length; } return false; } function createTypePredicateFromTypePredicateNode(node) { var parameterName = node.parameterName; if (parameterName.kind === 71 /* Identifier */) { return { kind: 1 /* Identifier */, parameterName: parameterName ? parameterName.escapedText : undefined, parameterIndex: parameterName ? getTypePredicateParameterIndex(node.parent.parameters, parameterName) : undefined, type: getTypeFromTypeNode(node.type) }; } else { return { kind: 0 /* This */, type: getTypeFromTypeNode(node.type) }; } } /** * Gets the minimum number of type arguments needed to satisfy all non-optional type * parameters. */ function getMinTypeArgumentCount(typeParameters) { var minTypeArgumentCount = 0; if (typeParameters) { for (var i = 0; i < typeParameters.length; i++) { if (!hasTypeParameterDefault(typeParameters[i])) { minTypeArgumentCount = i + 1; } } } return minTypeArgumentCount; } /** * Fill in default types for unsupplied type arguments. If `typeArguments` is undefined * when a default type is supplied, a new array will be created and returned. * * @param typeArguments The supplied type arguments. * @param typeParameters The requested type parameters. * @param minTypeArgumentCount The minimum number of required type arguments. */ function fillMissingTypeArguments(typeArguments, typeParameters, minTypeArgumentCount, isJavaScriptImplicitAny) { var numTypeParameters = ts.length(typeParameters); if (numTypeParameters) { var numTypeArguments = ts.length(typeArguments); if (isJavaScriptImplicitAny || (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters)) { if (!typeArguments) { typeArguments = []; } // Map an unsatisfied type parameter with a default type. // If a type parameter does not have a default type, or if the default type // is a forward reference, the empty object type is used. for (var i = numTypeArguments; i < numTypeParameters; i++) { typeArguments[i] = getDefaultTypeArgumentType(isJavaScriptImplicitAny); } for (var i = numTypeArguments; i < numTypeParameters; i++) { var mapper = createTypeMapper(typeParameters, typeArguments); var defaultType = getDefaultFromTypeParameter(typeParameters[i]); if (defaultType && isTypeIdenticalTo(defaultType, emptyObjectType) && isJavaScriptImplicitAny) { defaultType = anyType; } typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny); } typeArguments.length = typeParameters.length; } } return typeArguments; } function getSignatureFromDeclaration(declaration) { var links = getNodeLinks(declaration); if (!links.resolvedSignature) { var parameters = []; var hasLiteralTypes = false; var minArgumentCount = 0; var thisParameter = undefined; var hasThisParameter = void 0; var iife = ts.getImmediatelyInvokedFunctionExpression(declaration); var isJSConstructSignature = ts.isJSDocConstructSignature(declaration); var isUntypedSignatureInJSFile = !iife && !isJSConstructSignature && ts.isInJavaScriptFile(declaration) && !ts.hasJSDocParameterTags(declaration); // If this is a JSDoc construct signature, then skip the first parameter in the // parameter list. The first parameter represents the return type of the construct // signature. for (var i = isJSConstructSignature ? 1 : 0; i < declaration.parameters.length; i++) { var param = declaration.parameters[i]; var paramSymbol = param.symbol; // Include parameter symbol instead of property symbol in the signature if (paramSymbol && !!(paramSymbol.flags & 4 /* Property */) && !ts.isBindingPattern(param.name)) { var resolvedSymbol = resolveName(param, paramSymbol.escapedName, 107455 /* Value */, undefined, undefined, /*isUse*/ false); paramSymbol = resolvedSymbol; } if (i === 0 && paramSymbol.escapedName === "this") { hasThisParameter = true; thisParameter = param.symbol; } else { parameters.push(paramSymbol); } if (param.type && param.type.kind === 174 /* LiteralType */) { hasLiteralTypes = true; } // Record a new minimum argument count if this is not an optional parameter var isOptionalParameter_1 = param.initializer || param.questionToken || param.dotDotDotToken || iife && parameters.length > iife.arguments.length && !param.type || isJSDocOptionalParameter(param) || isUntypedSignatureInJSFile; if (!isOptionalParameter_1) { minArgumentCount = parameters.length; } } // If only one accessor includes a this-type annotation, the other behaves as if it had the same type annotation if ((declaration.kind === 154 /* GetAccessor */ || declaration.kind === 155 /* SetAccessor */) && !hasNonBindableDynamicName(declaration) && (!hasThisParameter || !thisParameter)) { var otherKind = declaration.kind === 154 /* GetAccessor */ ? 155 /* SetAccessor */ : 154 /* GetAccessor */; var other = ts.getDeclarationOfKind(getSymbolOfNode(declaration), otherKind); if (other) { thisParameter = getAnnotatedAccessorThisParameter(other); } } var classType = declaration.kind === 153 /* Constructor */ ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(declaration.parent.symbol)) : undefined; var typeParameters = classType ? classType.localTypeParameters : getTypeParametersFromDeclaration(declaration); var returnType = getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType); var typePredicate = declaration.type && declaration.type.kind === 159 /* TypePredicate */ ? createTypePredicateFromTypePredicateNode(declaration.type) : undefined; var hasRestLikeParameter = ts.hasRestParameter(declaration) || ts.isInJavaScriptFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters); links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestLikeParameter, hasLiteralTypes); } return links.resolvedSignature; } function maybeAddJsSyntheticRestParameter(declaration, parameters) { // JS functions get a free rest parameter if: // a) The last parameter has `...` preceding its type // b) It references `arguments` somewhere var lastParam = ts.lastOrUndefined(declaration.parameters); var lastParamTags = lastParam && ts.getJSDocParameterTags(lastParam); var lastParamVariadicType = lastParamTags && ts.firstDefined(lastParamTags, function (p) { return p.typeExpression && ts.isJSDocVariadicType(p.typeExpression.type) ? p.typeExpression.type : undefined; }); if (!lastParamVariadicType && !containsArgumentsReference(declaration)) { return false; } var syntheticArgsSymbol = createSymbol(3 /* Variable */, "args"); syntheticArgsSymbol.type = lastParamVariadicType ? createArrayType(getTypeFromTypeNode(lastParamVariadicType.type)) : anyArrayType; syntheticArgsSymbol.isRestParameter = true; if (lastParamVariadicType) { // Replace the last parameter with a rest parameter. parameters.pop(); } parameters.push(syntheticArgsSymbol); return true; } function getSignatureReturnTypeFromDeclaration(declaration, isJSConstructSignature, classType) { if (isJSConstructSignature) { return getTypeFromTypeNode(declaration.parameters[0].type); } else if (classType) { return classType; } var typeNode = ts.getEffectiveReturnTypeNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); } // TypeScript 1.0 spec (April 2014): // If only one accessor includes a type annotation, the other behaves as if it had the same type annotation. if (declaration.kind === 154 /* GetAccessor */ && !hasNonBindableDynamicName(declaration)) { var setter = ts.getDeclarationOfKind(getSymbolOfNode(declaration), 155 /* SetAccessor */); return getAnnotatedAccessorType(setter); } if (ts.nodeIsMissing(declaration.body)) { return anyType; } } function containsArgumentsReference(declaration) { var links = getNodeLinks(declaration); if (links.containsArgumentsReference === undefined) { if (links.flags & 8192 /* CaptureArguments */) { links.containsArgumentsReference = true; } else { links.containsArgumentsReference = traverse(declaration.body); } } return links.containsArgumentsReference; function traverse(node) { if (!node) return false; switch (node.kind) { case 71 /* Identifier */: return node.escapedText === "arguments" && ts.isExpressionNode(node); case 150 /* PropertyDeclaration */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return node.name.kind === 145 /* ComputedPropertyName */ && traverse(node.name); default: return !ts.nodeStartsNewLexicalEnvironment(node) && !ts.isPartOfTypeNode(node) && ts.forEachChild(node, traverse); } } } function getSignaturesOfSymbol(symbol) { if (!symbol) return ts.emptyArray; var result = []; for (var i = 0; i < symbol.declarations.length; i++) { var node = symbol.declarations[i]; switch (node.kind) { case 161 /* FunctionType */: case 162 /* ConstructorType */: case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 158 /* IndexSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 277 /* JSDocFunctionType */: // Don't include signature if node is the implementation of an overloaded function. A node is considered // an implementation node if it has a body and the previous node is of the same kind and immediately // precedes the implementation node (i.e. has the same parent and ends where the implementation starts). if (i > 0 && node.body) { var previous = symbol.declarations[i - 1]; if (node.parent === previous.parent && node.kind === previous.kind && node.pos === previous.end) { break; } } result.push(getSignatureFromDeclaration(node)); } } return result; } function resolveExternalModuleTypeByLiteral(name) { var moduleSym = resolveExternalModuleName(name, name); if (moduleSym) { var resolvedModuleSymbol = resolveExternalModuleSymbol(moduleSym); if (resolvedModuleSymbol) { return getTypeOfSymbol(resolvedModuleSymbol); } } return anyType; } function getThisTypeOfSignature(signature) { if (signature.thisParameter) { return getTypeOfSymbol(signature.thisParameter); } } function getReturnTypeOfSignature(signature) { if (!signature.resolvedReturnType) { if (!pushTypeResolution(signature, 3 /* ResolvedReturnType */)) { return unknownType; } var type = void 0; if (signature.target) { type = instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper); } else if (signature.unionSignatures) { type = getUnionType(ts.map(signature.unionSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); } else { type = getReturnTypeFromBody(signature.declaration); } if (!popTypeResolution()) { type = anyType; if (noImplicitAny) { var declaration = signature.declaration; var name = ts.getNameOfDeclaration(declaration); if (name) { error(name, ts.Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, ts.declarationNameToString(name)); } else { error(declaration, ts.Diagnostics.Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions); } } } signature.resolvedReturnType = type; } return signature.resolvedReturnType; } function isResolvingReturnTypeOfSignature(signature) { return !signature.resolvedReturnType && findResolutionCycleStartIndex(signature, 3 /* ResolvedReturnType */) >= 0; } function getRestTypeOfSignature(signature) { if (signature.hasRestParameter) { var type = getTypeOfSymbol(ts.lastOrUndefined(signature.parameters)); if (ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType) { return type.typeArguments[0]; } } return anyType; } function getSignatureInstantiation(signature, typeArguments, isJavascript) { typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, getMinTypeArgumentCount(signature.typeParameters), isJavascript); var instantiations = signature.instantiations || (signature.instantiations = ts.createMap()); var id = getTypeListId(typeArguments); var instantiation = instantiations.get(id); if (!instantiation) { instantiations.set(id, instantiation = createSignatureInstantiation(signature, typeArguments)); } return instantiation; } function createSignatureInstantiation(signature, typeArguments) { return instantiateSignature(signature, createTypeMapper(signature.typeParameters, typeArguments), /*eraseTypeParameters*/ true); } function getErasedSignature(signature) { return signature.typeParameters ? signature.erasedSignatureCache || (signature.erasedSignatureCache = createErasedSignature(signature)) : signature; } function createErasedSignature(signature) { // Create an instantiation of the signature where all type arguments are the any type. return instantiateSignature(signature, createTypeEraser(signature.typeParameters), /*eraseTypeParameters*/ true); } function getCanonicalSignature(signature) { return signature.typeParameters ? signature.canonicalSignatureCache || (signature.canonicalSignatureCache = createCanonicalSignature(signature)) : signature; } function createCanonicalSignature(signature) { // Create an instantiation of the signature where each unconstrained type parameter is replaced with // its original. When a generic class or interface is instantiated, each generic method in the class or // interface is instantiated with a fresh set of cloned type parameters (which we need to handle scenarios // where different generations of the same type parameter are in scope). This leads to a lot of new type // identities, and potentially a lot of work comparing those identities, so here we create an instantiation // that uses the original type identities for all unconstrained type parameters. return getSignatureInstantiation(signature, ts.map(signature.typeParameters, function (tp) { return tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp; }), ts.isInJavaScriptFile(signature.declaration)); } function getBaseSignature(signature) { var typeParameters = signature.typeParameters; if (typeParameters) { var typeEraser_1 = createTypeEraser(typeParameters); var baseConstraints = ts.map(typeParameters, function (tp) { return instantiateType(getBaseConstraintOfType(tp), typeEraser_1) || emptyObjectType; }); return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true); } return signature; } 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 === 153 /* Constructor */ || signature.declaration.kind === 157 /* ConstructSignature */; var type = createObjectType(16 /* Anonymous */); type.members = emptySymbols; type.properties = ts.emptyArray; type.callSignatures = !isConstructor ? [signature] : ts.emptyArray; type.constructSignatures = isConstructor ? [signature] : ts.emptyArray; signature.isolatedSignatureType = type; } return signature.isolatedSignatureType; } function getIndexSymbol(symbol) { return symbol.members.get("__index" /* Index */); } function getIndexDeclarationOfSymbol(symbol, kind) { var syntaxKind = kind === 1 /* Number */ ? 133 /* NumberKeyword */ : 136 /* StringKeyword */; var indexSymbol = getIndexSymbol(symbol); if (indexSymbol) { for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; var node = decl; if (node.parameters.length === 1) { var parameter = node.parameters[0]; if (parameter && parameter.type && parameter.type.kind === syntaxKind) { return node; } } } } return undefined; } function createIndexInfo(type, isReadonly, declaration) { return { type: type, isReadonly: isReadonly, declaration: declaration }; } function getIndexInfoOfSymbol(symbol, kind) { var declaration = getIndexDeclarationOfSymbol(symbol, kind); if (declaration) { return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, ts.hasModifier(declaration, 64 /* Readonly */), declaration); } return undefined; } function getConstraintDeclaration(type) { return type.symbol && ts.getDeclarationOfKind(type.symbol, 146 /* TypeParameter */).constraint; } function getConstraintFromTypeParameter(typeParameter) { if (!typeParameter.constraint) { if (typeParameter.target) { var targetConstraint = getConstraintOfTypeParameter(typeParameter.target); typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType; } else { var constraintDeclaration = getConstraintDeclaration(typeParameter); typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : noConstraintType; } } return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint; } function getParentSymbolOfTypeParameter(typeParameter) { return getSymbolOfNode(ts.getDeclarationOfKind(typeParameter.symbol, 146 /* TypeParameter */).parent); } function getTypeListId(types) { var result = ""; if (types) { var length_4 = types.length; var i = 0; while (i < length_4) { var startId = types[i].id; var count = 1; while (i + count < length_4 && types[i + count].id === startId + count) { count++; } if (result.length) { result += ","; } result += startId; if (count > 1) { result += ":" + count; } i += count; } } return result; } // This function is used to propagate certain flags when creating new object type references and union types. // It is only necessary to do so if a constituent type might be the undefined type, the null type, the type // of an object literal or the anyFunctionType. This is because there are operations in the type checker // that care about the presence of such types at arbitrary depth in a containing type. function getPropagatingFlagsOfTypes(types, excludeKinds) { var result = 0; for (var _i = 0, types_6 = types; _i < types_6.length; _i++) { var type = types_6[_i]; if (!(type.flags & excludeKinds)) { result |= type.flags; } } return result & 29360128 /* PropagatingFlags */; } function createTypeReference(target, typeArguments) { var id = getTypeListId(typeArguments); var type = target.instantiations.get(id); if (!type) { type = createObjectType(4 /* Reference */, target.symbol); target.instantiations.set(id, type); type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; type.target = target; type.typeArguments = typeArguments; } return type; } function cloneTypeReference(source) { var type = createType(source.flags); type.symbol = source.symbol; type.objectFlags = source.objectFlags; type.target = source.target; type.typeArguments = source.typeArguments; return type; } function getTypeReferenceArity(type) { return ts.length(type.target.typeParameters); } /** * Get type from type-reference that reference to class or interface */ function getTypeFromClassOrInterfaceReference(node, symbol, typeArgs) { var type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)); var typeParameters = type.localTypeParameters; if (typeParameters) { var numTypeArguments = ts.length(node.typeArguments); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); var isJs = ts.isInJavaScriptFile(node); var isJsImplicitAny = !noImplicitAny && isJs; if (!isJsImplicitAny && (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length)) { var missingAugmentsTag = isJs && node.parent.kind !== 282 /* JSDocAugmentsTag */; var diag = minTypeArgumentCount === typeParameters.length ? missingAugmentsTag ? ts.Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag : ts.Diagnostics.Generic_type_0_requires_1_type_argument_s : missingAugmentsTag ? ts.Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; var typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, 1 /* WriteArrayAsGenericType */); error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length); if (!isJs) { // TODO: Adopt same permissive behavior in TS as in JS to reduce follow-on editing experience failures (requires editing fillMissingTypeArguments) return unknownType; } } // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. var typeArguments = ts.concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArgs, typeParameters, minTypeArgumentCount, isJs)); return createTypeReference(type, typeArguments); } if (node.typeArguments) { error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); return unknownType; } return type; } function getTypeAliasInstantiation(symbol, typeArguments) { var type = getDeclaredTypeOfSymbol(symbol); var links = getSymbolLinks(symbol); var typeParameters = links.typeParameters; var id = getTypeListId(typeArguments); var instantiation = links.instantiations.get(id); if (!instantiation) { links.instantiations.set(id, instantiation = instantiateType(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), ts.isInJavaScriptFile(symbol.valueDeclaration))))); } return instantiation; } /** * Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include * references to the type parameters of the alias. We replace those with the actual type arguments by instantiating the * declared type. Instantiations are cached using the type identities of the type arguments as the key. */ function getTypeFromTypeAliasReference(node, symbol, typeArguments) { var type = getDeclaredTypeOfSymbol(symbol); var typeParameters = getSymbolLinks(symbol).typeParameters; if (typeParameters) { var numTypeArguments = ts.length(node.typeArguments); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { error(node, minTypeArgumentCount === typeParameters.length ? ts.Diagnostics.Generic_type_0_requires_1_type_argument_s : ts.Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, symbolToString(symbol), minTypeArgumentCount, typeParameters.length); return unknownType; } return getTypeAliasInstantiation(symbol, typeArguments); } if (node.typeArguments) { error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol)); return unknownType; } return type; } function getTypeReferenceName(node) { switch (node.kind) { case 160 /* TypeReference */: return node.typeName; case 202 /* ExpressionWithTypeArguments */: // We only support expressions that are simple qualified names. For other // expressions this produces undefined. var expr = node.expression; if (ts.isEntityNameExpression(expr)) { return expr; } } return undefined; } function resolveTypeReferenceName(typeReferenceName, meaning) { if (!typeReferenceName) { return unknownSymbol; } return resolveEntityName(typeReferenceName, meaning) || unknownSymbol; } function getTypeReferenceType(node, symbol) { var typeArguments = typeArgumentsFromTypeReferenceNode(node); // Do unconditionally so we mark type arguments as referenced. if (symbol === unknownSymbol) { return unknownType; } var type = getTypeReferenceTypeWorker(node, symbol, typeArguments); if (type) { return type; } // Get type from reference to named type that cannot be generic (enum or type parameter) var res = tryGetDeclaredTypeOfSymbol(symbol); if (res !== undefined) { if (typeArguments) { error(node, ts.Diagnostics.Type_0_is_not_generic, symbolToString(symbol)); return unknownType; } return res; } if (!(symbol.flags & 107455 /* Value */ && isJSDocTypeReference(node))) { return unknownType; } // A jsdoc TypeReference may have resolved to a value (as opposed to a type). If // the symbol is a constructor function, return the inferred class type; otherwise, // the type of this reference is just the type of the value we resolved to. var valueType = getTypeOfSymbol(symbol); if (valueType.symbol && !isInferredClassType(valueType)) { var referenceType = getTypeReferenceTypeWorker(node, valueType.symbol, typeArguments); if (referenceType) { return referenceType; } } // Resolve the type reference as a Type for the purpose of reporting errors. resolveTypeReferenceName(getTypeReferenceName(node), 793064 /* Type */); return valueType; } function getTypeReferenceTypeWorker(node, symbol, typeArguments) { if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) { return getTypeFromClassOrInterfaceReference(node, symbol, typeArguments); } if (symbol.flags & 524288 /* TypeAlias */) { return getTypeFromTypeAliasReference(node, symbol, typeArguments); } if (symbol.flags & 16 /* Function */ && isJSDocTypeReference(node) && (symbol.members || ts.getJSDocClassTag(symbol.valueDeclaration))) { return getInferredClassType(symbol); } } function isJSDocTypeReference(node) { return node.flags & 1048576 /* JSDoc */ && node.kind === 160 /* TypeReference */; } function getIntendedTypeFromJSDocTypeReference(node) { if (ts.isIdentifier(node.typeName)) { if (node.typeName.escapedText === "Object") { if (ts.isJSDocIndexSignature(node)) { var indexed = getTypeFromTypeNode(node.typeArguments[0]); var target = getTypeFromTypeNode(node.typeArguments[1]); var index = createIndexInfo(target, /*isReadonly*/ false); return createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, indexed === stringType && index, indexed === numberType && index); } return anyType; } switch (node.typeName.escapedText) { case "String": return stringType; case "Number": return numberType; case "Boolean": return booleanType; case "Void": return voidType; case "Undefined": return undefinedType; case "Null": return nullType; case "Function": case "function": return globalFunctionType; case "Array": case "array": return !node.typeArguments || !node.typeArguments.length ? anyArrayType : undefined; case "Promise": case "promise": return !node.typeArguments || !node.typeArguments.length ? createPromiseType(anyType) : undefined; } } } function getTypeFromJSDocNullableTypeNode(node) { var type = getTypeFromTypeNode(node.type); return strictNullChecks ? getNullableType(type, 8192 /* Null */) : type; } function getTypeFromTypeReference(node) { var links = getNodeLinks(node); if (!links.resolvedType) { var symbol = void 0; var type = void 0; var meaning = 793064 /* Type */; if (isJSDocTypeReference(node)) { type = getIntendedTypeFromJSDocTypeReference(node); meaning |= 107455 /* Value */; } if (!type) { symbol = resolveTypeReferenceName(getTypeReferenceName(node), meaning); type = getTypeReferenceType(node, symbol); } // Cache both the resolved symbol and the resolved type. The resolved symbol is needed in when we check the // type reference in checkTypeReferenceOrExpressionWithTypeArguments. links.resolvedSymbol = symbol; links.resolvedType = type; } return links.resolvedType; } function typeArgumentsFromTypeReferenceNode(node) { return ts.map(node.typeArguments, getTypeFromTypeNode); } function getTypeFromTypeQueryNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { // TypeScript 1.0 spec (April 2014): 3.6.3 // The expression is processed as an identifier expression (section 4.3) // or property access expression(section 4.10), // the widened type(section 3.9) of which becomes the result. links.resolvedType = getWidenedType(checkExpression(node.exprName)); } return links.resolvedType; } function getTypeOfGlobalSymbol(symbol, arity) { function getTypeDeclaration(symbol) { var declarations = symbol.declarations; for (var _i = 0, declarations_3 = declarations; _i < declarations_3.length; _i++) { var declaration = declarations_3[_i]; switch (declaration.kind) { case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: return declaration; } } } if (!symbol) { return arity ? emptyGenericType : emptyObjectType; } var type = getDeclaredTypeOfSymbol(symbol); if (!(type.flags & 65536 /* Object */)) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_be_a_class_or_interface_type, ts.symbolName(symbol)); return arity ? emptyGenericType : emptyObjectType; } if (ts.length(type.typeParameters) !== arity) { error(getTypeDeclaration(symbol), ts.Diagnostics.Global_type_0_must_have_1_type_parameter_s, ts.symbolName(symbol), arity); return arity ? emptyGenericType : emptyObjectType; } return type; } function getGlobalValueSymbol(name, reportErrors) { return getGlobalSymbol(name, 107455 /* Value */, reportErrors ? ts.Diagnostics.Cannot_find_global_value_0 : undefined); } function getGlobalTypeSymbol(name, reportErrors) { return getGlobalSymbol(name, 793064 /* Type */, reportErrors ? ts.Diagnostics.Cannot_find_global_type_0 : undefined); } function getGlobalSymbol(name, meaning, diagnostic) { // Don't track references for global symbols anyway, so value if `isReference` is arbitrary return resolveName(undefined, name, meaning, diagnostic, name, /*isUse*/ false); } function getGlobalType(name, arity, reportErrors) { var symbol = getGlobalTypeSymbol(name, reportErrors); return symbol || reportErrors ? getTypeOfGlobalSymbol(symbol, arity) : undefined; } function getGlobalTypedPropertyDescriptorType() { return deferredGlobalTypedPropertyDescriptorType || (deferredGlobalTypedPropertyDescriptorType = getGlobalType("TypedPropertyDescriptor", /*arity*/ 1, /*reportErrors*/ true)) || emptyGenericType; } function getGlobalTemplateStringsArrayType() { return deferredGlobalTemplateStringsArrayType || (deferredGlobalTemplateStringsArrayType = getGlobalType("TemplateStringsArray", /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType; } function getGlobalESSymbolConstructorSymbol(reportErrors) { return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol", reportErrors)); } function getGlobalESSymbolType(reportErrors) { return deferredGlobalESSymbolType || (deferredGlobalESSymbolType = getGlobalType("Symbol", /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalPromiseType(reportErrors) { return deferredGlobalPromiseType || (deferredGlobalPromiseType = getGlobalType("Promise", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalPromiseConstructorSymbol(reportErrors) { return deferredGlobalPromiseConstructorSymbol || (deferredGlobalPromiseConstructorSymbol = getGlobalValueSymbol("Promise", reportErrors)); } function getGlobalPromiseConstructorLikeType(reportErrors) { return deferredGlobalPromiseConstructorLikeType || (deferredGlobalPromiseConstructorLikeType = getGlobalType("PromiseConstructorLike", /*arity*/ 0, reportErrors)) || emptyObjectType; } function getGlobalAsyncIterableType(reportErrors) { return deferredGlobalAsyncIterableType || (deferredGlobalAsyncIterableType = getGlobalType("AsyncIterable", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncIteratorType(reportErrors) { return deferredGlobalAsyncIteratorType || (deferredGlobalAsyncIteratorType = getGlobalType("AsyncIterator", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalAsyncIterableIteratorType(reportErrors) { return deferredGlobalAsyncIterableIteratorType || (deferredGlobalAsyncIterableIteratorType = getGlobalType("AsyncIterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIterableType(reportErrors) { return deferredGlobalIterableType || (deferredGlobalIterableType = getGlobalType("Iterable", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIteratorType(reportErrors) { return deferredGlobalIteratorType || (deferredGlobalIteratorType = getGlobalType("Iterator", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalIterableIteratorType(reportErrors) { return deferredGlobalIterableIteratorType || (deferredGlobalIterableIteratorType = getGlobalType("IterableIterator", /*arity*/ 1, reportErrors)) || emptyGenericType; } function getGlobalTypeOrUndefined(name, arity) { if (arity === void 0) { arity = 0; } var symbol = getGlobalSymbol(name, 793064 /* Type */, /*diagnostic*/ undefined); return symbol && getTypeOfGlobalSymbol(symbol, arity); } /** * Returns a type that is inside a namespace at the global scope, e.g. * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type */ function getExportedTypeFromNamespace(namespace, name) { var namespaceSymbol = getGlobalSymbol(namespace, 1920 /* Namespace */, /*diagnosticMessage*/ undefined); var typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, 793064 /* Type */); return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol); } /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ function createTypeFromGenericGlobalType(genericGlobalType, typeArguments) { return genericGlobalType !== emptyGenericType ? createTypeReference(genericGlobalType, typeArguments) : emptyObjectType; } function createTypedPropertyDescriptorType(propertyType) { return createTypeFromGenericGlobalType(getGlobalTypedPropertyDescriptorType(), [propertyType]); } function createAsyncIterableType(iteratedType) { return createTypeFromGenericGlobalType(getGlobalAsyncIterableType(/*reportErrors*/ true), [iteratedType]); } function createAsyncIterableIteratorType(iteratedType) { return createTypeFromGenericGlobalType(getGlobalAsyncIterableIteratorType(/*reportErrors*/ true), [iteratedType]); } function createIterableType(iteratedType) { return createTypeFromGenericGlobalType(getGlobalIterableType(/*reportErrors*/ true), [iteratedType]); } function createIterableIteratorType(iteratedType) { return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(/*reportErrors*/ true), [iteratedType]); } function createArrayType(elementType) { return createTypeFromGenericGlobalType(globalArrayType, [elementType]); } function getTypeFromArrayTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType)); } return links.resolvedType; } // We represent tuple types as type references to synthesized generic interface types created by // this function. The types are of the form: // // interface Tuple extends Array { 0: T0, 1: T1, 2: T2, ... } // // Note that the generic type created by this function has no symbol associated with it. The same // is true for each of the synthesized type parameters. function createTupleTypeOfArity(arity) { var typeParameters = []; var properties = []; for (var i = 0; i < arity; i++) { var typeParameter = createType(32768 /* TypeParameter */); typeParameters.push(typeParameter); var property = createSymbol(4 /* Property */, "" + i); property.type = typeParameter; properties.push(property); } var lengthSymbol = createSymbol(4 /* Property */, "length"); lengthSymbol.type = getLiteralType(arity); properties.push(lengthSymbol); var type = createObjectType(8 /* Tuple */ | 4 /* Reference */); type.typeParameters = typeParameters; type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; type.instantiations = ts.createMap(); type.instantiations.set(getTypeListId(type.typeParameters), type); type.target = type; type.typeArguments = type.typeParameters; type.thisType = createType(32768 /* TypeParameter */); type.thisType.isThisType = true; type.thisType.constraint = type; type.declaredProperties = properties; type.declaredCallSignatures = ts.emptyArray; type.declaredConstructSignatures = ts.emptyArray; type.declaredStringIndexInfo = undefined; type.declaredNumberIndexInfo = undefined; return type; } function getTupleTypeOfArity(arity) { return tupleTypes[arity] || (tupleTypes[arity] = createTupleTypeOfArity(arity)); } function createTupleType(elementTypes) { return createTypeReference(getTupleTypeOfArity(elementTypes.length), elementTypes); } function getTypeFromTupleTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = createTupleType(ts.map(node.elementTypes, getTypeFromTypeNode)); } return links.resolvedType; } function getTypeId(type) { return type.id; } function containsType(types, type) { return ts.binarySearch(types, type, getTypeId, ts.compareValues) >= 0; } // Return true if the given intersection type contains (a) more than one unit type or (b) an object // type and a nullable type (null or undefined). function isEmptyIntersectionType(type) { var combined = 0; for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var t = _a[_i]; if (t.flags & 13536 /* Unit */ && combined & 13536 /* Unit */) { return true; } combined |= t.flags; if (combined & 12288 /* Nullable */ && combined & (65536 /* Object */ | 33554432 /* NonPrimitive */)) { return true; } } return false; } function addTypeToUnion(typeSet, type) { var flags = type.flags; if (flags & 131072 /* Union */) { addTypesToUnion(typeSet, type.types); } else if (flags & 1 /* Any */) { typeSet.containsAny = true; } else if (!strictNullChecks && flags & 12288 /* Nullable */) { if (flags & 4096 /* Undefined */) typeSet.containsUndefined = true; if (flags & 8192 /* Null */) typeSet.containsNull = true; if (!(flags & 4194304 /* ContainsWideningType */)) typeSet.containsNonWideningType = true; } else if (!(flags & 16384 /* Never */ || flags & 262144 /* Intersection */ && isEmptyIntersectionType(type))) { // We ignore 'never' types in unions. Likewise, we ignore intersections of unit types as they are // another form of 'never' (in that they have an empty value domain). We could in theory turn // intersections of unit types into 'never' upon construction, but deferring the reduction makes it // easier to reason about their origin. if (flags & 2 /* String */) typeSet.containsString = true; if (flags & 4 /* Number */) typeSet.containsNumber = true; if (flags & 512 /* ESSymbol */) typeSet.containsESSymbol = true; if (flags & 1120 /* StringOrNumberLiteralOrUnique */) typeSet.containsLiteralOrUniqueESSymbol = true; var len = typeSet.length; var index = len && type.id > typeSet[len - 1].id ? ~len : ts.binarySearch(typeSet, type, getTypeId, ts.compareValues); if (index < 0) { if (!(flags & 65536 /* Object */ && type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) { typeSet.splice(~index, 0, type); } } } } // Add the given types to the given type set. Order is preserved, duplicates are removed, // and nested types of the given kind are flattened into the set. function addTypesToUnion(typeSet, types) { for (var _i = 0, types_7 = types; _i < types_7.length; _i++) { var type = types_7[_i]; addTypeToUnion(typeSet, type); } } function containsIdenticalType(types, type) { for (var _i = 0, types_8 = types; _i < types_8.length; _i++) { var t = types_8[_i]; if (isTypeIdenticalTo(t, type)) { return true; } } return false; } function isSubtypeOfAny(source, targets) { for (var _i = 0, targets_1 = targets; _i < targets_1.length; _i++) { var target = targets_1[_i]; if (source !== target && isTypeSubtypeOf(source, target) && (!(ts.getObjectFlags(getTargetType(source)) & 1 /* Class */) || !(ts.getObjectFlags(getTargetType(target)) & 1 /* Class */) || isTypeDerivedFrom(source, target))) { return true; } } return false; } function isSetOfLiteralsFromSameEnum(types) { var first = types[0]; if (first.flags & 256 /* EnumLiteral */) { var firstEnum = getParentOfSymbol(first.symbol); for (var i = 1; i < types.length; i++) { var other = types[i]; if (!(other.flags & 256 /* EnumLiteral */) || (firstEnum !== getParentOfSymbol(other.symbol))) { return false; } } return true; } return false; } function removeSubtypes(types) { if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) { return; } var i = types.length; while (i > 0) { i--; if (isSubtypeOfAny(types[i], types)) { ts.orderedRemoveItemAt(types, i); } } } function removeRedundantLiteralTypes(types) { var i = types.length; while (i > 0) { i--; var t = types[i]; var remove = t.flags & 32 /* StringLiteral */ && types.containsString || t.flags & 64 /* NumberLiteral */ && types.containsNumber || t.flags & 1024 /* UniqueESSymbol */ && types.containsESSymbol || t.flags & 96 /* StringOrNumberLiteral */ && t.flags & 2097152 /* FreshLiteral */ && containsType(types, t.regularType); if (remove) { ts.orderedRemoveItemAt(types, i); } } } // We sort and deduplicate the constituent types based on object identity. If the subtypeReduction // flag is specified we also reduce the constituent type set to only include types that aren't subtypes // of other types. Subtype reduction is expensive for large union types and is possible only when union // types are known not to circularly reference themselves (as is the case with union types created by // expression constructs such as array literals and the || and ?: operators). Named types can // circularly reference themselves and therefore cannot be subtype reduced during their declaration. // For example, "type Item = string | (() => Item" is a named type that circularly references itself. function getUnionType(types, subtypeReduction, aliasSymbol, aliasTypeArguments) { if (types.length === 0) { return neverType; } if (types.length === 1) { return types[0]; } var typeSet = []; addTypesToUnion(typeSet, types); if (typeSet.containsAny) { return anyType; } if (subtypeReduction) { removeSubtypes(typeSet); } else if (typeSet.containsLiteralOrUniqueESSymbol) { removeRedundantLiteralTypes(typeSet); } if (typeSet.length === 0) { return typeSet.containsNull ? typeSet.containsNonWideningType ? nullType : nullWideningType : typeSet.containsUndefined ? typeSet.containsNonWideningType ? undefinedType : undefinedWideningType : neverType; } return getUnionTypeFromSortedList(typeSet, aliasSymbol, aliasTypeArguments); } // This function assumes the constituent type list is sorted and deduplicated. function getUnionTypeFromSortedList(types, aliasSymbol, aliasTypeArguments) { if (types.length === 0) { return neverType; } if (types.length === 1) { return types[0]; } var id = getTypeListId(types); var type = unionTypes.get(id); if (!type) { var propagatedFlags = getPropagatingFlagsOfTypes(types, /*excludeKinds*/ 12288 /* Nullable */); type = createType(131072 /* Union */ | propagatedFlags); unionTypes.set(id, type); type.types = types; /* Note: This is the alias symbol (or lack thereof) that we see when we first encounter this union type. For aliases of identical unions, eg `type T = A | B; type U = A | B`, the symbol of the first alias encountered is the aliasSymbol. (In the language service, the order may depend on the order in which a user takes actions, such as hovering over symbols.) It's important that we create equivalent union types only once, so that's an unfortunate side effect. */ type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = aliasTypeArguments; } return type; } function getTypeFromUnionTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getUnionType(ts.map(node.types, getTypeFromTypeNode), /*subtypeReduction*/ false, getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node)); } return links.resolvedType; } function addTypeToIntersection(typeSet, type) { if (type.flags & 262144 /* Intersection */) { addTypesToIntersection(typeSet, type.types); } else if (type.flags & 1 /* Any */) { typeSet.containsAny = true; } else if (type.flags & 16384 /* Never */) { typeSet.containsNever = true; } else if (ts.getObjectFlags(type) & 16 /* Anonymous */ && isEmptyObjectType(type)) { typeSet.containsEmptyObject = true; } else if ((strictNullChecks || !(type.flags & 12288 /* Nullable */)) && !ts.contains(typeSet, type)) { if (type.flags & 65536 /* Object */) { typeSet.containsObjectType = true; } if (type.flags & 131072 /* Union */ && typeSet.unionIndex === undefined) { typeSet.unionIndex = typeSet.length; } if (!(type.flags & 65536 /* Object */ && type.objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */) && containsIdenticalType(typeSet, type))) { typeSet.push(type); } } } // Add the given types to the given type set. Order is preserved, freshness is removed from literal // types, duplicates are removed, and nested types of the given kind are flattened into the set. function addTypesToIntersection(typeSet, types) { for (var _i = 0, types_9 = types; _i < types_9.length; _i++) { var type = types_9[_i]; addTypeToIntersection(typeSet, getRegularTypeOfLiteralType(type)); } } // We normalize combinations of intersection and union types based on the distributive property of the '&' // operator. Specifically, because X & (A | B) is equivalent to X & A | X & B, we can transform intersection // types with union type constituents into equivalent union types with intersection type constituents and // effectively ensure that union types are always at the top level in type representations. // // We do not perform structural deduplication on intersection types. Intersection types are created only by the & // type operator and we can't reduce those because we want to support recursive intersection types. For example, // a type alias of the form "type List = T & { next: List }" cannot be reduced during its declaration. // Also, unlike union types, the order of the constituent types is preserved in order that overload resolution // for intersections of types with signatures can be deterministic. function getIntersectionType(types, aliasSymbol, aliasTypeArguments) { if (types.length === 0) { return emptyObjectType; } var typeSet = []; addTypesToIntersection(typeSet, types); if (typeSet.containsNever) { return neverType; } if (typeSet.containsAny) { return anyType; } if (typeSet.containsEmptyObject && !typeSet.containsObjectType) { typeSet.push(emptyObjectType); } if (typeSet.length === 1) { return typeSet[0]; } var unionIndex = typeSet.unionIndex; if (unionIndex !== undefined) { // We are attempting to construct a type of the form X & (A | B) & Y. Transform this into a type of // the form X & A & Y | X & B & Y and recursively reduce until no union type constituents remain. var unionType = typeSet[unionIndex]; return getUnionType(ts.map(unionType.types, function (t) { return getIntersectionType(ts.replaceElement(typeSet, unionIndex, t)); }), /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments); } var id = getTypeListId(typeSet); var type = intersectionTypes.get(id); if (!type) { var propagatedFlags = getPropagatingFlagsOfTypes(typeSet, /*excludeKinds*/ 12288 /* Nullable */); type = createType(262144 /* Intersection */ | propagatedFlags); intersectionTypes.set(id, type); type.types = typeSet; type.aliasSymbol = aliasSymbol; // See comment in `getUnionTypeFromSortedList`. type.aliasTypeArguments = aliasTypeArguments; } return type; } function getTypeFromIntersectionTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getIntersectionType(ts.map(node.types, getTypeFromTypeNode), getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node)); } return links.resolvedType; } function getIndexTypeForGenericType(type) { if (!type.resolvedIndexType) { type.resolvedIndexType = createType(524288 /* Index */); type.resolvedIndexType.type = type; } return type.resolvedIndexType; } function getLiteralTypeFromPropertyName(prop) { return ts.getDeclarationModifierFlagsFromSymbol(prop) & 24 /* NonPublicAccessibilityModifier */ || ts.startsWith(prop.escapedName, "__@") ? neverType : getLiteralType(ts.symbolName(prop)); } function getLiteralTypeFromPropertyNames(type) { return getUnionType(ts.map(getPropertiesOfType(type), getLiteralTypeFromPropertyName)); } function getIndexType(type) { return maybeTypeOfKind(type, 1081344 /* TypeVariable */) ? getIndexTypeForGenericType(type) : ts.getObjectFlags(type) & 32 /* Mapped */ ? getConstraintTypeFromMappedType(type) : type.flags & 1 /* Any */ || getIndexInfoOfType(type, 0 /* String */) ? stringType : getLiteralTypeFromPropertyNames(type); } function getIndexTypeOrString(type) { var indexType = getIndexType(type); return indexType.flags & 16384 /* Never */ ? stringType : indexType; } function getTypeFromTypeOperatorNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { switch (node.operator) { case 127 /* KeyOfKeyword */: links.resolvedType = getIndexType(getTypeFromTypeNode(node.type)); break; case 140 /* UniqueKeyword */: links.resolvedType = node.type.kind === 137 /* SymbolKeyword */ ? getESSymbolLikeTypeForNode(ts.walkUpParenthesizedTypes(node.parent)) : unknownType; break; } } return links.resolvedType; } function createIndexedAccessType(objectType, indexType) { var type = createType(1048576 /* IndexedAccess */); type.objectType = objectType; type.indexType = indexType; return type; } function getPropertyTypeForIndexType(objectType, indexType, accessNode, cacheSymbol) { var accessExpression = accessNode && accessNode.kind === 181 /* ElementAccessExpression */ ? accessNode : undefined; var propName = isTypeUsableAsLateBoundName(indexType) ? getLateBoundNameFromType(indexType) : accessExpression && checkThatExpressionIsProperSymbolReference(accessExpression.argumentExpression, indexType, /*reportError*/ false) ? ts.getPropertyNameForKnownSymbolName(ts.idText(accessExpression.argumentExpression.name)) : undefined; if (propName !== undefined) { var prop = getPropertyOfType(objectType, propName); if (prop) { if (accessExpression) { if (ts.isAssignmentTarget(accessExpression) && (isReferenceToReadonlyEntity(accessExpression, prop) || isReferenceThroughNamespaceImport(accessExpression))) { error(accessExpression.argumentExpression, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(prop)); return unknownType; } if (cacheSymbol) { getNodeLinks(accessNode).resolvedSymbol = prop; } } return getTypeOfSymbol(prop); } } if (!(indexType.flags & 12288 /* Nullable */) && isTypeAssignableToKind(indexType, 524322 /* StringLike */ | 84 /* NumberLike */ | 1536 /* ESSymbolLike */)) { if (isTypeAny(objectType)) { return anyType; } var indexInfo = isTypeAssignableToKind(indexType, 84 /* NumberLike */) && getIndexInfoOfType(objectType, 1 /* Number */) || getIndexInfoOfType(objectType, 0 /* String */) || undefined; if (indexInfo) { if (accessExpression && indexInfo.isReadonly && (ts.isAssignmentTarget(accessExpression) || ts.isDeleteTarget(accessExpression))) { error(accessExpression, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } return indexInfo.type; } if (accessExpression && !isConstEnumObjectType(objectType)) { if (noImplicitAny && !compilerOptions.suppressImplicitAnyIndexErrors) { if (getIndexTypeOfType(objectType, 1 /* Number */)) { error(accessExpression.argumentExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_index_expression_is_not_of_type_number); } else { error(accessExpression, ts.Diagnostics.Element_implicitly_has_an_any_type_because_type_0_has_no_index_signature, typeToString(objectType)); } } return anyType; } } if (accessNode) { var indexNode = accessNode.kind === 181 /* ElementAccessExpression */ ? accessNode.argumentExpression : accessNode.indexType; if (indexType.flags & (32 /* StringLiteral */ | 64 /* NumberLiteral */)) { error(indexNode, ts.Diagnostics.Property_0_does_not_exist_on_type_1, "" + indexType.value, typeToString(objectType)); } else if (indexType.flags & (2 /* String */ | 4 /* Number */)) { error(indexNode, ts.Diagnostics.Type_0_has_no_matching_index_signature_for_type_1, typeToString(objectType), typeToString(indexType)); } else { error(indexNode, ts.Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType)); } return unknownType; } return anyType; } function isGenericObjectType(type) { return type.flags & 1081344 /* TypeVariable */ ? true : ts.getObjectFlags(type) & 32 /* Mapped */ ? isGenericIndexType(getConstraintTypeFromMappedType(type)) : type.flags & 393216 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericObjectType) : false; } function isGenericIndexType(type) { return type.flags & (1081344 /* TypeVariable */ | 524288 /* Index */) ? true : type.flags & 393216 /* UnionOrIntersection */ ? ts.forEach(type.types, isGenericIndexType) : false; } // Return true if the given type is a non-generic object type with a string index signature and no // other members. function isStringIndexOnlyType(type) { if (type.flags & 65536 /* Object */ && !isGenericMappedType(type)) { var t = resolveStructuredTypeMembers(type); return t.properties.length === 0 && t.callSignatures.length === 0 && t.constructSignatures.length === 0 && t.stringIndexInfo && !t.numberIndexInfo; } return false; } // Transform an indexed access to a simpler form, if possible. Return the simpler form, or return // undefined if no transformation is possible. function getTransformedIndexedAccessType(type) { var objectType = type.objectType; // Given an indexed access type T[K], if T is an intersection containing one or more generic types and one or // more object types with only a string index signature, e.g. '(U & V & { [x: string]: D })[K]', return a // transformed type of the form '(U & V)[K] | D'. This allows us to properly reason about higher order indexed // access types with default property values as expressed by D. if (objectType.flags & 262144 /* Intersection */ && isGenericObjectType(objectType) && ts.some(objectType.types, isStringIndexOnlyType)) { var regularTypes = []; var stringIndexTypes = []; for (var _i = 0, _a = objectType.types; _i < _a.length; _i++) { var t = _a[_i]; if (isStringIndexOnlyType(t)) { stringIndexTypes.push(getIndexTypeOfType(t, 0 /* String */)); } else { regularTypes.push(t); } } return getUnionType([ getIndexedAccessType(getIntersectionType(regularTypes), type.indexType), getIntersectionType(stringIndexTypes) ]); } // If the object type is a mapped type { [P in K]: E }, where K is generic, instantiate E using a mapper // that substitutes the index type for P. For example, for an index access { [P in K]: Box }[X], we // construct the type Box. if (isGenericMappedType(objectType)) { var mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [type.indexType]); var objectTypeMapper = objectType.mapper; var templateMapper = objectTypeMapper ? combineTypeMappers(objectTypeMapper, mapper) : mapper; return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper); } return undefined; } function getIndexedAccessType(objectType, indexType, accessNode) { // If the index type is generic, or if the object type is generic and doesn't originate in an expression, // we are performing a higher-order index access where we cannot meaningfully access the properties of the // object type. Note that for a generic T and a non-generic K, we eagerly resolve T[K] if it originates in // an expression. This is to preserve backwards compatibility. For example, an element access 'this["foo"]' // has always been resolved eagerly using the constraint type of 'this' at the given location. if (isGenericIndexType(indexType) || !(accessNode && accessNode.kind === 181 /* ElementAccessExpression */) && isGenericObjectType(objectType)) { if (objectType.flags & 1 /* Any */) { return objectType; } // Defer the operation by creating an indexed access type. var id = objectType.id + "," + indexType.id; var type = indexedAccessTypes.get(id); if (!type) { indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType)); } return type; } // In the following we resolve T[K] to the type of the property in T selected by K. // We treat boolean as different from other unions to improve errors; // skipping straight to getPropertyTypeForIndexType gives errors with 'boolean' instead of 'true'. var apparentObjectType = getApparentType(objectType); if (indexType.flags & 131072 /* Union */ && !(indexType.flags & 8 /* Boolean */)) { var propTypes = []; for (var _i = 0, _a = indexType.types; _i < _a.length; _i++) { var t = _a[_i]; var propType = getPropertyTypeForIndexType(apparentObjectType, t, accessNode, /*cacheSymbol*/ false); if (propType === unknownType) { return unknownType; } propTypes.push(propType); } return getUnionType(propTypes); } return getPropertyTypeForIndexType(apparentObjectType, indexType, accessNode, /*cacheSymbol*/ true); } function getTypeFromIndexedAccessTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node); } return links.resolvedType; } function getTypeFromMappedTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { var type = createObjectType(32 /* Mapped */, node.symbol); type.declaration = node; type.aliasSymbol = getAliasSymbolForTypeNode(node); type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node); links.resolvedType = type; // Eagerly resolve the constraint type which forces an error if the constraint type circularly // references itself through one or more type aliases. getConstraintTypeFromMappedType(type); } return links.resolvedType; } function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { // Deferred resolution of members is handled by resolveObjectTypeMembers var aliasSymbol = getAliasSymbolForTypeNode(node); if (getMembersOfSymbol(node.symbol).size === 0 && !aliasSymbol) { links.resolvedType = emptyTypeLiteralType; } else { var type = createObjectType(16 /* Anonymous */, node.symbol); type.aliasSymbol = aliasSymbol; type.aliasTypeArguments = getAliasTypeArgumentsForTypeNode(node); if (ts.isJSDocTypeLiteral(node) && node.isArrayType) { type = createArrayType(type); } links.resolvedType = type; } } return links.resolvedType; } function getAliasSymbolForTypeNode(node) { return node.parent.kind === 232 /* TypeAliasDeclaration */ ? getSymbolOfNode(node.parent) : undefined; } function getAliasTypeArgumentsForTypeNode(node) { var symbol = getAliasSymbolForTypeNode(node); return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined; } /** * Since the source of spread types are object literals, which are not binary, * this function should be called in a left folding style, with left = previous result of getSpreadType * and right = the new element to be spread. */ function getSpreadType(left, right, symbol, propagatedFlags) { if (left.flags & 1 /* Any */ || right.flags & 1 /* Any */) { return anyType; } if (left.flags & 16384 /* Never */) { return right; } if (right.flags & 16384 /* Never */) { return left; } if (left.flags & 131072 /* Union */) { return mapType(left, function (t) { return getSpreadType(t, right, symbol, propagatedFlags); }); } if (right.flags & 131072 /* Union */) { return mapType(right, function (t) { return getSpreadType(left, t, symbol, propagatedFlags); }); } if (right.flags & 33554432 /* NonPrimitive */) { return nonPrimitiveType; } if (right.flags & (136 /* BooleanLike */ | 84 /* NumberLike */ | 524322 /* StringLike */ | 272 /* EnumLike */)) { return left; } var members = ts.createSymbolTable(); var skippedPrivateMembers = ts.createUnderscoreEscapedMap(); var stringIndexInfo; var numberIndexInfo; if (left === emptyObjectType) { // for the first spread element, left === emptyObjectType, so take the right's string indexer stringIndexInfo = getIndexInfoOfType(right, 0 /* String */); numberIndexInfo = getIndexInfoOfType(right, 1 /* Number */); } else { stringIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 0 /* String */), getIndexInfoOfType(right, 0 /* String */)); numberIndexInfo = unionSpreadIndexInfos(getIndexInfoOfType(left, 1 /* Number */), getIndexInfoOfType(right, 1 /* Number */)); } for (var _i = 0, _a = getPropertiesOfType(right); _i < _a.length; _i++) { var rightProp = _a[_i]; // we approximate own properties as non-methods plus methods that are inside the object literal var isSetterWithoutGetter = rightProp.flags & 65536 /* SetAccessor */ && !(rightProp.flags & 32768 /* GetAccessor */); if (ts.getDeclarationModifierFlagsFromSymbol(rightProp) & (8 /* Private */ | 16 /* Protected */)) { skippedPrivateMembers.set(rightProp.escapedName, true); } else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) { members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp)); } } for (var _b = 0, _c = getPropertiesOfType(left); _b < _c.length; _b++) { var leftProp = _c[_b]; if (leftProp.flags & 65536 /* SetAccessor */ && !(leftProp.flags & 32768 /* GetAccessor */) || skippedPrivateMembers.has(leftProp.escapedName) || isClassMethod(leftProp)) { continue; } if (members.has(leftProp.escapedName)) { var rightProp = members.get(leftProp.escapedName); var rightType = getTypeOfSymbol(rightProp); if (rightProp.flags & 16777216 /* Optional */) { var declarations = ts.concatenate(leftProp.declarations, rightProp.declarations); var flags = 4 /* Property */ | (leftProp.flags & 16777216 /* Optional */); var result = createSymbol(flags, leftProp.escapedName); result.type = getUnionType([getTypeOfSymbol(leftProp), getTypeWithFacts(rightType, 131072 /* NEUndefined */)]); result.leftSpread = leftProp; result.rightSpread = rightProp; result.declarations = declarations; members.set(leftProp.escapedName, result); } } else { members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp)); } } var spread = createAnonymousType(symbol, members, ts.emptyArray, ts.emptyArray, getNonReadonlyIndexSignature(stringIndexInfo), getNonReadonlyIndexSignature(numberIndexInfo)); spread.flags |= propagatedFlags; spread.flags |= 2097152 /* FreshLiteral */ | 8388608 /* ContainsObjectLiteral */; spread.objectFlags |= (128 /* ObjectLiteral */ | 1024 /* ContainsSpread */); return spread; } function getNonReadonlySymbol(prop) { if (!isReadonlySymbol(prop)) { return prop; } var flags = 4 /* Property */ | (prop.flags & 16777216 /* Optional */); var result = createSymbol(flags, prop.escapedName); result.type = getTypeOfSymbol(prop); result.declarations = prop.declarations; result.syntheticOrigin = prop; return result; } function getNonReadonlyIndexSignature(index) { if (index && index.isReadonly) { return createIndexInfo(index.type, /*isReadonly*/ false, index.declaration); } return index; } function isClassMethod(prop) { return prop.flags & 8192 /* Method */ && ts.find(prop.declarations, function (decl) { return ts.isClassLike(decl.parent); }); } function createLiteralType(flags, value, symbol) { var type = createType(flags); type.symbol = symbol; type.value = value; return type; } function getFreshTypeOfLiteralType(type) { if (type.flags & 96 /* StringOrNumberLiteral */ && !(type.flags & 2097152 /* FreshLiteral */)) { if (!type.freshType) { var freshType = createLiteralType(type.flags | 2097152 /* FreshLiteral */, type.value, type.symbol); freshType.regularType = type; type.freshType = freshType; } return type.freshType; } return type; } function getRegularTypeOfLiteralType(type) { return type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 2097152 /* FreshLiteral */ ? type.regularType : type; } function getLiteralType(value, enumId, symbol) { // We store all literal types in a single map with keys of the form '#NNN' and '@SSS', // where NNN is the text representation of a numeric literal and SSS are the characters // of a string literal. For literal enum members we use 'EEE#NNN' and 'EEE@SSS', where // EEE is a unique id for the containing enum type. var qualifier = typeof value === "number" ? "#" : "@"; var key = enumId ? enumId + qualifier + value : qualifier + value; var type = literalTypes.get(key); if (!type) { var flags = (typeof value === "number" ? 64 /* NumberLiteral */ : 32 /* StringLiteral */) | (enumId ? 256 /* EnumLiteral */ : 0); literalTypes.set(key, type = createLiteralType(flags, value, symbol)); } return type; } function getTypeFromLiteralTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getRegularTypeOfLiteralType(checkExpression(node.literal)); } return links.resolvedType; } function createUniqueESSymbolType(symbol) { var type = createType(1024 /* UniqueESSymbol */); type.symbol = symbol; return type; } function getESSymbolLikeTypeForNode(node) { if (ts.isValidESSymbolDeclaration(node)) { var symbol = getSymbolOfNode(node); var links = getSymbolLinks(symbol); return links.type || (links.type = createUniqueESSymbolType(symbol)); } return esSymbolType; } function getThisType(node) { var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); var parent = container && container.parent; if (parent && (ts.isClassLike(parent) || parent.kind === 231 /* InterfaceDeclaration */)) { if (!ts.hasModifier(container, 32 /* Static */) && (container.kind !== 153 /* Constructor */ || ts.isNodeDescendantOf(node, container.body))) { return getDeclaredTypeOfClassOrInterface(getSymbolOfNode(parent)).thisType; } } error(node, ts.Diagnostics.A_this_type_is_available_only_in_a_non_static_member_of_a_class_or_interface); return unknownType; } function getTypeFromThisTypeNode(node) { var links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getThisType(node); } return links.resolvedType; } function getTypeFromTypeNode(node) { switch (node.kind) { case 119 /* AnyKeyword */: case 272 /* JSDocAllType */: case 273 /* JSDocUnknownType */: return anyType; case 136 /* StringKeyword */: return stringType; case 133 /* NumberKeyword */: return numberType; case 122 /* BooleanKeyword */: return booleanType; case 137 /* SymbolKeyword */: return esSymbolType; case 105 /* VoidKeyword */: return voidType; case 139 /* UndefinedKeyword */: return undefinedType; case 95 /* NullKeyword */: return nullType; case 130 /* NeverKeyword */: return neverType; case 134 /* ObjectKeyword */: return node.flags & 65536 /* JavaScriptFile */ ? anyType : nonPrimitiveType; case 170 /* ThisType */: case 99 /* ThisKeyword */: return getTypeFromThisTypeNode(node); case 174 /* LiteralType */: return getTypeFromLiteralTypeNode(node); case 160 /* TypeReference */: return getTypeFromTypeReference(node); case 159 /* TypePredicate */: return booleanType; case 202 /* ExpressionWithTypeArguments */: return getTypeFromTypeReference(node); case 163 /* TypeQuery */: return getTypeFromTypeQueryNode(node); case 165 /* ArrayType */: return getTypeFromArrayTypeNode(node); case 166 /* TupleType */: return getTypeFromTupleTypeNode(node); case 167 /* UnionType */: return getTypeFromUnionTypeNode(node); case 168 /* IntersectionType */: return getTypeFromIntersectionTypeNode(node); case 274 /* JSDocNullableType */: return getTypeFromJSDocNullableTypeNode(node); case 169 /* ParenthesizedType */: case 275 /* JSDocNonNullableType */: case 276 /* JSDocOptionalType */: case 271 /* JSDocTypeExpression */: return getTypeFromTypeNode(node.type); case 278 /* JSDocVariadicType */: return getTypeFromJSDocVariadicType(node); case 161 /* FunctionType */: case 162 /* ConstructorType */: case 164 /* TypeLiteral */: case 280 /* JSDocTypeLiteral */: case 277 /* JSDocFunctionType */: return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); case 171 /* TypeOperator */: return getTypeFromTypeOperatorNode(node); case 172 /* IndexedAccessType */: return getTypeFromIndexedAccessTypeNode(node); case 173 /* MappedType */: return getTypeFromMappedTypeNode(node); // This function assumes that an identifier or qualified name is a type expression // Callers should first ensure this by calling isTypeNode case 71 /* Identifier */: case 144 /* QualifiedName */: var symbol = getSymbolAtLocation(node); return symbol && getDeclaredTypeOfSymbol(symbol); default: return unknownType; } } function instantiateList(items, mapper, instantiator) { if (items && items.length) { var result = []; for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { var v = items_1[_i]; result.push(instantiator(v, mapper)); } return result; } return items; } function instantiateTypes(types, mapper) { return instantiateList(types, mapper, instantiateType); } function instantiateSignatures(signatures, mapper) { return instantiateList(signatures, mapper, instantiateSignature); } function makeUnaryTypeMapper(source, target) { return function (t) { return t === source ? target : t; }; } function makeBinaryTypeMapper(source1, target1, source2, target2) { return function (t) { return t === source1 ? target1 : t === source2 ? target2 : t; }; } function makeArrayTypeMapper(sources, targets) { return function (t) { for (var i = 0; i < sources.length; i++) { if (t === sources[i]) { return targets ? targets[i] : anyType; } } return t; }; } function createTypeMapper(sources, targets) { ts.Debug.assert(targets === undefined || sources.length === targets.length); return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : makeArrayTypeMapper(sources, targets); } function createTypeEraser(sources) { return createTypeMapper(sources, /*targets*/ undefined); } /** * Maps forward-references to later types parameters to the empty object type. * This is used during inference when instantiating type parameter defaults. */ function createBackreferenceMapper(typeParameters, index) { return function (t) { return ts.indexOf(typeParameters, t) >= index ? emptyObjectType : t; }; } function isInferenceContext(mapper) { return !!mapper.signature; } function cloneTypeMapper(mapper) { return mapper && isInferenceContext(mapper) ? createInferenceContext(mapper.signature, mapper.flags | 2 /* NoDefault */, mapper.compareTypes, mapper.inferences) : mapper; } function combineTypeMappers(mapper1, mapper2) { return function (t) { return instantiateType(mapper1(t), mapper2); }; } function createReplacementMapper(source, target, baseMapper) { return function (t) { return t === source ? target : baseMapper(t); }; } function cloneTypeParameter(typeParameter) { var result = createType(32768 /* TypeParameter */); result.symbol = typeParameter.symbol; result.target = typeParameter; return result; } function cloneTypePredicate(predicate, mapper) { if (ts.isIdentifierTypePredicate(predicate)) { return { kind: 1 /* Identifier */, parameterName: predicate.parameterName, parameterIndex: predicate.parameterIndex, type: instantiateType(predicate.type, mapper) }; } else { return { kind: 0 /* This */, type: instantiateType(predicate.type, mapper) }; } } function instantiateSignature(signature, mapper, eraseTypeParameters) { var freshTypeParameters; var freshTypePredicate; if (signature.typeParameters && !eraseTypeParameters) { // First create a fresh set of type parameters, then include a mapping from the old to the // new type parameters in the mapper function. Finally store this mapper in the new type // parameters such that we can use it when instantiating constraints. freshTypeParameters = ts.map(signature.typeParameters, cloneTypeParameter); mapper = combineTypeMappers(createTypeMapper(signature.typeParameters, freshTypeParameters), mapper); for (var _i = 0, freshTypeParameters_1 = freshTypeParameters; _i < freshTypeParameters_1.length; _i++) { var tp = freshTypeParameters_1[_i]; tp.mapper = mapper; } } if (signature.typePredicate) { freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper); } var result = createSignature(signature.declaration, freshTypeParameters, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), /*resolvedReturnType*/ undefined, freshTypePredicate, signature.minArgumentCount, signature.hasRestParameter, signature.hasLiteralTypes); result.target = signature; result.mapper = mapper; return result; } function instantiateSymbol(symbol, mapper) { if (ts.getCheckFlags(symbol) & 1 /* Instantiated */) { var links = getSymbolLinks(symbol); // If symbol being instantiated is itself a instantiation, fetch the original target and combine the // type mappers. This ensures that original type identities are properly preserved and that aliases // always reference a non-aliases. symbol = links.target; mapper = combineTypeMappers(links.mapper, mapper); } // Keep the flags from the symbol we're instantiating. Mark that is instantiated, and // also transient so that we can just store data on it directly. var result = createSymbol(symbol.flags, symbol.escapedName, 1 /* Instantiated */); result.declarations = symbol.declarations; result.parent = symbol.parent; result.target = symbol; result.mapper = mapper; if (symbol.valueDeclaration) { result.valueDeclaration = symbol.valueDeclaration; } if (symbol.isRestParameter) { result.isRestParameter = symbol.isRestParameter; } return result; } function getAnonymousTypeInstantiation(type, mapper) { var target = type.objectFlags & 64 /* Instantiated */ ? type.target : type; var symbol = target.symbol; var links = getSymbolLinks(symbol); var typeParameters = links.typeParameters; if (!typeParameters) { // The first time an anonymous type is instantiated we compute and store a list of the type // parameters that are in scope (and therefore potentially referenced). For type literals that // aren't the right hand side of a generic type alias declaration we optimize by reducing the // set of type parameters to those that are possibly referenced in the literal. var declaration_1 = symbol.declarations[0]; var outerTypeParameters = getOuterTypeParameters(declaration_1, /*includeThisTypes*/ true) || ts.emptyArray; typeParameters = symbol.flags & 2048 /* TypeLiteral */ && !target.aliasTypeArguments ? ts.filter(outerTypeParameters, function (tp) { return isTypeParameterPossiblyReferenced(tp, declaration_1); }) : outerTypeParameters; links.typeParameters = typeParameters; if (typeParameters.length) { links.instantiations = ts.createMap(); links.instantiations.set(getTypeListId(typeParameters), target); } } if (typeParameters.length) { // We are instantiating an anonymous type that has one or more type parameters in scope. Apply the // mapper to the type parameters to produce the effective list of type arguments, and compute the // instantiation cache key from the type IDs of the type arguments. var combinedMapper = type.objectFlags & 64 /* Instantiated */ ? combineTypeMappers(type.mapper, mapper) : mapper; var typeArguments = ts.map(typeParameters, combinedMapper); var id = getTypeListId(typeArguments); var result = links.instantiations.get(id); if (!result) { var newMapper = createTypeMapper(typeParameters, typeArguments); result = target.objectFlags & 32 /* Mapped */ ? instantiateMappedType(target, newMapper) : instantiateAnonymousType(target, newMapper); links.instantiations.set(id, result); } return result; } return type; } function isTypeParameterPossiblyReferenced(tp, node) { // If the type parameter doesn't have exactly one declaration, if there are invening statement blocks // between the node and the type parameter declaration, if the node contains actual references to the // type parameter, or if the node contains type queries, we consider the type parameter possibly referenced. if (tp.symbol && tp.symbol.declarations && tp.symbol.declarations.length === 1) { var container_1 = tp.symbol.declarations[0].parent; if (ts.findAncestor(node, function (n) { return n.kind === 208 /* Block */ ? "quit" : n === container_1; })) { return ts.forEachChild(node, containsReference); } } return true; function containsReference(node) { switch (node.kind) { case 170 /* ThisType */: return tp.isThisType; case 71 /* Identifier */: return !tp.isThisType && ts.isPartOfTypeNode(node) && getTypeFromTypeNode(node) === tp; case 163 /* TypeQuery */: return true; } return ts.forEachChild(node, containsReference); } } function instantiateMappedType(type, mapper) { // Check if we have a homomorphic mapped type, i.e. a type of the form { [P in keyof T]: X } for some // type variable T. If so, the mapped type is distributive over a union type and when T is instantiated // to a union type A | B, we produce { [P in keyof A]: X } | { [P in keyof B]: X }. Furthermore, for // homomorphic mapped types we leave primitive types alone. For example, when T is instantiated to a // union type A | undefined, we produce { [P in keyof A]: X } | undefined. var constraintType = getConstraintTypeFromMappedType(type); if (constraintType.flags & 524288 /* Index */) { var typeVariable_1 = constraintType.type; if (typeVariable_1.flags & 32768 /* TypeParameter */) { var mappedTypeVariable = instantiateType(typeVariable_1, mapper); if (typeVariable_1 !== mappedTypeVariable) { return mapType(mappedTypeVariable, function (t) { if (isMappableType(t)) { return instantiateAnonymousType(type, createReplacementMapper(typeVariable_1, t, mapper)); } return t; }); } } } return instantiateAnonymousType(type, mapper); } function isMappableType(type) { return type.flags & (1 /* Any */ | 32768 /* TypeParameter */ | 65536 /* Object */ | 262144 /* Intersection */ | 1048576 /* IndexedAccess */); } function instantiateAnonymousType(type, mapper) { var result = createObjectType(type.objectFlags | 64 /* Instantiated */, type.symbol); if (type.objectFlags & 32 /* Mapped */) { result.declaration = type.declaration; } result.target = type; result.mapper = mapper; result.aliasSymbol = type.aliasSymbol; result.aliasTypeArguments = instantiateTypes(type.aliasTypeArguments, mapper); return result; } function instantiateType(type, mapper) { if (type && mapper !== identityMapper) { if (type.flags & 32768 /* TypeParameter */) { return mapper(type); } if (type.flags & 65536 /* Object */) { if (type.objectFlags & 16 /* Anonymous */) { // If the anonymous type originates in a declaration of a function, method, class, or // interface, in an object type literal, or in an object literal expression, we may need // to instantiate the type because it might reference a type parameter. return type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 32 /* Class */ | 2048 /* TypeLiteral */ | 4096 /* ObjectLiteral */) && type.symbol.declarations ? getAnonymousTypeInstantiation(type, mapper) : type; } if (type.objectFlags & 32 /* Mapped */) { return getAnonymousTypeInstantiation(type, mapper); } if (type.objectFlags & 4 /* Reference */) { return createTypeReference(type.target, instantiateTypes(type.typeArguments, mapper)); } } if (type.flags & 131072 /* Union */ && !(type.flags & 16382 /* Primitive */)) { return getUnionType(instantiateTypes(type.types, mapper), /*subtypeReduction*/ false, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } if (type.flags & 262144 /* Intersection */) { return getIntersectionType(instantiateTypes(type.types, mapper), type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper)); } if (type.flags & 524288 /* Index */) { return getIndexType(instantiateType(type.type, mapper)); } if (type.flags & 1048576 /* IndexedAccess */) { return getIndexedAccessType(instantiateType(type.objectType, mapper), instantiateType(type.indexType, mapper)); } } return type; } function instantiateIndexInfo(info, mapper) { return info && createIndexInfo(instantiateType(info.type, mapper), info.isReadonly, info.declaration); } // Returns true if the given expression contains (at any level of nesting) a function or arrow expression // that is subject to contextual typing. function isContextSensitive(node) { ts.Debug.assert(node.kind !== 152 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); switch (node.kind) { case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: return isContextSensitiveFunctionLikeDeclaration(node); case 179 /* ObjectLiteralExpression */: return ts.forEach(node.properties, isContextSensitive); case 178 /* ArrayLiteralExpression */: return ts.forEach(node.elements, isContextSensitive); case 196 /* ConditionalExpression */: return isContextSensitive(node.whenTrue) || isContextSensitive(node.whenFalse); case 195 /* BinaryExpression */: return node.operatorToken.kind === 54 /* BarBarToken */ && (isContextSensitive(node.left) || isContextSensitive(node.right)); case 265 /* PropertyAssignment */: return isContextSensitive(node.initializer); case 186 /* ParenthesizedExpression */: return isContextSensitive(node.expression); case 258 /* JsxAttributes */: return ts.forEach(node.properties, isContextSensitive); case 257 /* JsxAttribute */: // If there is no initializer, JSX attribute has a boolean value of true which is not context sensitive. return node.initializer && isContextSensitive(node.initializer); case 260 /* JsxExpression */: // It is possible to that node.expression is undefined (e.g
) return node.expression && isContextSensitive(node.expression); } return false; } function isContextSensitiveFunctionLikeDeclaration(node) { // Functions with type parameters are not context sensitive. if (node.typeParameters) { return false; } // Functions with any parameters that lack type annotations are context sensitive. if (ts.forEach(node.parameters, function (p) { return !ts.getEffectiveTypeAnnotationNode(p); })) { return true; } if (node.kind !== 188 /* ArrowFunction */) { // If the first parameter is not an explicit 'this' parameter, then the function has // an implicit 'this' parameter which is subject to contextual typing. var parameter = ts.firstOrUndefined(node.parameters); if (!(parameter && ts.parameterIsThisKeyword(parameter))) { return true; } } // TODO(anhans): A block should be context-sensitive if it has a context-sensitive return value. return node.body.kind === 208 /* Block */ ? false : isContextSensitive(node.body); } function isContextSensitiveFunctionOrObjectLiteralMethod(func) { return (isFunctionExpressionOrArrowFunction(func) || ts.isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func); } function getTypeWithoutSignatures(type) { if (type.flags & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(type); if (resolved.constructSignatures.length) { var result = createObjectType(16 /* Anonymous */, type.symbol); result.members = resolved.members; result.properties = resolved.properties; result.callSignatures = ts.emptyArray; result.constructSignatures = ts.emptyArray; return result; } } else if (type.flags & 262144 /* Intersection */) { return getIntersectionType(ts.map(type.types, getTypeWithoutSignatures)); } return type; } // TYPE CHECKING function isTypeIdenticalTo(source, target) { return isTypeRelatedTo(source, target, identityRelation); } function compareTypesIdentical(source, target) { return isTypeRelatedTo(source, target, identityRelation) ? -1 /* True */ : 0 /* False */; } function compareTypesAssignable(source, target) { return isTypeRelatedTo(source, target, assignableRelation) ? -1 /* True */ : 0 /* False */; } function isTypeSubtypeOf(source, target) { return isTypeRelatedTo(source, target, subtypeRelation); } function isTypeAssignableTo(source, target) { return isTypeRelatedTo(source, target, assignableRelation); } // An object type S is considered to be derived from an object type T if // S is a union type and every constituent of S is derived from T, // T is a union type and S is derived from at least one constituent of T, or // S is a type variable with a base constraint that is derived from T, // T is one of the global types Object and Function and S is a subtype of T, or // T occurs directly or indirectly in an 'extends' clause of S. // Note that this check ignores type parameters and only considers the // inheritance hierarchy. function isTypeDerivedFrom(source, target) { return source.flags & 131072 /* Union */ ? ts.every(source.types, function (t) { return isTypeDerivedFrom(t, target); }) : target.flags & 131072 /* Union */ ? ts.some(target.types, function (t) { return isTypeDerivedFrom(source, t); }) : source.flags & 1081344 /* TypeVariable */ ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : hasBaseType(source, getTargetType(target)); } /** * This is *not* a bi-directional relationship. * If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'. * * A type S is comparable to a type T if some (but not necessarily all) of the possible values of S are also possible values of T. * It is used to check following cases: * - the types of the left and right sides of equality/inequality operators (`===`, `!==`, `==`, `!=`). * - the types of `case` clause expressions and their respective `switch` expressions. * - the type of an expression in a type assertion with the type being asserted. */ function isTypeComparableTo(source, target) { return isTypeRelatedTo(source, target, comparableRelation); } function areTypesComparable(type1, type2) { return isTypeComparableTo(type1, type2) || isTypeComparableTo(type2, type1); } function checkTypeAssignableTo(source, target, errorNode, headMessage, containingMessageChain) { return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } /** * This is *not* a bi-directional relationship. * If one needs to check both directions for comparability, use a second call to this function or 'isTypeComparableTo'. */ function checkTypeComparableTo(source, target, errorNode, headMessage, containingMessageChain) { return checkTypeRelatedTo(source, target, comparableRelation, errorNode, headMessage, containingMessageChain); } function isSignatureAssignableTo(source, target, ignoreReturnTypes) { return compareSignaturesRelated(source, target, 0 /* None */, ignoreReturnTypes, /*reportErrors*/ false, /*errorReporter*/ undefined, compareTypesAssignable) !== 0 /* False */; } /** * See signatureRelatedTo, compareSignaturesIdentical */ function compareSignaturesRelated(source, target, callbackCheck, ignoreReturnTypes, reportErrors, errorReporter, compareTypes) { // TODO (drosen): De-duplicate code between related functions. if (source === target) { return -1 /* True */; } if (!target.hasRestParameter && source.minArgumentCount > target.parameters.length) { return 0 /* False */; } if (source.typeParameters && source.typeParameters !== target.typeParameters) { target = getCanonicalSignature(target); source = instantiateSignatureInContextOf(source, target, /*contextualMapper*/ undefined, compareTypes); } var kind = target.declaration ? target.declaration.kind : 0 /* Unknown */; var strictVariance = !callbackCheck && strictFunctionTypes && kind !== 152 /* MethodDeclaration */ && kind !== 151 /* MethodSignature */ && kind !== 153 /* Constructor */; var result = -1 /* True */; var sourceThisType = getThisTypeOfSignature(source); if (sourceThisType && sourceThisType !== voidType) { var targetThisType = getThisTypeOfSignature(target); if (targetThisType) { // void sources are assignable to anything. var related = !strictVariance && compareTypes(sourceThisType, targetThisType, /*reportErrors*/ false) || compareTypes(targetThisType, sourceThisType, reportErrors); if (!related) { if (reportErrors) { errorReporter(ts.Diagnostics.The_this_types_of_each_signature_are_incompatible); } return 0 /* False */; } result &= related; } } var sourceMax = getNumNonRestParameters(source); var targetMax = getNumNonRestParameters(target); var checkCount = getNumParametersToCheckForSignatureRelatability(source, sourceMax, target, targetMax); var sourceParams = source.parameters; var targetParams = target.parameters; for (var i = 0; i < checkCount; i++) { var sourceType = i < sourceMax ? getTypeOfParameter(sourceParams[i]) : getRestTypeOfSignature(source); var targetType = i < targetMax ? getTypeOfParameter(targetParams[i]) : getRestTypeOfSignature(target); // In order to ensure that any generic type Foo is at least co-variant with respect to T no matter // how Foo uses T, we need to relate parameters bi-variantly (given that parameters are input positions, // they naturally relate only contra-variantly). However, if the source and target parameters both have // function types with a single call signature, we know we are relating two callback parameters. In // that case it is sufficient to only relate the parameters of the signatures co-variantly because, // similar to return values, callback parameters are output positions. This means that a Promise, // where T is used only in callback parameter positions, will be co-variant (as opposed to bi-variant) // with respect to T. var sourceSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(sourceType)); var targetSig = callbackCheck ? undefined : getSingleCallSignature(getNonNullableType(targetType)); var callbacks = sourceSig && targetSig && !sourceSig.typePredicate && !targetSig.typePredicate && (getFalsyFlags(sourceType) & 12288 /* Nullable */) === (getFalsyFlags(targetType) & 12288 /* Nullable */); var related = callbacks ? compareSignaturesRelated(targetSig, sourceSig, strictVariance ? 2 /* Strict */ : 1 /* Bivariant */, /*ignoreReturnTypes*/ false, reportErrors, errorReporter, compareTypes) : !callbackCheck && !strictVariance && compareTypes(sourceType, targetType, /*reportErrors*/ false) || compareTypes(targetType, sourceType, reportErrors); if (!related) { if (reportErrors) { errorReporter(ts.Diagnostics.Types_of_parameters_0_and_1_are_incompatible, ts.symbolName(sourceParams[i < sourceMax ? i : sourceMax]), ts.symbolName(targetParams[i < targetMax ? i : targetMax])); } return 0 /* False */; } result &= related; } if (!ignoreReturnTypes) { var targetReturnType = getReturnTypeOfSignature(target); if (targetReturnType === voidType) { return result; } var sourceReturnType = getReturnTypeOfSignature(source); // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions if (target.typePredicate) { if (source.typePredicate) { result &= compareTypePredicateRelatedTo(source.typePredicate, target.typePredicate, source.declaration, target.declaration, reportErrors, errorReporter, compareTypes); } else if (ts.isIdentifierTypePredicate(target.typePredicate)) { if (reportErrors) { errorReporter(ts.Diagnostics.Signature_0_must_be_a_type_predicate, signatureToString(source)); } return 0 /* False */; } } else { // When relating callback signatures, we still need to relate return types bi-variantly as otherwise // the containing type wouldn't be co-variant. For example, interface Foo { add(cb: () => T): void } // wouldn't be co-variant for T without this rule. result &= callbackCheck === 1 /* Bivariant */ && compareTypes(targetReturnType, sourceReturnType, /*reportErrors*/ false) || compareTypes(sourceReturnType, targetReturnType, reportErrors); } } return result; } function compareTypePredicateRelatedTo(source, target, sourceDeclaration, targetDeclaration, reportErrors, errorReporter, compareTypes) { if (source.kind !== target.kind) { if (reportErrors) { errorReporter(ts.Diagnostics.A_this_based_type_guard_is_not_compatible_with_a_parameter_based_type_guard); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0 /* False */; } if (source.kind === 1 /* Identifier */) { var sourcePredicate = source; var targetPredicate = target; var sourceIndex = sourcePredicate.parameterIndex - (ts.getThisParameter(sourceDeclaration) ? 1 : 0); var targetIndex = targetPredicate.parameterIndex - (ts.getThisParameter(targetDeclaration) ? 1 : 0); if (sourceIndex !== targetIndex) { if (reportErrors) { errorReporter(ts.Diagnostics.Parameter_0_is_not_in_the_same_position_as_parameter_1, sourcePredicate.parameterName, targetPredicate.parameterName); errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return 0 /* False */; } } var related = compareTypes(source.type, target.type, reportErrors); if (related === 0 /* False */ && reportErrors) { errorReporter(ts.Diagnostics.Type_predicate_0_is_not_assignable_to_1, typePredicateToString(source), typePredicateToString(target)); } return related; } function isImplementationCompatibleWithOverload(implementation, overload) { var erasedSource = getErasedSignature(implementation); var erasedTarget = getErasedSignature(overload); // First see if the return types are compatible in either direction. var sourceReturnType = getReturnTypeOfSignature(erasedSource); var targetReturnType = getReturnTypeOfSignature(erasedTarget); if (targetReturnType === voidType || isTypeRelatedTo(targetReturnType, sourceReturnType, assignableRelation) || isTypeRelatedTo(sourceReturnType, targetReturnType, assignableRelation)) { return isSignatureAssignableTo(erasedSource, erasedTarget, /*ignoreReturnTypes*/ true); } return false; } function getNumNonRestParameters(signature) { var numParams = signature.parameters.length; return signature.hasRestParameter ? numParams - 1 : numParams; } function getNumParametersToCheckForSignatureRelatability(source, sourceNonRestParamCount, target, targetNonRestParamCount) { if (source.hasRestParameter === target.hasRestParameter) { if (source.hasRestParameter) { // If both have rest parameters, get the max and add 1 to // compensate for the rest parameter. return Math.max(sourceNonRestParamCount, targetNonRestParamCount) + 1; } else { return Math.min(sourceNonRestParamCount, targetNonRestParamCount); } } else { // Return the count for whichever signature doesn't have rest parameters. return source.hasRestParameter ? targetNonRestParamCount : sourceNonRestParamCount; } } function isEmptyResolvedType(t) { return t.properties.length === 0 && t.callSignatures.length === 0 && t.constructSignatures.length === 0 && !t.stringIndexInfo && !t.numberIndexInfo; } function isEmptyObjectType(type) { return type.flags & 65536 /* Object */ ? isEmptyResolvedType(resolveStructuredTypeMembers(type)) : type.flags & 33554432 /* NonPrimitive */ ? true : type.flags & 131072 /* Union */ ? ts.forEach(type.types, isEmptyObjectType) : type.flags & 262144 /* Intersection */ ? !ts.forEach(type.types, function (t) { return !isEmptyObjectType(t); }) : false; } function isEnumTypeRelatedTo(sourceSymbol, targetSymbol, errorReporter) { if (sourceSymbol === targetSymbol) { return true; } var id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol); var relation = enumRelation.get(id); if (relation !== undefined) { return relation; } if (sourceSymbol.escapedName !== targetSymbol.escapedName || !(sourceSymbol.flags & 256 /* RegularEnum */) || !(targetSymbol.flags & 256 /* RegularEnum */)) { enumRelation.set(id, false); return false; } var targetEnumType = getTypeOfSymbol(targetSymbol); for (var _i = 0, _a = getPropertiesOfType(getTypeOfSymbol(sourceSymbol)); _i < _a.length; _i++) { var property = _a[_i]; if (property.flags & 8 /* EnumMember */) { var targetProperty = getPropertyOfType(targetEnumType, property.escapedName); if (!targetProperty || !(targetProperty.flags & 8 /* EnumMember */)) { if (errorReporter) { errorReporter(ts.Diagnostics.Property_0_is_missing_in_type_1, ts.symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */)); } enumRelation.set(id, false); return false; } } } enumRelation.set(id, true); return true; } function isSimpleTypeRelatedTo(source, target, relation, errorReporter) { var s = source.flags; var t = target.flags; if (t & 1 /* Any */ || s & 16384 /* Never */) return true; if (t & 16384 /* Never */) return false; if (s & 524322 /* StringLike */ && t & 2 /* String */) return true; if (s & 32 /* StringLiteral */ && s & 256 /* EnumLiteral */ && t & 32 /* StringLiteral */ && !(t & 256 /* EnumLiteral */) && source.value === target.value) return true; if (s & 84 /* NumberLike */ && t & 4 /* Number */) return true; if (s & 64 /* NumberLiteral */ && s & 256 /* EnumLiteral */ && t & 64 /* NumberLiteral */ && !(t & 256 /* EnumLiteral */) && source.value === target.value) return true; if (s & 136 /* BooleanLike */ && t & 8 /* Boolean */) return true; if (s & 1536 /* ESSymbolLike */ && t & 512 /* ESSymbol */) return true; if (s & 16 /* Enum */ && t & 16 /* Enum */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true; if (s & 256 /* EnumLiteral */ && t & 256 /* EnumLiteral */) { if (s & 131072 /* Union */ && t & 131072 /* Union */ && isEnumTypeRelatedTo(source.symbol, target.symbol, errorReporter)) return true; if (s & 224 /* Literal */ && t & 224 /* Literal */ && source.value === target.value && isEnumTypeRelatedTo(getParentOfSymbol(source.symbol), getParentOfSymbol(target.symbol), errorReporter)) return true; } if (s & 4096 /* Undefined */ && (!strictNullChecks || t & (4096 /* Undefined */ | 2048 /* Void */))) return true; if (s & 8192 /* Null */ && (!strictNullChecks || t & 8192 /* Null */)) return true; if (s & 65536 /* Object */ && t & 33554432 /* NonPrimitive */) return true; if (s & 1024 /* UniqueESSymbol */ || t & 1024 /* UniqueESSymbol */) return false; if (relation === assignableRelation || relation === comparableRelation) { if (s & 1 /* Any */) return true; // Type number or any numeric literal type is assignable to any numeric enum type or any // numeric enum literal type. This rule exists for backwards compatibility reasons because // bit-flag enum types sometimes look like literal enum types with numeric literal values. if (s & (4 /* Number */ | 64 /* NumberLiteral */) && !(s & 256 /* EnumLiteral */) && (t & 16 /* Enum */ || t & 64 /* NumberLiteral */ && t & 256 /* EnumLiteral */)) return true; } return false; } function isTypeRelatedTo(source, target, relation) { if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 2097152 /* FreshLiteral */) { source = source.regularType; } if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 2097152 /* FreshLiteral */) { target = target.regularType; } if (source === target || relation === comparableRelation && !(target.flags & 16384 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) || relation !== identityRelation && isSimpleTypeRelatedTo(source, target, relation)) { return true; } if (source.flags & 65536 /* Object */ && target.flags & 65536 /* Object */) { var related = relation.get(getRelationKey(source, target, relation)); if (related !== undefined) { return related === 1 /* Succeeded */; } } if (source.flags & 2064384 /* StructuredOrTypeVariable */ || target.flags & 2064384 /* StructuredOrTypeVariable */) { return checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined); } return false; } /** * Checks if 'source' is related to 'target' (e.g.: is a assignable to). * @param source The left-hand-side of the relation. * @param target The right-hand-side of the relation. * @param relation The relation considered. One of 'identityRelation', 'subtypeRelation', 'assignableRelation', or 'comparableRelation'. * Used as both to determine which checks are performed and as a cache of previously computed results. * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used. * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used. * @param containingMessageChain A chain of errors to prepend any new errors found. */ function checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain) { var errorInfo; var maybeKeys; var sourceStack; var targetStack; var maybeCount = 0; var depth = 0; var expandingFlags = 0 /* None */; var overflow = false; var isIntersectionConstituent = false; ts.Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); var result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage); if (overflow) { error(errorNode, ts.Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); } else if (errorInfo) { if (containingMessageChain) { errorInfo = ts.concatenateDiagnosticMessageChains(containingMessageChain, errorInfo); } diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(errorNode, errorInfo)); } return result !== 0 /* False */; function reportError(message, arg0, arg1, arg2) { ts.Debug.assert(!!errorNode); errorInfo = ts.chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2); } function reportRelationError(message, source, target) { var sourceType = typeToString(source); var targetType = typeToString(target); if (sourceType === targetType) { sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */); targetType = typeToString(target, /*enclosingDeclaration*/ undefined, 256 /* UseFullyQualifiedType */); } if (!message) { if (relation === comparableRelation) { message = ts.Diagnostics.Type_0_is_not_comparable_to_type_1; } else if (sourceType === targetType) { message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; } else { message = ts.Diagnostics.Type_0_is_not_assignable_to_type_1; } } reportError(message, sourceType, targetType); } function tryElaborateErrorsForPrimitivesAndObjects(source, target) { var sourceType = typeToString(source); var targetType = typeToString(target); if ((globalStringType === source && stringType === target) || (globalNumberType === source && numberType === target) || (globalBooleanType === source && booleanType === target) || (getGlobalESSymbolType(/*reportErrors*/ false) === source && esSymbolType === target)) { reportError(ts.Diagnostics._0_is_a_primitive_but_1_is_a_wrapper_object_Prefer_using_0_when_possible, targetType, sourceType); } } function isUnionOrIntersectionTypeWithoutNullableConstituents(type) { if (!(type.flags & 393216 /* UnionOrIntersection */)) { return false; } // at this point we know that this is union or intersection type possibly with nullable constituents. // check if we still will have compound type if we ignore nullable components. var seenNonNullable = false; for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var t = _a[_i]; if (t.flags & 12288 /* Nullable */) { continue; } if (seenNonNullable) { return true; } seenNonNullable = true; } return false; } /** * Compare two types and return * * Ternary.True if they are related with no assumptions, * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related. */ function isRelatedTo(source, target, reportErrors, headMessage) { if (source.flags & 96 /* StringOrNumberLiteral */ && source.flags & 2097152 /* FreshLiteral */) { source = source.regularType; } if (target.flags & 96 /* StringOrNumberLiteral */ && target.flags & 2097152 /* FreshLiteral */) { target = target.regularType; } // both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases if (source === target) return -1 /* True */; if (relation === identityRelation) { return isIdenticalTo(source, target); } if (relation === comparableRelation && !(target.flags & 16384 /* Never */) && isSimpleTypeRelatedTo(target, source, relation) || isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return -1 /* True */; if (isObjectLiteralType(source) && source.flags & 2097152 /* FreshLiteral */) { if (hasExcessProperties(source, target, reportErrors)) { if (reportErrors) { reportRelationError(headMessage, source, target); } return 0 /* False */; } // Above we check for excess properties with respect to the entire target type. When union // and intersection types are further deconstructed on the target side, we don't want to // make the check again (as it might fail for a partial target type). Therefore we obtain // the regular source type and proceed with that. if (isUnionOrIntersectionTypeWithoutNullableConstituents(target)) { source = getRegularTypeOfObjectLiteral(source); } } if (relation !== comparableRelation && !(source.flags & 393216 /* UnionOrIntersection */) && !(target.flags & 131072 /* Union */) && !isIntersectionConstituent && source !== globalObjectType && (getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source)) && isWeakType(target) && !hasCommonProperties(source, target)) { if (reportErrors) { var calls = getSignaturesOfType(source, 0 /* Call */); var constructs = getSignaturesOfType(source, 1 /* Construct */); if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, /*reportErrors*/ false) || constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, /*reportErrors*/ false)) { reportError(ts.Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, typeToString(source), typeToString(target)); } else { reportError(ts.Diagnostics.Type_0_has_no_properties_in_common_with_type_1, typeToString(source), typeToString(target)); } } return 0 /* False */; } var result = 0 /* False */; var saveErrorInfo = errorInfo; var saveIsIntersectionConstituent = isIntersectionConstituent; isIntersectionConstituent = false; // Note that these checks are specifically ordered to produce correct results. In particular, // we need to deconstruct unions before intersections (because unions are always at the top), // and we need to handle "each" relations before "some" relations for the same kind of type. if (source.flags & 131072 /* Union */) { result = relation === comparableRelation ? someTypeRelatedToType(source, target, reportErrors && !(source.flags & 16382 /* Primitive */)) : eachTypeRelatedToType(source, target, reportErrors && !(source.flags & 16382 /* Primitive */)); } else { if (target.flags & 131072 /* Union */) { result = typeRelatedToSomeType(source, target, reportErrors && !(source.flags & 16382 /* Primitive */) && !(target.flags & 16382 /* Primitive */)); } else if (target.flags & 262144 /* Intersection */) { isIntersectionConstituent = true; result = typeRelatedToEachType(source, target, reportErrors); } else if (source.flags & 262144 /* Intersection */) { // Check to see if any constituents of the intersection are immediately related to the target. // // Don't report errors though. Checking whether a constituent is related to the source is not actually // useful and leads to some confusing error messages. Instead it is better to let the below checks // take care of this, or to not elaborate at all. For instance, // // - For an object type (such as 'C = A & B'), users are usually more interested in structural errors. // // - For a union type (such as '(A | B) = (C & D)'), it's better to hold onto the whole intersection // than to report that 'D' is not assignable to 'A' or 'B'. // // - For a primitive type or type parameter (such as 'number = A & B') there is no point in // breaking the intersection apart. result = someTypeRelatedToType(source, target, /*reportErrors*/ false); } if (!result && (source.flags & 2064384 /* StructuredOrTypeVariable */ || target.flags & 2064384 /* StructuredOrTypeVariable */)) { if (result = recursiveTypeRelatedTo(source, target, reportErrors)) { errorInfo = saveErrorInfo; } } } isIntersectionConstituent = saveIsIntersectionConstituent; if (!result && reportErrors) { if (source.flags & 65536 /* Object */ && target.flags & 16382 /* Primitive */) { tryElaborateErrorsForPrimitivesAndObjects(source, target); } else if (source.symbol && source.flags & 65536 /* Object */ && globalObjectType === source) { reportError(ts.Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead); } reportRelationError(headMessage, source, target); } return result; } function isIdenticalTo(source, target) { var result; if (source.flags & 65536 /* Object */ && target.flags & 65536 /* Object */) { return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false); } if (source.flags & 131072 /* Union */ && target.flags & 131072 /* Union */ || source.flags & 262144 /* Intersection */ && target.flags & 262144 /* Intersection */) { if (result = eachTypeRelatedToSomeType(source, target)) { if (result &= eachTypeRelatedToSomeType(target, source)) { return result; } } } return 0 /* False */; } function hasExcessProperties(source, target, reportErrors) { if (maybeTypeOfKind(target, 65536 /* Object */) && !(ts.getObjectFlags(target) & 512 /* ObjectLiteralPatternWithComputedProperties */)) { var isComparingJsxAttributes = !!(source.flags & 67108864 /* JsxAttributes */); if ((relation === assignableRelation || relation === comparableRelation) && (isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))) { return false; } if (target.flags & 131072 /* Union */) { var discriminantType = findMatchingDiscriminantType(source, target); if (discriminantType) { // check excess properties against discriminant type only, not the entire union return hasExcessProperties(source, discriminantType, reportErrors); } } var _loop_5 = function (prop) { if (!isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { if (reportErrors) { // We know *exactly* where things went wrong when comparing the types. // Use this property as the error node as this will be more helpful in // reasoning about what went wrong. ts.Debug.assert(!!errorNode); if (ts.isJsxAttributes(errorNode) || ts.isJsxOpeningLikeElement(errorNode)) { // JsxAttributes has an object-literal flag and undergo same type-assignablity check as normal object-literal. // However, using an object-literal error message will be very confusing to the users so we give different a message. reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(prop), typeToString(target)); } else { // use the property's value declaration if the property is assigned inside the literal itself var objectLiteralDeclaration_1 = source.symbol && ts.firstOrUndefined(source.symbol.declarations); var suggestion = void 0; if (prop.valueDeclaration && ts.findAncestor(prop.valueDeclaration, function (d) { return d === objectLiteralDeclaration_1; })) { var propDeclaration = prop.valueDeclaration; ts.Debug.assertNode(propDeclaration, ts.isObjectLiteralElementLike); errorNode = propDeclaration; if (ts.isIdentifier(propDeclaration.name)) { suggestion = getSuggestionForNonexistentProperty(propDeclaration.name, target); } } if (suggestion !== undefined) { reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_but_0_does_not_exist_in_type_1_Did_you_mean_to_write_2, symbolToString(prop), typeToString(target), suggestion); } else { reportError(ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(prop), typeToString(target)); } } } return { value: true }; } }; for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; var state_2 = _loop_5(prop); if (typeof state_2 === "object") return state_2.value; } } return false; } function eachTypeRelatedToSomeType(source, target) { var result = -1 /* True */; var sourceTypes = source.types; for (var _i = 0, sourceTypes_1 = sourceTypes; _i < sourceTypes_1.length; _i++) { var sourceType = sourceTypes_1[_i]; var related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false); if (!related) { return 0 /* False */; } result &= related; } return result; } function typeRelatedToSomeType(source, target, reportErrors) { var targetTypes = target.types; if (target.flags & 131072 /* Union */ && containsType(targetTypes, source)) { return -1 /* True */; } for (var _i = 0, targetTypes_1 = targetTypes; _i < targetTypes_1.length; _i++) { var type = targetTypes_1[_i]; var related = isRelatedTo(source, type, /*reportErrors*/ false); if (related) { return related; } } if (reportErrors) { var discriminantType = findMatchingDiscriminantType(source, target); isRelatedTo(source, discriminantType || targetTypes[targetTypes.length - 1], /*reportErrors*/ true); } return 0 /* False */; } // Keep this up-to-date with the same logic within `getApparentTypeOfContextualType`, since they should behave similarly function findMatchingDiscriminantType(source, target) { var match; var sourceProperties = getPropertiesOfObjectType(source); if (sourceProperties) { var sourcePropertiesFiltered = findDiscriminantProperties(sourceProperties, target); if (sourcePropertiesFiltered) { for (var _i = 0, sourcePropertiesFiltered_1 = sourcePropertiesFiltered; _i < sourcePropertiesFiltered_1.length; _i++) { var sourceProperty = sourcePropertiesFiltered_1[_i]; var sourceType = getTypeOfSymbol(sourceProperty); for (var _a = 0, _b = target.types; _a < _b.length; _a++) { var type = _b[_a]; var targetType = getTypeOfPropertyOfType(type, sourceProperty.escapedName); if (targetType && isRelatedTo(sourceType, targetType)) { if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine if (match) { return undefined; } match = type; } } } } } return match; } function typeRelatedToEachType(source, target, reportErrors) { var result = -1 /* True */; var targetTypes = target.types; for (var _i = 0, targetTypes_2 = targetTypes; _i < targetTypes_2.length; _i++) { var targetType = targetTypes_2[_i]; var related = isRelatedTo(source, targetType, reportErrors); if (!related) { return 0 /* False */; } result &= related; } return result; } function someTypeRelatedToType(source, target, reportErrors) { var sourceTypes = source.types; if (source.flags & 131072 /* Union */ && containsType(sourceTypes, target)) { return -1 /* True */; } var len = sourceTypes.length; for (var i = 0; i < len; i++) { var related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1); if (related) { return related; } } return 0 /* False */; } function eachTypeRelatedToType(source, target, reportErrors) { var result = -1 /* True */; var sourceTypes = source.types; for (var _i = 0, sourceTypes_2 = sourceTypes; _i < sourceTypes_2.length; _i++) { var sourceType = sourceTypes_2[_i]; var related = isRelatedTo(sourceType, target, reportErrors); if (!related) { return 0 /* False */; } result &= related; } return result; } function typeArgumentsRelatedTo(source, target, variances, reportErrors) { var sources = source.typeArguments || ts.emptyArray; var targets = target.typeArguments || ts.emptyArray; if (sources.length !== targets.length && relation === identityRelation) { return 0 /* False */; } var length = sources.length <= targets.length ? sources.length : targets.length; var result = -1 /* True */; for (var i = 0; i < length; i++) { // When variance information isn't available we default to covariance. This happens // in the process of computing variance information for recursive types and when // comparing 'this' type arguments. var variance = i < variances.length ? variances[i] : 1 /* Covariant */; // We ignore arguments for independent type parameters (because they're never witnessed). if (variance !== 4 /* Independent */) { var s = sources[i]; var t = targets[i]; var related = -1 /* True */; if (variance === 1 /* Covariant */) { related = isRelatedTo(s, t, reportErrors); } else if (variance === 2 /* Contravariant */) { related = isRelatedTo(t, s, reportErrors); } else if (variance === 3 /* Bivariant */) { // In the bivariant case we first compare contravariantly without reporting // errors. Then, if that doesn't succeed, we compare covariantly with error // reporting. Thus, error elaboration will be based on the the covariant check, // which is generally easier to reason about. related = isRelatedTo(t, s, /*reportErrors*/ false); if (!related) { related = isRelatedTo(s, t, reportErrors); } } else { // In the invariant case we first compare covariantly, and only when that // succeeds do we proceed to compare contravariantly. Thus, error elaboration // will typically be based on the covariant check. related = isRelatedTo(s, t, reportErrors); if (related) { related &= isRelatedTo(t, s, reportErrors); } } if (!related) { return 0 /* False */; } result &= related; } } return result; } // Determine if possibly recursive types are related. First, check if the result is already available in the global cache. // Second, check if we have already started a comparison of the given two types in which case we assume the result to be true. // Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion // and issue an error. Otherwise, actually compare the structure of the two types. function recursiveTypeRelatedTo(source, target, reportErrors) { if (overflow) { return 0 /* False */; } var id = getRelationKey(source, target, relation); var related = relation.get(id); if (related !== undefined) { if (reportErrors && related === 2 /* Failed */) { // We are elaborating errors and the cached result is an unreported failure. Record the result as a reported // failure and continue computing the relation such that errors get reported. relation.set(id, 3 /* FailedAndReported */); } else { return related === 1 /* Succeeded */ ? -1 /* True */ : 0 /* False */; } } if (!maybeKeys) { maybeKeys = []; sourceStack = []; targetStack = []; } else { for (var i = 0; i < maybeCount; i++) { // If source and target are already being compared, consider them related with assumptions if (id === maybeKeys[i]) { return 1 /* Maybe */; } } if (depth === 100) { overflow = true; return 0 /* False */; } } var maybeStart = maybeCount; maybeKeys[maybeCount] = id; maybeCount++; sourceStack[depth] = source; targetStack[depth] = target; depth++; var saveExpandingFlags = expandingFlags; if (!(expandingFlags & 1 /* Source */) && isDeeplyNestedType(source, sourceStack, depth)) expandingFlags |= 1 /* Source */; if (!(expandingFlags & 2 /* Target */) && isDeeplyNestedType(target, targetStack, depth)) expandingFlags |= 2 /* Target */; var result = expandingFlags !== 3 /* Both */ ? structuredTypeRelatedTo(source, target, reportErrors) : 1 /* Maybe */; expandingFlags = saveExpandingFlags; depth--; if (result) { if (result === -1 /* True */ || depth === 0) { // If result is definitely true, record all maybe keys as having succeeded for (var i = maybeStart; i < maybeCount; i++) { relation.set(maybeKeys[i], 1 /* Succeeded */); } maybeCount = maybeStart; } } else { // A false result goes straight into global cache (when something is false under // assumptions it will also be false without assumptions) relation.set(id, reportErrors ? 3 /* FailedAndReported */ : 2 /* Failed */); maybeCount = maybeStart; } return result; } function structuredTypeRelatedTo(source, target, reportErrors) { var result; var originalErrorInfo; var saveErrorInfo = errorInfo; if (target.flags & 32768 /* TypeParameter */) { // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P]. if (ts.getObjectFlags(source) & 32 /* Mapped */ && getConstraintTypeFromMappedType(source) === getIndexType(target)) { if (!source.declaration.questionToken) { var templateType = getTemplateTypeFromMappedType(source); var indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source)); if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) { return result; } } } } else if (target.flags & 524288 /* Index */) { // A keyof S is related to a keyof T if T is related to S. if (source.flags & 524288 /* Index */) { if (result = isRelatedTo(target.type, source.type, /*reportErrors*/ false)) { return result; } } // A type S is assignable to keyof T if S is assignable to keyof C, where C is the // constraint of T. var constraint = getConstraintOfType(target.type); if (constraint) { if (result = isRelatedTo(source, getIndexType(constraint), reportErrors)) { return result; } } } else if (target.flags & 1048576 /* IndexedAccess */) { // A type S is related to a type T[K] if S is related to A[K], where K is string-like and // A is the apparent type of S. var constraint = getConstraintOfIndexedAccess(target); if (constraint) { if (result = isRelatedTo(source, constraint, reportErrors)) { errorInfo = saveErrorInfo; return result; } } } else if (isGenericMappedType(target) && !isGenericMappedType(source) && getConstraintTypeFromMappedType(target) === getIndexType(source)) { // A source type T is related to a target type { [P in keyof T]: X } if T[P] is related to X. var indexedAccessType = getIndexedAccessType(source, getTypeParameterFromMappedType(target)); var templateType = getTemplateTypeFromMappedType(target); if (result = isRelatedTo(indexedAccessType, templateType, reportErrors)) { errorInfo = saveErrorInfo; return result; } } if (source.flags & 32768 /* TypeParameter */) { var constraint = getConstraintOfTypeParameter(source); // A type parameter with no constraint is not related to the non-primitive object type. if (constraint || !(target.flags & 33554432 /* NonPrimitive */)) { if (!constraint || constraint.flags & 1 /* Any */) { constraint = emptyObjectType; } // Report constraint errors only if the constraint is not the empty object type var reportConstraintErrors = reportErrors && constraint !== emptyObjectType; if (result = isRelatedTo(constraint, target, reportConstraintErrors)) { errorInfo = saveErrorInfo; return result; } } } else if (source.flags & 1048576 /* IndexedAccess */) { // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and // A is the apparent type of S. var constraint = getConstraintOfIndexedAccess(source); if (constraint) { if (result = isRelatedTo(constraint, target, reportErrors)) { errorInfo = saveErrorInfo; return result; } } else if (target.flags & 1048576 /* IndexedAccess */ && source.indexType === target.indexType) { // if we have indexed access types with identical index types, see if relationship holds for // the two object types. if (result = isRelatedTo(source.objectType, target.objectType, reportErrors)) { errorInfo = saveErrorInfo; return result; } } } else { if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target && !(source.flags & 134217728 /* MarkerType */ || target.flags & 134217728 /* MarkerType */)) { // We have type references to the same generic type, and the type references are not marker // type references (which are intended by be compared structurally). Obtain the variance // information for the type parameters and relate the type arguments accordingly. var variances = getVariances(source.target); if (result = typeArgumentsRelatedTo(source, target, variances, reportErrors)) { return result; } // The type arguments did not relate appropriately, but it may be because we have no variance // information (in which case typeArgumentsRelatedTo defaulted to covariance for all type // arguments). It might also be the case that the target type has a 'void' type argument for // a covariant type parameter that is only used in return positions within the generic type // (in which case any type argument is permitted on the source side). In those cases we proceed // with a structural comparison. Otherwise, we know for certain the instantiations aren't // related and we can return here. if (variances !== ts.emptyArray && !hasCovariantVoidArgument(target, variances)) { // In some cases generic types that are covariant in regular type checking mode become // invariant in --strictFunctionTypes mode because one or more type parameters are used in // both co- and contravariant positions. In order to make it easier to diagnose *why* such // types are invariant, if any of the type parameters are invariant we reset the reported // errors and instead force a structural comparison (which will include elaborations that // reveal the reason). if (!(reportErrors && ts.some(variances, function (v) { return v === 0 /* Invariant */; }))) { return 0 /* False */; } // We remember the original error information so we can restore it in case the structural // comparison unexpectedly succeeds. This can happen when the structural comparison result // is a Ternary.Maybe for example caused by the recursion depth limiter. originalErrorInfo = errorInfo; errorInfo = saveErrorInfo; } } // Even if relationship doesn't hold for unions, intersections, or generic type references, // it may hold in a structural comparison. var sourceIsPrimitive = !!(source.flags & 16382 /* Primitive */); if (relation !== identityRelation) { source = getApparentType(source); } // In a check of the form X = A & B, we will have previously checked if A relates to X or B relates // to X. Failing both of those we want to check if the aggregation of A and B's members structurally // relates to X. Thus, we include intersection types on the source side here. if (source.flags & (65536 /* Object */ | 262144 /* Intersection */) && target.flags & 65536 /* Object */) { // Report structural errors only if we haven't reported any errors yet var reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !sourceIsPrimitive; // An empty object type is related to any mapped type that includes a '?' modifier. if (isPartialMappedType(target) && !isGenericMappedType(source) && isEmptyObjectType(source)) { result = -1 /* True */; } else if (isGenericMappedType(target)) { result = isGenericMappedType(source) ? mappedTypeRelatedTo(source, target, reportStructuralErrors) : 0 /* False */; } else { result = propertiesRelatedTo(source, target, reportStructuralErrors); if (result) { result &= signaturesRelatedTo(source, target, 0 /* Call */, reportStructuralErrors); if (result) { result &= signaturesRelatedTo(source, target, 1 /* Construct */, reportStructuralErrors); if (result) { result &= indexTypesRelatedTo(source, target, 0 /* String */, sourceIsPrimitive, reportStructuralErrors); if (result) { result &= indexTypesRelatedTo(source, target, 1 /* Number */, sourceIsPrimitive, reportStructuralErrors); } } } } } if (result) { if (!originalErrorInfo) { errorInfo = saveErrorInfo; return result; } errorInfo = originalErrorInfo; } } } return 0 /* False */; } // A type [P in S]: X is related to a type [Q in T]: Y if T is related to S and X' is // related to Y, where X' is an instantiation of X in which P is replaced with Q. Notice // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source, target, reportErrors) { var modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : !(getCombinedMappedTypeModifiers(source) & 2 /* Optional */) || getCombinedMappedTypeModifiers(target) & 2 /* Optional */); if (modifiersRelated) { var result_1; if (result_1 = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { var mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]); return result_1 & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), reportErrors); } } return 0 /* False */; } function propertiesRelatedTo(source, target, reportErrors) { if (relation === identityRelation) { return propertiesIdenticalTo(source, target); } var requireOptionalProperties = relation === subtypeRelation && !isObjectLiteralType(source) && !isEmptyArrayLiteralType(source); var unmatchedProperty = getUnmatchedProperty(source, target, requireOptionalProperties); if (unmatchedProperty) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_is_missing_in_type_1, symbolToString(unmatchedProperty), typeToString(source)); } return 0 /* False */; } if (isObjectLiteralType(target)) { for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) { var sourceProp = _a[_i]; if (!getPropertyOfObjectType(target, sourceProp.escapedName)) { var sourceType = getTypeOfSymbol(sourceProp); if (!(sourceType === undefinedType || sourceType === undefinedWideningType)) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_does_not_exist_on_type_1, symbolToString(sourceProp), typeToString(target)); } return 0 /* False */; } } } } var result = -1 /* True */; var properties = getPropertiesOfObjectType(target); for (var _b = 0, properties_3 = properties; _b < properties_3.length; _b++) { var targetProp = properties_3[_b]; if (!(targetProp.flags & 4194304 /* Prototype */)) { var sourceProp = getPropertyOfType(source, targetProp.escapedName); if (sourceProp && sourceProp !== targetProp) { var sourcePropFlags = ts.getDeclarationModifierFlagsFromSymbol(sourceProp); var targetPropFlags = ts.getDeclarationModifierFlagsFromSymbol(targetProp); if (sourcePropFlags & 8 /* Private */ || targetPropFlags & 8 /* Private */) { if (ts.getCheckFlags(sourceProp) & 256 /* ContainsPrivate */) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(sourceProp), typeToString(source)); } return 0 /* False */; } if (sourceProp.valueDeclaration !== targetProp.valueDeclaration) { if (reportErrors) { if (sourcePropFlags & 8 /* Private */ && targetPropFlags & 8 /* Private */) { reportError(ts.Diagnostics.Types_have_separate_declarations_of_a_private_property_0, symbolToString(targetProp)); } else { reportError(ts.Diagnostics.Property_0_is_private_in_type_1_but_not_in_type_2, symbolToString(targetProp), typeToString(sourcePropFlags & 8 /* Private */ ? source : target), typeToString(sourcePropFlags & 8 /* Private */ ? target : source)); } } return 0 /* False */; } } else if (targetPropFlags & 16 /* Protected */) { if (!isValidOverrideOf(sourceProp, targetProp)) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_is_protected_but_type_1_is_not_a_class_derived_from_2, symbolToString(targetProp), typeToString(getDeclaringClass(sourceProp) || source), typeToString(getDeclaringClass(targetProp) || target)); } return 0 /* False */; } } else if (sourcePropFlags & 16 /* Protected */) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_is_protected_in_type_1_but_public_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target)); } return 0 /* False */; } var related = isRelatedTo(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp), reportErrors); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Types_of_property_0_are_incompatible, symbolToString(targetProp)); } return 0 /* False */; } result &= related; // When checking for comparability, be more lenient with optional properties. if (relation !== comparableRelation && sourceProp.flags & 16777216 /* Optional */ && !(targetProp.flags & 16777216 /* Optional */)) { // TypeScript 1.0 spec (April 2014): 3.8.3 // S is a subtype of a type T, and T is a supertype of S if ... // S' and T are object types and, for each member M in T.. // M is a property and S' contains a property N where // if M is a required property, N is also a required property // (M - property in T) // (N - property in S) if (reportErrors) { reportError(ts.Diagnostics.Property_0_is_optional_in_type_1_but_required_in_type_2, symbolToString(targetProp), typeToString(source), typeToString(target)); } return 0 /* False */; } } } } return result; } /** * A type is 'weak' if it is an object type with at least one optional property * and no required properties, call/construct signatures or index signatures */ function isWeakType(type) { if (type.flags & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(type); return resolved.callSignatures.length === 0 && resolved.constructSignatures.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo && resolved.properties.length > 0 && ts.every(resolved.properties, function (p) { return !!(p.flags & 16777216 /* Optional */); }); } if (type.flags & 262144 /* Intersection */) { return ts.every(type.types, isWeakType); } return false; } function hasCommonProperties(source, target) { var isComparingJsxAttributes = !!(source.flags & 67108864 /* JsxAttributes */); for (var _i = 0, _a = getPropertiesOfType(source); _i < _a.length; _i++) { var prop = _a[_i]; if (isKnownProperty(target, prop.escapedName, isComparingJsxAttributes)) { return true; } } return false; } function propertiesIdenticalTo(source, target) { if (!(source.flags & 65536 /* Object */ && target.flags & 65536 /* Object */)) { return 0 /* False */; } var sourceProperties = getPropertiesOfObjectType(source); var targetProperties = getPropertiesOfObjectType(target); if (sourceProperties.length !== targetProperties.length) { return 0 /* False */; } var result = -1 /* True */; for (var _i = 0, sourceProperties_1 = sourceProperties; _i < sourceProperties_1.length; _i++) { var sourceProp = sourceProperties_1[_i]; var targetProp = getPropertyOfObjectType(target, sourceProp.escapedName); if (!targetProp) { return 0 /* False */; } var related = compareProperties(sourceProp, targetProp, isRelatedTo); if (!related) { return 0 /* False */; } result &= related; } return result; } function signaturesRelatedTo(source, target, kind, reportErrors) { if (relation === identityRelation) { return signaturesIdenticalTo(source, target, kind); } if (target === anyFunctionType || source === anyFunctionType) { return -1 /* True */; } var sourceSignatures = getSignaturesOfType(source, kind); var targetSignatures = getSignaturesOfType(target, kind); if (kind === 1 /* Construct */ && sourceSignatures.length && targetSignatures.length) { if (ts.isAbstractConstructorType(source) && !ts.isAbstractConstructorType(target)) { // An abstract constructor type is not assignable to a non-abstract constructor type // as it would otherwise be possible to new an abstract class. Note that the assignability // check we perform for an extends clause excludes construct signatures from the target, // so this check never proceeds. if (reportErrors) { reportError(ts.Diagnostics.Cannot_assign_an_abstract_constructor_type_to_a_non_abstract_constructor_type); } return 0 /* False */; } if (!constructorVisibilitiesAreCompatible(sourceSignatures[0], targetSignatures[0], reportErrors)) { return 0 /* False */; } } var result = -1 /* True */; var saveErrorInfo = errorInfo; if (ts.getObjectFlags(source) & 64 /* Instantiated */ && ts.getObjectFlags(target) & 64 /* Instantiated */ && source.symbol === target.symbol) { // We have instantiations of the same anonymous type (which typically will be the type of a // method). Simply do a pairwise comparison of the signatures in the two signature lists instead // of the much more expensive N * M comparison matrix we explore below. We erase type parameters // as they are known to always be the same. for (var i = 0; i < targetSignatures.length; i++) { var related = signatureRelatedTo(sourceSignatures[i], targetSignatures[i], /*erase*/ true, reportErrors); if (!related) { return 0 /* False */; } result &= related; } } else if (sourceSignatures.length === 1 && targetSignatures.length === 1) { // For simple functions (functions with a single signature) we only erase type parameters for // the comparable relation. Otherwise, if the source signature is generic, we instantiate it // in the context of the target signature before checking the relationship. Ideally we'd do // this regardless of the number of signatures, but the potential costs are prohibitive due // to the quadratic nature of the logic below. var eraseGenerics = relation === comparableRelation || compilerOptions.noStrictGenericChecks; result = signatureRelatedTo(sourceSignatures[0], targetSignatures[0], eraseGenerics, reportErrors); } else { outer: for (var _i = 0, targetSignatures_1 = targetSignatures; _i < targetSignatures_1.length; _i++) { var t = targetSignatures_1[_i]; // Only elaborate errors from the first failure var shouldElaborateErrors = reportErrors; for (var _a = 0, sourceSignatures_1 = sourceSignatures; _a < sourceSignatures_1.length; _a++) { var s = sourceSignatures_1[_a]; var related = signatureRelatedTo(s, t, /*erase*/ true, shouldElaborateErrors); if (related) { result &= related; errorInfo = saveErrorInfo; continue outer; } shouldElaborateErrors = false; } if (shouldElaborateErrors) { reportError(ts.Diagnostics.Type_0_provides_no_match_for_the_signature_1, typeToString(source), signatureToString(t, /*enclosingDeclaration*/ undefined, /*flags*/ undefined, kind)); } return 0 /* False */; } } return result; } /** * See signatureAssignableTo, compareSignaturesIdentical */ function signatureRelatedTo(source, target, erase, reportErrors) { return compareSignaturesRelated(erase ? getErasedSignature(source) : source, erase ? getErasedSignature(target) : target, 0 /* None */, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo); } function signaturesIdenticalTo(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); var targetSignatures = getSignaturesOfType(target, kind); if (sourceSignatures.length !== targetSignatures.length) { return 0 /* False */; } var result = -1 /* True */; for (var i = 0; i < sourceSignatures.length; i++) { var related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreThisTypes*/ false, /*ignoreReturnTypes*/ false, isRelatedTo); if (!related) { return 0 /* False */; } result &= related; } return result; } function eachPropertyRelatedTo(source, target, kind, reportErrors) { var result = -1 /* True */; for (var _i = 0, _a = getPropertiesOfObjectType(source); _i < _a.length; _i++) { var prop = _a[_i]; if (kind === 0 /* String */ || isNumericLiteralName(prop.escapedName)) { var related = isRelatedTo(getTypeOfSymbol(prop), target, reportErrors); if (!related) { if (reportErrors) { reportError(ts.Diagnostics.Property_0_is_incompatible_with_index_signature, symbolToString(prop)); } return 0 /* False */; } result &= related; } } return result; } function indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors) { var related = isRelatedTo(sourceInfo.type, targetInfo.type, reportErrors); if (!related && reportErrors) { reportError(ts.Diagnostics.Index_signatures_are_incompatible); } return related; } function indexTypesRelatedTo(source, target, kind, sourceIsPrimitive, reportErrors) { if (relation === identityRelation) { return indexTypesIdenticalTo(source, target, kind); } var targetInfo = getIndexInfoOfType(target, kind); if (!targetInfo || targetInfo.type.flags & 1 /* Any */ && !sourceIsPrimitive) { // Index signature of type any permits assignment from everything but primitives return -1 /* True */; } var sourceInfo = getIndexInfoOfType(source, kind) || kind === 1 /* Number */ && getIndexInfoOfType(source, 0 /* String */); if (sourceInfo) { return indexInfoRelatedTo(sourceInfo, targetInfo, reportErrors); } if (isGenericMappedType(source)) { // A generic mapped type { [P in K]: T } is related to an index signature { [x: string]: U } // if T is related to U. return kind === 0 /* String */ && isRelatedTo(getTemplateTypeFromMappedType(source), targetInfo.type, reportErrors); } if (isObjectTypeWithInferableIndex(source)) { var related = -1 /* True */; if (kind === 0 /* String */) { var sourceNumberInfo = getIndexInfoOfType(source, 1 /* Number */); if (sourceNumberInfo) { related = indexInfoRelatedTo(sourceNumberInfo, targetInfo, reportErrors); } } if (related) { related &= eachPropertyRelatedTo(source, targetInfo.type, kind, reportErrors); } return related; } if (reportErrors) { reportError(ts.Diagnostics.Index_signature_is_missing_in_type_0, typeToString(source)); } return 0 /* False */; } function indexTypesIdenticalTo(source, target, indexKind) { var targetInfo = getIndexInfoOfType(target, indexKind); var sourceInfo = getIndexInfoOfType(source, indexKind); if (!sourceInfo && !targetInfo) { return -1 /* True */; } if (sourceInfo && targetInfo && sourceInfo.isReadonly === targetInfo.isReadonly) { return isRelatedTo(sourceInfo.type, targetInfo.type); } return 0 /* False */; } function constructorVisibilitiesAreCompatible(sourceSignature, targetSignature, reportErrors) { if (!sourceSignature.declaration || !targetSignature.declaration) { return true; } var sourceAccessibility = ts.getSelectedModifierFlags(sourceSignature.declaration, 24 /* NonPublicAccessibilityModifier */); var targetAccessibility = ts.getSelectedModifierFlags(targetSignature.declaration, 24 /* NonPublicAccessibilityModifier */); // A public, protected and private signature is assignable to a private signature. if (targetAccessibility === 8 /* Private */) { return true; } // A public and protected signature is assignable to a protected signature. if (targetAccessibility === 16 /* Protected */ && sourceAccessibility !== 8 /* Private */) { return true; } // Only a public signature is assignable to public signature. if (targetAccessibility !== 16 /* Protected */ && !sourceAccessibility) { return true; } if (reportErrors) { reportError(ts.Diagnostics.Cannot_assign_a_0_constructor_type_to_a_1_constructor_type, visibilityToString(sourceAccessibility), visibilityToString(targetAccessibility)); } return false; } } // Return a type reference where the source type parameter is replaced with the target marker // type, and flag the result as a marker type reference. function getMarkerTypeReference(type, source, target) { var result = createTypeReference(type, ts.map(type.typeParameters, function (t) { return t === source ? target : t; })); result.flags |= 134217728 /* MarkerType */; return result; } // Return an array containing the variance of each type parameter. The variance is effectively // a digest of the type comparisons that occur for each type argument when instantiations of the // generic type are structurally compared. We infer the variance information by comparing // instantiations of the generic type for type arguments with known relations. The function // returns the emptyArray singleton if we're not in strictFunctionTypes mode or if the function // has been invoked recursively for the given generic type. function getVariances(type) { if (!strictFunctionTypes) { return ts.emptyArray; } var typeParameters = type.typeParameters || ts.emptyArray; var variances = type.variances; if (!variances) { if (type === globalArrayType || type === globalReadonlyArrayType) { // Arrays are known to be covariant, no need to spend time computing this variances = [1 /* Covariant */]; } else { // The emptyArray singleton is used to signal a recursive invocation. type.variances = ts.emptyArray; variances = []; for (var _i = 0, typeParameters_1 = typeParameters; _i < typeParameters_1.length; _i++) { var tp = typeParameters_1[_i]; // We first compare instantiations where the type parameter is replaced with // marker types that have a known subtype relationship. From this we can infer // invariance, covariance, contravariance or bivariance. var typeWithSuper = getMarkerTypeReference(type, tp, markerSuperType); var typeWithSub = getMarkerTypeReference(type, tp, markerSubType); var variance = (isTypeAssignableTo(typeWithSub, typeWithSuper) ? 1 /* Covariant */ : 0) | (isTypeAssignableTo(typeWithSuper, typeWithSub) ? 2 /* Contravariant */ : 0); // If the instantiations appear to be related bivariantly it may be because the // type parameter is independent (i.e. it isn't witnessed anywhere in the generic // type). To determine this we compare instantiations where the type parameter is // replaced with marker types that are known to be unrelated. if (variance === 3 /* Bivariant */ && isTypeAssignableTo(getMarkerTypeReference(type, tp, markerOtherType), typeWithSuper)) { variance = 4 /* Independent */; } variances.push(variance); } } type.variances = variances; } return variances; } // Return true if the given type reference has a 'void' type argument for a covariant type parameter. // See comment at call in recursiveTypeRelatedTo for when this case matters. function hasCovariantVoidArgument(type, variances) { for (var i = 0; i < variances.length; i++) { if (variances[i] === 1 /* Covariant */ && type.typeArguments[i].flags & 2048 /* Void */) { return true; } } return false; } function isUnconstrainedTypeParameter(type) { return type.flags & 32768 /* TypeParameter */ && !getConstraintFromTypeParameter(type); } function isTypeReferenceWithGenericArguments(type) { return ts.getObjectFlags(type) & 4 /* Reference */ && ts.some(type.typeArguments, function (t) { return isUnconstrainedTypeParameter(t) || isTypeReferenceWithGenericArguments(t); }); } /** * getTypeReferenceId(A) returns "111=0-12=1" * where A.id=111 and number.id=12 */ function getTypeReferenceId(type, typeParameters, depth) { if (depth === void 0) { depth = 0; } var result = "" + type.target.id; for (var _i = 0, _a = type.typeArguments; _i < _a.length; _i++) { var t = _a[_i]; if (isUnconstrainedTypeParameter(t)) { var index = ts.indexOf(typeParameters, t); if (index < 0) { index = typeParameters.length; typeParameters.push(t); } result += "=" + index; } else if (depth < 4 && isTypeReferenceWithGenericArguments(t)) { result += "<" + getTypeReferenceId(t, typeParameters, depth + 1) + ">"; } else { result += "-" + t.id; } } return result; } /** * To improve caching, the relation key for two generic types uses the target's id plus ids of the type parameters. * For other cases, the types ids are used. */ function getRelationKey(source, target, relation) { if (relation === identityRelation && source.id > target.id) { var temp = source; source = target; target = temp; } if (isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target)) { var typeParameters = []; return getTypeReferenceId(source, typeParameters) + "," + getTypeReferenceId(target, typeParameters); } return source.id + "," + target.id; } // Invoke the callback for each underlying property symbol of the given symbol and return the first // value that isn't undefined. function forEachProperty(prop, callback) { if (ts.getCheckFlags(prop) & 6 /* Synthetic */) { for (var _i = 0, _a = prop.containingType.types; _i < _a.length; _i++) { var t = _a[_i]; var p = getPropertyOfType(t, prop.escapedName); var result = p && forEachProperty(p, callback); if (result) { return result; } } return undefined; } return callback(prop); } // Return the declaring class type of a property or undefined if property not declared in class function getDeclaringClass(prop) { return prop.parent && prop.parent.flags & 32 /* Class */ ? getDeclaredTypeOfSymbol(getParentOfSymbol(prop)) : undefined; } // Return true if some underlying source property is declared in a class that derives // from the given base class. function isPropertyInClassDerivedFrom(prop, baseClass) { return forEachProperty(prop, function (sp) { var sourceClass = getDeclaringClass(sp); return sourceClass ? hasBaseType(sourceClass, baseClass) : false; }); } // Return true if source property is a valid override of protected parts of target property. function isValidOverrideOf(sourceProp, targetProp) { return !forEachProperty(targetProp, function (tp) { return ts.getDeclarationModifierFlagsFromSymbol(tp) & 16 /* Protected */ ? !isPropertyInClassDerivedFrom(sourceProp, getDeclaringClass(tp)) : false; }); } // Return true if the given class derives from each of the declaring classes of the protected // constituents of the given property. function isClassDerivedFromDeclaringClasses(checkClass, prop) { return forEachProperty(prop, function (p) { return ts.getDeclarationModifierFlagsFromSymbol(p) & 16 /* Protected */ ? !hasBaseType(checkClass, getDeclaringClass(p)) : false; }) ? undefined : checkClass; } // Return true if the given type is deeply nested. We consider this to be the case when structural type comparisons // for 5 or more occurrences or instantiations of the type have been recorded on the given stack. It is possible, // though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely // expanding. Effectively, we will generate a false positive when two types are structurally equal to at least 5 // levels, but unequal at some level beyond that. function isDeeplyNestedType(type, stack, depth) { // We track all object types that have an associated symbol (representing the origin of the type) if (depth >= 5 && type.flags & 65536 /* Object */) { var symbol = type.symbol; if (symbol) { var count = 0; for (var i = 0; i < depth; i++) { var t = stack[i]; if (t.flags & 65536 /* Object */ && t.symbol === symbol) { count++; if (count >= 5) return true; } } } } return false; } function isPropertyIdenticalTo(sourceProp, targetProp) { return compareProperties(sourceProp, targetProp, compareTypesIdentical) !== 0 /* False */; } function compareProperties(sourceProp, targetProp, compareTypes) { // Two members are considered identical when // - they are public properties with identical names, optionality, and types, // - they are private or protected properties originating in the same declaration and having identical types if (sourceProp === targetProp) { return -1 /* True */; } var sourcePropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(sourceProp) & 24 /* NonPublicAccessibilityModifier */; var targetPropAccessibility = ts.getDeclarationModifierFlagsFromSymbol(targetProp) & 24 /* NonPublicAccessibilityModifier */; if (sourcePropAccessibility !== targetPropAccessibility) { return 0 /* False */; } if (sourcePropAccessibility) { if (getTargetSymbol(sourceProp) !== getTargetSymbol(targetProp)) { return 0 /* False */; } } else { if ((sourceProp.flags & 16777216 /* Optional */) !== (targetProp.flags & 16777216 /* Optional */)) { return 0 /* False */; } } if (isReadonlySymbol(sourceProp) !== isReadonlySymbol(targetProp)) { return 0 /* False */; } return compareTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); } function isMatchingSignature(source, target, partialMatch) { // A source signature matches a target signature if the two signatures have the same number of required, // optional, and rest parameters. if (source.parameters.length === target.parameters.length && source.minArgumentCount === target.minArgumentCount && source.hasRestParameter === target.hasRestParameter) { return true; } // A source signature partially matches a target signature if the target signature has no fewer required // parameters and no more overall parameters than the source signature (where a signature with a rest // parameter is always considered to have more overall parameters than one without). var sourceRestCount = source.hasRestParameter ? 1 : 0; var targetRestCount = target.hasRestParameter ? 1 : 0; if (partialMatch && source.minArgumentCount <= target.minArgumentCount && (sourceRestCount > targetRestCount || sourceRestCount === targetRestCount && source.parameters.length >= target.parameters.length)) { return true; } return false; } /** * See signatureRelatedTo, compareSignaturesIdentical */ function compareSignaturesIdentical(source, target, partialMatch, ignoreThisTypes, ignoreReturnTypes, compareTypes) { // TODO (drosen): De-duplicate code between related functions. if (source === target) { return -1 /* True */; } if (!(isMatchingSignature(source, target, partialMatch))) { return 0 /* False */; } // Check that the two signatures have the same number of type parameters. We might consider // also checking that any type parameter constraints match, but that would require instantiating // the constraints with a common set of type arguments to get relatable entities in places where // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile, // particularly as we're comparing erased versions of the signatures below. if (ts.length(source.typeParameters) !== ts.length(target.typeParameters)) { return 0 /* False */; } // Spec 1.0 Section 3.8.3 & 3.8.4: // M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N source = getErasedSignature(source); target = getErasedSignature(target); var result = -1 /* True */; if (!ignoreThisTypes) { var sourceThisType = getThisTypeOfSignature(source); if (sourceThisType) { var targetThisType = getThisTypeOfSignature(target); if (targetThisType) { var related = compareTypes(sourceThisType, targetThisType); if (!related) { return 0 /* False */; } result &= related; } } } var targetLen = target.parameters.length; for (var i = 0; i < targetLen; i++) { var s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfParameter(source.parameters[i]); var t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfParameter(target.parameters[i]); var related = compareTypes(s, t); if (!related) { return 0 /* False */; } result &= related; } if (!ignoreReturnTypes) { result &= compareTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } return result; } function isRestParameterIndex(signature, parameterIndex) { return signature.hasRestParameter && parameterIndex >= signature.parameters.length - 1; } function literalTypesWithSameBaseType(types) { var commonBaseType; for (var _i = 0, types_10 = types; _i < types_10.length; _i++) { var t = types_10[_i]; var baseType = getBaseTypeOfLiteralType(t); if (!commonBaseType) { commonBaseType = baseType; } if (baseType === t || baseType !== commonBaseType) { return false; } } return true; } // When the candidate types are all literal types with the same base type, return a union // of those literal types. Otherwise, return the leftmost type for which no type to the // right is a supertype. function getSupertypeOrUnion(types) { return literalTypesWithSameBaseType(types) ? getUnionType(types) : ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(s, t) ? t : s; }); } function getCommonSupertype(types) { if (!strictNullChecks) { return getSupertypeOrUnion(types); } var primaryTypes = ts.filter(types, function (t) { return !(t.flags & 12288 /* Nullable */); }); return primaryTypes.length ? getNullableType(getSupertypeOrUnion(primaryTypes), getFalsyFlagsOfTypes(types) & 12288 /* Nullable */) : getUnionType(types, /*subtypeReduction*/ true); } // Return the leftmost type for which no type to the right is a subtype. function getCommonSubtype(types) { return ts.reduceLeft(types, function (s, t) { return isTypeSubtypeOf(t, s) ? t : s; }); } function isArrayType(type) { return ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalArrayType; } function isArrayLikeType(type) { // A type is array-like if it is a reference to the global Array or global ReadonlyArray type, // or if it is not the undefined or null type and if it is assignable to ReadonlyArray return ts.getObjectFlags(type) & 4 /* Reference */ && (type.target === globalArrayType || type.target === globalReadonlyArrayType) || !(type.flags & 12288 /* Nullable */) && isTypeAssignableTo(type, anyReadonlyArrayType); } function isEmptyArrayLiteralType(type) { var elementType = isArrayType(type) ? type.typeArguments[0] : undefined; return elementType === undefinedWideningType || elementType === implicitNeverType; } function isTupleLikeType(type) { return !!getPropertyOfType(type, "0"); } function isUnitType(type) { return !!(type.flags & 13536 /* Unit */); } function isLiteralType(type) { return type.flags & 8 /* Boolean */ ? true : type.flags & 131072 /* Union */ ? type.flags & 256 /* EnumLiteral */ ? true : !ts.forEach(type.types, function (t) { return !isUnitType(t); }) : isUnitType(type); } function getBaseTypeOfLiteralType(type) { return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) : type.flags & 32 /* StringLiteral */ ? stringType : type.flags & 64 /* NumberLiteral */ ? numberType : type.flags & 128 /* BooleanLiteral */ ? booleanType : type.flags & 131072 /* Union */ ? getUnionType(ts.sameMap(type.types, getBaseTypeOfLiteralType)) : type; } function getWidenedLiteralType(type) { return type.flags & 256 /* EnumLiteral */ ? getBaseTypeOfEnumLiteralType(type) : type.flags & 32 /* StringLiteral */ && type.flags & 2097152 /* FreshLiteral */ ? stringType : type.flags & 64 /* NumberLiteral */ && type.flags & 2097152 /* FreshLiteral */ ? numberType : type.flags & 128 /* BooleanLiteral */ ? booleanType : type.flags & 131072 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedLiteralType)) : type; } function getWidenedUniqueESSymbolType(type) { return type.flags & 1024 /* UniqueESSymbol */ ? esSymbolType : type.flags & 131072 /* Union */ ? getUnionType(ts.sameMap(type.types, getWidenedUniqueESSymbolType)) : type; } function getWidenedLiteralLikeTypeForContextualType(type, contextualType) { if (!isLiteralOfContextualType(type, contextualType)) { type = getWidenedUniqueESSymbolType(getWidenedLiteralType(type)); } return type; } /** * Check if a Type was written as a tuple type literal. * Prefer using isTupleLikeType() unless the use of `elementTypes` is required. */ function isTupleType(type) { return !!(ts.getObjectFlags(type) & 4 /* Reference */ && type.target.objectFlags & 8 /* Tuple */); } function getFalsyFlagsOfTypes(types) { var result = 0; for (var _i = 0, types_11 = types; _i < types_11.length; _i++) { var t = types_11[_i]; result |= getFalsyFlags(t); } return result; } // Returns the String, Number, Boolean, StringLiteral, NumberLiteral, BooleanLiteral, Void, Undefined, or Null // flags for the string, number, boolean, "", 0, false, void, undefined, or null types respectively. Returns // no flags for all other types (including non-falsy literal types). function getFalsyFlags(type) { return type.flags & 131072 /* Union */ ? getFalsyFlagsOfTypes(type.types) : type.flags & 32 /* StringLiteral */ ? type.value === "" ? 32 /* StringLiteral */ : 0 : type.flags & 64 /* NumberLiteral */ ? type.value === 0 ? 64 /* NumberLiteral */ : 0 : type.flags & 128 /* BooleanLiteral */ ? type === falseType ? 128 /* BooleanLiteral */ : 0 : type.flags & 14574 /* PossiblyFalsy */; } function removeDefinitelyFalsyTypes(type) { return getFalsyFlags(type) & 14560 /* DefinitelyFalsy */ ? filterType(type, function (t) { return !(getFalsyFlags(t) & 14560 /* DefinitelyFalsy */); }) : type; } function extractDefinitelyFalsyTypes(type) { return mapType(type, getDefinitelyFalsyPartOfType); } function getDefinitelyFalsyPartOfType(type) { return type.flags & 2 /* String */ ? emptyStringType : type.flags & 4 /* Number */ ? zeroType : type.flags & 8 /* Boolean */ || type === falseType ? falseType : type.flags & (2048 /* Void */ | 4096 /* Undefined */ | 8192 /* Null */) || type.flags & 32 /* StringLiteral */ && type.value === "" || type.flags & 64 /* NumberLiteral */ && type.value === 0 ? type : neverType; } /** * Add undefined or null or both to a type if they are missing. * @param type - type to add undefined and/or null to if not present * @param flags - Either TypeFlags.Undefined or TypeFlags.Null, or both */ function getNullableType(type, flags) { var missing = (flags & ~type.flags) & (4096 /* Undefined */ | 8192 /* Null */); return missing === 0 ? type : missing === 4096 /* Undefined */ ? getUnionType([type, undefinedType]) : missing === 8192 /* Null */ ? getUnionType([type, nullType]) : getUnionType([type, undefinedType, nullType]); } function getOptionalType(type) { ts.Debug.assert(strictNullChecks); return type.flags & 4096 /* Undefined */ ? type : getUnionType([type, undefinedType]); } function getNonNullableType(type) { return strictNullChecks ? getTypeWithFacts(type, 524288 /* NEUndefinedOrNull */) : type; } /** * Return true if type was inferred from an object literal, written as an object type literal, or is the shape of a module * with no call or construct signatures. */ function isObjectTypeWithInferableIndex(type) { return type.symbol && (type.symbol.flags & (4096 /* ObjectLiteral */ | 2048 /* TypeLiteral */ | 512 /* ValueModule */)) !== 0 && !typeHasCallOrConstructSignatures(type); } function createSymbolWithType(source, type) { var symbol = createSymbol(source.flags, source.escapedName); symbol.declarations = source.declarations; symbol.parent = source.parent; symbol.type = type; symbol.target = source; if (source.valueDeclaration) { symbol.valueDeclaration = source.valueDeclaration; } return symbol; } function transformTypeOfMembers(type, f) { var members = ts.createSymbolTable(); for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { var property = _a[_i]; var original = getTypeOfSymbol(property); var updated = f(original); members.set(property.escapedName, updated === original ? property : createSymbolWithType(property, updated)); } return members; } /** * If the the provided object literal is subject to the excess properties check, * create a new that is exempt. Recursively mark object literal members as exempt. * Leave signatures alone since they are not subject to the check. */ function getRegularTypeOfObjectLiteral(type) { if (!(isObjectLiteralType(type) && type.flags & 2097152 /* FreshLiteral */)) { return type; } var regularType = type.regularType; if (regularType) { return regularType; } var resolved = type; var members = transformTypeOfMembers(type, getRegularTypeOfObjectLiteral); var regularNew = createAnonymousType(resolved.symbol, members, resolved.callSignatures, resolved.constructSignatures, resolved.stringIndexInfo, resolved.numberIndexInfo); regularNew.flags = resolved.flags & ~2097152 /* FreshLiteral */; regularNew.objectFlags |= 128 /* ObjectLiteral */; type.regularType = regularNew; return regularNew; } function createWideningContext(parent, propertyName, siblings) { return { parent: parent, propertyName: propertyName, siblings: siblings, resolvedPropertyNames: undefined }; } function getSiblingsOfContext(context) { if (!context.siblings) { var siblings_1 = []; for (var _i = 0, _a = getSiblingsOfContext(context.parent); _i < _a.length; _i++) { var type = _a[_i]; if (isObjectLiteralType(type)) { var prop = getPropertyOfObjectType(type, context.propertyName); if (prop) { forEachType(getTypeOfSymbol(prop), function (t) { siblings_1.push(t); }); } } } context.siblings = siblings_1; } return context.siblings; } function getPropertyNamesOfContext(context) { if (!context.resolvedPropertyNames) { var names = ts.createMap(); for (var _i = 0, _a = getSiblingsOfContext(context); _i < _a.length; _i++) { var t = _a[_i]; if (isObjectLiteralType(t) && !(ts.getObjectFlags(t) & 1024 /* ContainsSpread */)) { for (var _b = 0, _c = getPropertiesOfType(t); _b < _c.length; _b++) { var prop = _c[_b]; names.set(prop.escapedName, true); } } } context.resolvedPropertyNames = ts.arrayFrom(names.keys()); } return context.resolvedPropertyNames; } function getWidenedProperty(prop, context) { var original = getTypeOfSymbol(prop); var propContext = context && createWideningContext(context, prop.escapedName, /*siblings*/ undefined); var widened = getWidenedTypeWithContext(original, propContext); return widened === original ? prop : createSymbolWithType(prop, widened); } function getUndefinedProperty(name) { var cached = undefinedProperties.get(name); if (cached) { return cached; } var result = createSymbol(4 /* Property */ | 16777216 /* Optional */, name); result.type = undefinedType; undefinedProperties.set(name, result); return result; } function getWidenedTypeOfObjectLiteral(type, context) { var members = ts.createSymbolTable(); for (var _i = 0, _a = getPropertiesOfObjectType(type); _i < _a.length; _i++) { var prop = _a[_i]; // Since get accessors already widen their return value there is no need to // widen accessor based properties here. members.set(prop.escapedName, prop.flags & 4 /* Property */ ? getWidenedProperty(prop, context) : prop); } if (context) { for (var _b = 0, _c = getPropertyNamesOfContext(context); _b < _c.length; _b++) { var name = _c[_b]; if (!members.has(name)) { members.set(name, getUndefinedProperty(name)); } } } var stringIndexInfo = getIndexInfoOfType(type, 0 /* String */); var numberIndexInfo = getIndexInfoOfType(type, 1 /* Number */); return createAnonymousType(type.symbol, members, ts.emptyArray, ts.emptyArray, stringIndexInfo && createIndexInfo(getWidenedType(stringIndexInfo.type), stringIndexInfo.isReadonly), numberIndexInfo && createIndexInfo(getWidenedType(numberIndexInfo.type), numberIndexInfo.isReadonly)); } function getWidenedType(type) { return getWidenedTypeWithContext(type, /*context*/ undefined); } function getWidenedTypeWithContext(type, context) { if (type.flags & 12582912 /* RequiresWidening */) { if (type.flags & 12288 /* Nullable */) { return anyType; } if (isObjectLiteralType(type)) { return getWidenedTypeOfObjectLiteral(type, context); } if (type.flags & 131072 /* Union */) { var unionContext_1 = context || createWideningContext(/*parent*/ undefined, /*propertyName*/ undefined, type.types); var widenedTypes = ts.sameMap(type.types, function (t) { return t.flags & 12288 /* Nullable */ ? t : getWidenedTypeWithContext(t, unionContext_1); }); // Widening an empty object literal transitions from a highly restrictive type to // a highly inclusive one. For that reason we perform subtype reduction here if the // union includes empty object types (e.g. reducing {} | string to just {}). return getUnionType(widenedTypes, ts.some(widenedTypes, isEmptyObjectType)); } if (isArrayType(type) || isTupleType(type)) { return createTypeReference(type.target, ts.sameMap(type.typeArguments, getWidenedType)); } } return type; } /** * Reports implicit any errors that occur as a result of widening 'null' and 'undefined' * to 'any'. A call to reportWideningErrorsInType is normally accompanied by a call to * getWidenedType. But in some cases getWidenedType is called without reporting errors * (type argument inference is an example). * * The return value indicates whether an error was in fact reported. The particular circumstances * are on a best effort basis. Currently, if the null or undefined that causes widening is inside * an object literal property (arbitrarily deeply), this function reports an error. If no error is * reported, reportImplicitAnyError is a suitable fallback to report a general error. */ function reportWideningErrorsInType(type) { var errorReported = false; if (type.flags & 4194304 /* ContainsWideningType */) { if (type.flags & 131072 /* Union */) { if (ts.some(type.types, isEmptyObjectType)) { errorReported = true; } else { for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var t = _a[_i]; if (reportWideningErrorsInType(t)) { errorReported = true; } } } } if (isArrayType(type) || isTupleType(type)) { for (var _b = 0, _c = type.typeArguments; _b < _c.length; _b++) { var t = _c[_b]; if (reportWideningErrorsInType(t)) { errorReported = true; } } } if (isObjectLiteralType(type)) { for (var _d = 0, _e = getPropertiesOfObjectType(type); _d < _e.length; _d++) { var p = _e[_d]; var t = getTypeOfSymbol(p); if (t.flags & 4194304 /* ContainsWideningType */) { if (!reportWideningErrorsInType(t)) { error(p.valueDeclaration, ts.Diagnostics.Object_literal_s_property_0_implicitly_has_an_1_type, ts.symbolName(p), typeToString(getWidenedType(t))); } errorReported = true; } } } } return errorReported; } function reportImplicitAnyError(declaration, type) { var typeAsString = typeToString(getWidenedType(type)); var diagnostic; switch (declaration.kind) { case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: diagnostic = ts.Diagnostics.Member_0_implicitly_has_an_1_type; break; case 147 /* 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 177 /* BindingElement */: diagnostic = ts.Diagnostics.Binding_element_0_implicitly_has_an_1_type; break; case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: if (!declaration.name) { error(declaration, ts.Diagnostics.Function_expression_which_lacks_return_type_annotation_implicitly_has_an_0_return_type, typeAsString); return; } diagnostic = ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type; break; default: diagnostic = ts.Diagnostics.Variable_0_implicitly_has_an_1_type; } error(declaration, diagnostic, ts.declarationNameToString(ts.getNameOfDeclaration(declaration)), typeAsString); } function reportErrorsFromWidening(declaration, type) { if (produceDiagnostics && noImplicitAny && type.flags & 4194304 /* ContainsWideningType */) { // Report implicit any error within type if possible, otherwise report error on declaration if (!reportWideningErrorsInType(type)) { reportImplicitAnyError(declaration, type); } } } function forEachMatchingParameterType(source, target, callback) { var sourceMax = source.parameters.length; var targetMax = target.parameters.length; var count; if (source.hasRestParameter && target.hasRestParameter) { count = Math.max(sourceMax, targetMax); } else if (source.hasRestParameter) { count = targetMax; } else if (target.hasRestParameter) { count = sourceMax; } else { count = Math.min(sourceMax, targetMax); } for (var i = 0; i < count; i++) { callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i)); } } function createInferenceContext(signature, flags, compareTypes, baseInferences) { var inferences = baseInferences ? ts.map(baseInferences, cloneInferenceInfo) : ts.map(signature.typeParameters, createInferenceInfo); var context = mapper; context.signature = signature; context.inferences = inferences; context.flags = flags; context.compareTypes = compareTypes || compareTypesAssignable; return context; function mapper(t) { for (var i = 0; i < inferences.length; i++) { if (t === inferences[i].typeParameter) { inferences[i].isFixed = true; return getInferredType(context, i); } } return t; } } function createInferenceInfo(typeParameter) { return { typeParameter: typeParameter, candidates: undefined, inferredType: undefined, priority: undefined, topLevel: true, isFixed: false }; } function cloneInferenceInfo(inference) { return { typeParameter: inference.typeParameter, candidates: inference.candidates && inference.candidates.slice(), inferredType: inference.inferredType, priority: inference.priority, topLevel: inference.topLevel, isFixed: inference.isFixed }; } // Return true if the given type could possibly reference a type parameter for which // we perform type inference (i.e. a type parameter of a generic function). We cache // results for union and intersection types for performance reasons. function couldContainTypeVariables(type) { var objectFlags = ts.getObjectFlags(type); return !!(type.flags & (1081344 /* TypeVariable */ | 524288 /* Index */) || objectFlags & 4 /* Reference */ && ts.forEach(type.typeArguments, couldContainTypeVariables) || objectFlags & 16 /* Anonymous */ && type.symbol && type.symbol.flags & (16 /* Function */ | 8192 /* Method */ | 2048 /* TypeLiteral */ | 32 /* Class */) || objectFlags & 32 /* Mapped */ || type.flags & 393216 /* UnionOrIntersection */ && couldUnionOrIntersectionContainTypeVariables(type)); } function couldUnionOrIntersectionContainTypeVariables(type) { if (type.couldContainTypeVariables === undefined) { type.couldContainTypeVariables = ts.forEach(type.types, couldContainTypeVariables); } return type.couldContainTypeVariables; } function isTypeParameterAtTopLevel(type, typeParameter) { return type === typeParameter || type.flags & 393216 /* UnionOrIntersection */ && ts.forEach(type.types, function (t) { return isTypeParameterAtTopLevel(t, typeParameter); }); } /** Create an object with properties named in the string literal type. Every property has type `{}` */ function createEmptyObjectTypeFromStringLiteral(type) { var members = ts.createSymbolTable(); forEachType(type, function (t) { if (!(t.flags & 32 /* StringLiteral */)) { return; } var name = ts.escapeLeadingUnderscores(t.value); var literalProp = createSymbol(4 /* Property */, name); literalProp.type = emptyObjectType; if (t.symbol) { literalProp.declarations = t.symbol.declarations; literalProp.valueDeclaration = t.symbol.valueDeclaration; } members.set(name, literalProp); }); var indexInfo = type.flags & 2 /* String */ ? createIndexInfo(emptyObjectType, /*isReadonly*/ false) : undefined; return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined); } /** * Infer a suitable input type for a homomorphic mapped type { [P in keyof T]: X }. We construct * an object type with the same set of properties as the source type, where the type of each * property is computed by inferring from the source property type to X for the type * variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for). */ function inferTypeForHomomorphicMappedType(source, target, mappedTypeStack) { var properties = getPropertiesOfType(source); var indexInfo = getIndexInfoOfType(source, 0 /* String */); if (properties.length === 0 && !indexInfo) { return undefined; } var typeParameter = getIndexedAccessType(getConstraintTypeFromMappedType(target).type, getTypeParameterFromMappedType(target)); var inference = createInferenceInfo(typeParameter); var inferences = [inference]; var templateType = getTemplateTypeFromMappedType(target); var readonlyMask = target.declaration.readonlyToken ? false : true; var optionalMask = target.declaration.questionToken ? 0 : 16777216 /* Optional */; var members = ts.createSymbolTable(); for (var _i = 0, properties_4 = properties; _i < properties_4.length; _i++) { var prop = properties_4[_i]; var propType = getTypeOfSymbol(prop); // If any property contains context sensitive functions that have been skipped, the source type // is incomplete and we can't infer a meaningful input type. if (propType.flags & 16777216 /* ContainsAnyFunctionType */) { return undefined; } var checkFlags = readonlyMask && isReadonlySymbol(prop) ? 8 /* Readonly */ : 0; var inferredProp = createSymbol(4 /* Property */ | prop.flags & optionalMask, prop.escapedName, checkFlags); inferredProp.declarations = prop.declarations; inferredProp.type = inferTargetType(propType); members.set(prop.escapedName, inferredProp); } if (indexInfo) { indexInfo = createIndexInfo(inferTargetType(indexInfo.type), readonlyMask && indexInfo.isReadonly); } return createAnonymousType(undefined, members, ts.emptyArray, ts.emptyArray, indexInfo, undefined); function inferTargetType(sourceType) { inference.candidates = undefined; inferTypes(inferences, sourceType, templateType, 0, mappedTypeStack); return inference.candidates ? getUnionType(inference.candidates, /*subtypeReduction*/ true) : emptyObjectType; } } function getUnmatchedProperty(source, target, requireOptionalProperties) { var properties = target.flags & 262144 /* Intersection */ ? getPropertiesOfUnionOrIntersectionType(target) : getPropertiesOfObjectType(target); for (var _i = 0, properties_5 = properties; _i < properties_5.length; _i++) { var targetProp = properties_5[_i]; if (requireOptionalProperties || !(targetProp.flags & 16777216 /* Optional */)) { var sourceProp = getPropertyOfType(source, targetProp.escapedName); if (!sourceProp) { return targetProp; } } } return undefined; } function inferTypes(inferences, originalSource, originalTarget, priority, mappedTypeStack) { if (priority === void 0) { priority = 0; } var symbolStack; var visited; inferFromTypes(originalSource, originalTarget); function inferFromTypes(source, target) { if (!couldContainTypeVariables(target)) { return; } if (source.aliasSymbol && source.aliasTypeArguments && source.aliasSymbol === target.aliasSymbol) { // Source and target are types originating in the same generic type alias declaration. // Simply infer from source type arguments to target type arguments. var sourceTypes = source.aliasTypeArguments; var targetTypes = target.aliasTypeArguments; for (var i = 0; i < sourceTypes.length; i++) { inferFromTypes(sourceTypes[i], targetTypes[i]); } return; } if (source.flags & 131072 /* Union */ && target.flags & 131072 /* Union */ && !(source.flags & 256 /* EnumLiteral */ && target.flags & 256 /* EnumLiteral */) || source.flags & 262144 /* Intersection */ && target.flags & 262144 /* Intersection */) { // Source and target are both unions or both intersections. If source and target // are the same type, just relate each constituent type to itself. if (source === target) { for (var _i = 0, _a = source.types; _i < _a.length; _i++) { var t = _a[_i]; inferFromTypes(t, t); } return; } // Find each source constituent type that has an identically matching target constituent // type, and for each such type infer from the type to itself. When inferring from a // type to itself we effectively find all type parameter occurrences within that type // and infer themselves as their type arguments. We have special handling for numeric // and string literals because the number and string types are not represented as unions // of all their possible values. var matchingTypes = void 0; for (var _b = 0, _c = source.types; _b < _c.length; _b++) { var t = _c[_b]; if (typeIdenticalToSomeType(t, target.types)) { (matchingTypes || (matchingTypes = [])).push(t); inferFromTypes(t, t); } else if (t.flags & (64 /* NumberLiteral */ | 32 /* StringLiteral */)) { var b = getBaseTypeOfLiteralType(t); if (typeIdenticalToSomeType(b, target.types)) { (matchingTypes || (matchingTypes = [])).push(t, b); } } } // Next, to improve the quality of inferences, reduce the source and target types by // removing the identically matched constituents. For example, when inferring from // 'string | string[]' to 'string | T' we reduce the types to 'string[]' and 'T'. if (matchingTypes) { source = removeTypesFromUnionOrIntersection(source, matchingTypes); target = removeTypesFromUnionOrIntersection(target, matchingTypes); } } if (target.flags & 1081344 /* TypeVariable */) { // If target is a type parameter, make an inference, unless the source type contains // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions). // Because the anyFunctionType is internal, it should not be exposed to the user by adding // it as an inference candidate. Hopefully, a better candidate will come along that does // not contain anyFunctionType when we come back to this argument for its second round // of inference. Also, we exclude inferences for silentNeverType (which is used as a wildcard // when constructing types from type parameters that had no inference candidates). if (source.flags & 16777216 /* ContainsAnyFunctionType */ || source === silentNeverType) { return; } var inference = getInferenceInfoForType(target); if (inference) { if (!inference.isFixed) { // We give lowest priority to inferences of implicitNeverType (which is used as the // element type for empty array literals). Thus, inferences from empty array literals // only matter when no other inferences are made. var p = priority | (source === implicitNeverType ? 16 /* NeverType */ : 0); if (!inference.candidates || p < inference.priority) { inference.candidates = [source]; inference.priority = p; } else if (p === inference.priority) { inference.candidates.push(source); } if (!(p & 8 /* ReturnType */) && target.flags & 32768 /* TypeParameter */ && !isTypeParameterAtTopLevel(originalTarget, target)) { inference.topLevel = false; } } return; } } else if (ts.getObjectFlags(source) & 4 /* Reference */ && ts.getObjectFlags(target) & 4 /* Reference */ && source.target === target.target) { // If source and target are references to the same generic type, infer from type arguments var sourceTypes = source.typeArguments || ts.emptyArray; var targetTypes = target.typeArguments || ts.emptyArray; var count = sourceTypes.length < targetTypes.length ? sourceTypes.length : targetTypes.length; var variances = getVariances(source.target); for (var i = 0; i < count; i++) { if (i < variances.length && variances[i] === 2 /* Contravariant */) { inferFromContravariantTypes(sourceTypes[i], targetTypes[i]); } else { inferFromTypes(sourceTypes[i], targetTypes[i]); } } } else if (source.flags & 524288 /* Index */ && target.flags & 524288 /* Index */) { priority ^= 1 /* Contravariant */; inferFromTypes(source.type, target.type); priority ^= 1 /* Contravariant */; } else if ((isLiteralType(source) || source.flags & 2 /* String */) && target.flags & 524288 /* Index */) { var empty = createEmptyObjectTypeFromStringLiteral(source); priority ^= 1 /* Contravariant */; inferFromTypes(empty, target.type); priority ^= 1 /* Contravariant */; } else if (source.flags & 1048576 /* IndexedAccess */ && target.flags & 1048576 /* IndexedAccess */) { inferFromTypes(source.objectType, target.objectType); inferFromTypes(source.indexType, target.indexType); } else if (target.flags & 393216 /* UnionOrIntersection */) { var targetTypes = target.types; var typeVariableCount = 0; var typeVariable = void 0; // First infer to each type in union or intersection that isn't a type variable for (var _d = 0, targetTypes_3 = targetTypes; _d < targetTypes_3.length; _d++) { var t = targetTypes_3[_d]; if (getInferenceInfoForType(t)) { typeVariable = t; typeVariableCount++; } else { inferFromTypes(source, t); } } // Next, if target containings a single naked type variable, make a secondary inference to that type // variable. This gives meaningful results for union types in co-variant positions and intersection // types in contra-variant positions (such as callback parameters). if (typeVariableCount === 1) { var savePriority = priority; priority |= 2 /* NakedTypeVariable */; inferFromTypes(source, typeVariable); priority = savePriority; } } else if (source.flags & 131072 /* Union */) { // Source is a union or intersection type, infer from each constituent type var sourceTypes = source.types; for (var _e = 0, sourceTypes_3 = sourceTypes; _e < sourceTypes_3.length; _e++) { var sourceType = sourceTypes_3[_e]; inferFromTypes(sourceType, target); } } else { source = getApparentType(source); if (source.flags & (65536 /* Object */ | 262144 /* Intersection */)) { var key = source.id + "," + target.id; if (visited && visited.get(key)) { return; } (visited || (visited = ts.createMap())).set(key, true); // If we are already processing another target type with the same associated symbol (such as // an instantiation of the same generic type), we do not explore this target as it would yield // no further inferences. We exclude the static side of classes from this check since it shares // its symbol with the instance side which would lead to false positives. var isNonConstructorObject = target.flags & 65536 /* Object */ && !(ts.getObjectFlags(target) & 16 /* Anonymous */ && target.symbol && target.symbol.flags & 32 /* Class */); var symbol = isNonConstructorObject ? target.symbol : undefined; if (symbol) { if (ts.contains(symbolStack, symbol)) { return; } (symbolStack || (symbolStack = [])).push(symbol); inferFromObjectTypes(source, target); symbolStack.pop(); } else { inferFromObjectTypes(source, target); } } } } function inferFromContravariantTypes(source, target) { if (strictFunctionTypes) { priority ^= 1 /* Contravariant */; inferFromTypes(source, target); priority ^= 1 /* Contravariant */; } else { inferFromTypes(source, target); } } function getInferenceInfoForType(type) { if (type.flags & 1081344 /* TypeVariable */) { for (var _i = 0, inferences_1 = inferences; _i < inferences_1.length; _i++) { var inference = inferences_1[_i]; if (type === inference.typeParameter) { return inference; } } } return undefined; } function inferFromObjectTypes(source, target) { if (isGenericMappedType(source) && isGenericMappedType(target)) { // The source and target types are generic types { [P in S]: X } and { [P in T]: Y }, so we infer // from S to T and from X to Y. inferFromTypes(getConstraintTypeFromMappedType(source), getConstraintTypeFromMappedType(target)); inferFromTypes(getTemplateTypeFromMappedType(source), getTemplateTypeFromMappedType(target)); } if (ts.getObjectFlags(target) & 32 /* Mapped */) { var constraintType = getConstraintTypeFromMappedType(target); if (constraintType.flags & 524288 /* Index */) { // We're inferring from some source type S to a homomorphic mapped type { [P in keyof T]: X }, // where T is a type variable. Use inferTypeForHomomorphicMappedType to infer a suitable source // type and then make a secondary inference from that type to T. We make a secondary inference // such that direct inferences to T get priority over inferences to Partial, for example. var inference = getInferenceInfoForType(constraintType.type); if (inference && !inference.isFixed) { var key = (source.symbol ? getSymbolId(source.symbol) + "," : "") + getSymbolId(target.symbol); if (ts.contains(mappedTypeStack, key)) { return; } (mappedTypeStack || (mappedTypeStack = [])).push(key); var inferredType = inferTypeForHomomorphicMappedType(source, target, mappedTypeStack); mappedTypeStack.pop(); if (inferredType) { var savePriority = priority; priority |= 4 /* MappedType */; inferFromTypes(inferredType, inference.typeParameter); priority = savePriority; } } return; } if (constraintType.flags & 32768 /* TypeParameter */) { // We're inferring from some source type S to a mapped type { [P in T]: X }, where T is a type // parameter. Infer from 'keyof S' to T and infer from a union of each property type in S to X. inferFromTypes(getIndexType(source), constraintType); inferFromTypes(getUnionType(ts.map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(target)); return; } } // Infer from the members of source and target only if the two types are possibly related. We check // in both directions because we may be inferring for a co-variant or a contra-variant position. if (!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) || !getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false)) { inferFromProperties(source, target); inferFromSignatures(source, target, 0 /* Call */); inferFromSignatures(source, target, 1 /* Construct */); inferFromIndexTypes(source, target); } } function inferFromProperties(source, target) { var properties = getPropertiesOfObjectType(target); for (var _i = 0, properties_6 = properties; _i < properties_6.length; _i++) { var targetProp = properties_6[_i]; var sourceProp = getPropertyOfType(source, targetProp.escapedName); if (sourceProp) { inferFromTypes(getTypeOfSymbol(sourceProp), getTypeOfSymbol(targetProp)); } } } function inferFromSignatures(source, target, kind) { var sourceSignatures = getSignaturesOfType(source, kind); var targetSignatures = getSignaturesOfType(target, kind); var sourceLen = sourceSignatures.length; var targetLen = targetSignatures.length; var len = sourceLen < targetLen ? sourceLen : targetLen; for (var i = 0; i < len; i++) { inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i])); } } function inferFromSignature(source, target) { forEachMatchingParameterType(source, target, inferFromContravariantTypes); if (source.typePredicate && target.typePredicate && source.typePredicate.kind === target.typePredicate.kind) { inferFromTypes(source.typePredicate.type, target.typePredicate.type); } else { inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } } function inferFromIndexTypes(source, target) { var targetStringIndexType = getIndexTypeOfType(target, 0 /* String */); if (targetStringIndexType) { var sourceIndexType = getIndexTypeOfType(source, 0 /* String */) || getImplicitIndexTypeOfType(source, 0 /* String */); if (sourceIndexType) { inferFromTypes(sourceIndexType, targetStringIndexType); } } var targetNumberIndexType = getIndexTypeOfType(target, 1 /* Number */); if (targetNumberIndexType) { var sourceIndexType = getIndexTypeOfType(source, 1 /* Number */) || getIndexTypeOfType(source, 0 /* String */) || getImplicitIndexTypeOfType(source, 1 /* Number */); if (sourceIndexType) { inferFromTypes(sourceIndexType, targetNumberIndexType); } } } } function typeIdenticalToSomeType(type, types) { for (var _i = 0, types_12 = types; _i < types_12.length; _i++) { var t = types_12[_i]; if (isTypeIdenticalTo(t, type)) { return true; } } return false; } /** * Return a new union or intersection type computed by removing a given set of types * from a given union or intersection type. */ function removeTypesFromUnionOrIntersection(type, typesToRemove) { var reducedTypes = []; for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var t = _a[_i]; if (!typeIdenticalToSomeType(t, typesToRemove)) { reducedTypes.push(t); } } return type.flags & 131072 /* Union */ ? getUnionType(reducedTypes) : getIntersectionType(reducedTypes); } function hasPrimitiveConstraint(type) { var constraint = getConstraintOfTypeParameter(type); return constraint && maybeTypeOfKind(constraint, 16382 /* Primitive */ | 524288 /* Index */); } function isObjectLiteralType(type) { return !!(ts.getObjectFlags(type) & 128 /* ObjectLiteral */); } function widenObjectLiteralCandidates(candidates) { if (candidates.length > 1) { var objectLiterals = ts.filter(candidates, isObjectLiteralType); if (objectLiterals.length) { var objectLiteralsType = getWidenedType(getUnionType(objectLiterals, /*subtypeReduction*/ true)); return ts.concatenate(ts.filter(candidates, function (t) { return !isObjectLiteralType(t); }), [objectLiteralsType]); } } return candidates; } function getInferredType(context, index) { var inference = context.inferences[index]; var inferredType = inference.inferredType; if (!inferredType) { if (inference.candidates) { // Extract all object literal types and replace them with a single widened and normalized type. var candidates = widenObjectLiteralCandidates(inference.candidates); // We widen inferred literal types if // all inferences were made to top-level ocurrences of the type parameter, and // the type parameter has no constraint or its constraint includes no primitive or literal types, and // the type parameter was fixed during inference or does not occur at top-level in the return type. var signature = context.signature; var widenLiteralTypes = inference.topLevel && !hasPrimitiveConstraint(inference.typeParameter) && (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); var baseCandidates = widenLiteralTypes ? ts.sameMap(candidates, getWidenedLiteralType) : candidates; // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. var unwidenedType = inference.priority & 1 /* Contravariant */ ? getCommonSubtype(baseCandidates) : context.flags & 1 /* InferUnionTypes */ || inference.priority & 8 /* ReturnType */ ? getUnionType(baseCandidates, /*subtypeReduction*/ true) : getCommonSupertype(baseCandidates); inferredType = getWidenedType(unwidenedType); } else if (context.flags & 2 /* NoDefault */) { // We use silentNeverType as the wildcard that signals no inferences. inferredType = silentNeverType; } else { // Infer either the default or the empty object type when no inferences were // made. It is important to remember that in this case, inference still // succeeds, meaning there is no error for not having inference candidates. An // inference error only occurs when there are *conflicting* candidates, i.e. // candidates with no common supertype. var defaultType = getDefaultFromTypeParameter(inference.typeParameter); if (defaultType) { // Instantiate the default type. Any forward reference to a type // parameter should be instantiated to the empty object type. inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context.signature.typeParameters, index), context)); } else { inferredType = getDefaultTypeArgumentType(!!(context.flags & 4 /* AnyDefault */)); } } inferredType = getWidenedUniqueESSymbolType(inferredType); inference.inferredType = inferredType; var constraint = getConstraintOfTypeParameter(context.signature.typeParameters[index]); if (constraint) { var instantiatedConstraint = instantiateType(constraint, context); if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = getWidenedUniqueESSymbolType(instantiatedConstraint); } } } return inferredType; } function getDefaultTypeArgumentType(isInJavaScriptFile) { return isInJavaScriptFile ? anyType : emptyObjectType; } function getInferredTypes(context) { var result = []; for (var i = 0; i < context.inferences.length; i++) { result.push(getInferredType(context, i)); } return result; } // EXPRESSION TYPE CHECKING function getResolvedSymbol(node) { var links = getNodeLinks(node); if (!links.resolvedSymbol) { links.resolvedSymbol = !ts.nodeIsMissing(node) && resolveName(node, node.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */, ts.Diagnostics.Cannot_find_name_0, node, !ts.isWriteOnlyAccess(node), ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1) || unknownSymbol; } return links.resolvedSymbol; } function isInTypeQuery(node) { // TypeScript 1.0 spec (April 2014): 3.6.3 // A type query consists of the keyword typeof followed by an expression. // The expression is restricted to a single identifier or a sequence of identifiers separated by periods return !!ts.findAncestor(node, function (n) { return n.kind === 163 /* TypeQuery */ ? true : n.kind === 71 /* Identifier */ || n.kind === 144 /* QualifiedName */ ? false : "quit"; }); } // Return the flow cache key for a "dotted name" (i.e. a sequence of identifiers // separated by dots). The key consists of the id of the symbol referenced by the // leftmost identifier followed by zero or more property names separated by dots. // The result is undefined if the reference isn't a dotted name. We prefix nodes // occurring in an apparent type position with '@' because the control flow type // of such nodes may be based on the apparent type instead of the declared type. function getFlowCacheKey(node) { if (node.kind === 71 /* Identifier */) { var symbol = getResolvedSymbol(node); return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined; } if (node.kind === 99 /* ThisKeyword */) { return "0"; } if (node.kind === 180 /* PropertyAccessExpression */) { var key = getFlowCacheKey(node.expression); return key && key + "." + ts.idText(node.name); } if (node.kind === 177 /* BindingElement */) { var container = node.parent.parent; var key = container.kind === 177 /* BindingElement */ ? getFlowCacheKey(container) : (container.initializer && getFlowCacheKey(container.initializer)); var text = getBindingElementNameText(node); var result = key && text && (key + "." + text); return result; } return undefined; } function getBindingElementNameText(element) { if (element.parent.kind === 175 /* ObjectBindingPattern */) { var name = element.propertyName || element.name; switch (name.kind) { case 71 /* Identifier */: return ts.idText(name); case 145 /* ComputedPropertyName */: return ts.isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined; case 9 /* StringLiteral */: case 8 /* NumericLiteral */: return name.text; default: // Per types, array and object binding patterns remain, however they should never be present if propertyName is not defined ts.Debug.fail("Unexpected name kind for binding element name"); } } else { return "" + element.parent.elements.indexOf(element); } } function isMatchingReference(source, target) { switch (source.kind) { case 71 /* Identifier */: return target.kind === 71 /* Identifier */ && getResolvedSymbol(source) === getResolvedSymbol(target) || (target.kind === 227 /* VariableDeclaration */ || target.kind === 177 /* BindingElement */) && getExportSymbolOfValueSymbolIfExported(getResolvedSymbol(source)) === getSymbolOfNode(target); case 99 /* ThisKeyword */: return target.kind === 99 /* ThisKeyword */; case 97 /* SuperKeyword */: return target.kind === 97 /* SuperKeyword */; case 180 /* PropertyAccessExpression */: return target.kind === 180 /* PropertyAccessExpression */ && source.name.escapedText === target.name.escapedText && isMatchingReference(source.expression, target.expression); case 177 /* BindingElement */: if (target.kind !== 180 /* PropertyAccessExpression */) return false; var t = target; if (t.name.escapedText !== getBindingElementNameText(source)) return false; if (source.parent.parent.kind === 177 /* BindingElement */ && isMatchingReference(source.parent.parent, t.expression)) { return true; } if (source.parent.parent.kind === 227 /* VariableDeclaration */) { var maybeId = source.parent.parent.initializer; return maybeId && isMatchingReference(maybeId, t.expression); } } return false; } function containsMatchingReference(source, target) { while (source.kind === 180 /* PropertyAccessExpression */) { source = source.expression; if (isMatchingReference(source, target)) { return true; } } return false; } // Return true if target is a property access xxx.yyy, source is a property access xxx.zzz, the declared // type of xxx is a union type, and yyy is a property that is possibly a discriminant. We consider a property // a possible discriminant if its type differs in the constituents of containing union type, and if every // choice is a unit type or a union of unit types. function containsMatchingReferenceDiscriminant(source, target) { return target.kind === 180 /* PropertyAccessExpression */ && containsMatchingReference(source, target.expression) && isDiscriminantProperty(getDeclaredTypeOfReference(target.expression), target.name.escapedText); } function getDeclaredTypeOfReference(expr) { if (expr.kind === 71 /* Identifier */) { return getTypeOfSymbol(getResolvedSymbol(expr)); } if (expr.kind === 180 /* PropertyAccessExpression */) { var type = getDeclaredTypeOfReference(expr.expression); return type && getTypeOfPropertyOfType(type, expr.name.escapedText); } return undefined; } function isDiscriminantProperty(type, name) { if (type && type.flags & 131072 /* Union */) { var prop = getUnionOrIntersectionProperty(type, name); if (prop && ts.getCheckFlags(prop) & 2 /* SyntheticProperty */) { if (prop.isDiscriminantProperty === undefined) { prop.isDiscriminantProperty = prop.checkFlags & 32 /* HasNonUniformType */ && isLiteralType(getTypeOfSymbol(prop)); } return prop.isDiscriminantProperty; } } return false; } function findDiscriminantProperties(sourceProperties, target) { var result; for (var _i = 0, sourceProperties_2 = sourceProperties; _i < sourceProperties_2.length; _i++) { var sourceProperty = sourceProperties_2[_i]; if (isDiscriminantProperty(target, sourceProperty.escapedName)) { if (result) { result.push(sourceProperty); continue; } result = [sourceProperty]; } } return result; } function isOrContainsMatchingReference(source, target) { return isMatchingReference(source, target) || containsMatchingReference(source, target); } function hasMatchingArgument(callExpression, reference) { if (callExpression.arguments) { for (var _i = 0, _a = callExpression.arguments; _i < _a.length; _i++) { var argument = _a[_i]; if (isOrContainsMatchingReference(reference, argument)) { return true; } } } if (callExpression.expression.kind === 180 /* 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 & 131072 /* Union */)) { return isTypeAssignableTo(source, target); } for (var _i = 0, _a = source.types; _i < _a.length; _i++) { var t = _a[_i]; if (isTypeAssignableTo(t, target)) { return true; } } return false; } // Remove those constituent types of declaredType to which no constituent type of assignedType is assignable. // For example, when a variable of type number | string | boolean is assigned a value of type number | boolean, // we remove type string. function getAssignmentReducedType(declaredType, assignedType) { if (declaredType !== assignedType) { if (assignedType.flags & 16384 /* Never */) { return assignedType; } var reducedType = filterType(declaredType, function (t) { return typeMaybeAssignableTo(assignedType, t); }); if (!(reducedType.flags & 16384 /* Never */)) { return reducedType; } } return declaredType; } function getTypeFactsOfTypes(types) { var result = 0 /* None */; for (var _i = 0, types_13 = types; _i < types_13.length; _i++) { var t = types_13[_i]; result |= getTypeFacts(t); } return result; } function isFunctionObjectType(type) { // We do a quick check for a "bind" property before performing the more expensive subtype // check. This gives us a quicker out in the common case where an object type is not a function. var resolved = resolveStructuredTypeMembers(type); return !!(resolved.callSignatures.length || resolved.constructSignatures.length || resolved.members.get("bind") && isTypeSubtypeOf(type, globalFunctionType)); } function getTypeFacts(type) { var flags = type.flags; if (flags & 2 /* String */) { return strictNullChecks ? 4079361 /* StringStrictFacts */ : 4194049 /* StringFacts */; } if (flags & 32 /* StringLiteral */) { var isEmpty = type.value === ""; return strictNullChecks ? isEmpty ? 3030785 /* EmptyStringStrictFacts */ : 1982209 /* NonEmptyStringStrictFacts */ : isEmpty ? 3145473 /* EmptyStringFacts */ : 4194049 /* NonEmptyStringFacts */; } if (flags & (4 /* Number */ | 16 /* Enum */)) { return strictNullChecks ? 4079234 /* NumberStrictFacts */ : 4193922 /* NumberFacts */; } if (flags & 64 /* NumberLiteral */) { var isZero = type.value === 0; return strictNullChecks ? isZero ? 3030658 /* ZeroStrictFacts */ : 1982082 /* NonZeroStrictFacts */ : isZero ? 3145346 /* ZeroFacts */ : 4193922 /* NonZeroFacts */; } if (flags & 8 /* Boolean */) { return strictNullChecks ? 4078980 /* BooleanStrictFacts */ : 4193668 /* BooleanFacts */; } if (flags & 136 /* BooleanLike */) { return strictNullChecks ? type === falseType ? 3030404 /* FalseStrictFacts */ : 1981828 /* TrueStrictFacts */ : type === falseType ? 3145092 /* FalseFacts */ : 4193668 /* TrueFacts */; } if (flags & 65536 /* Object */) { return isFunctionObjectType(type) ? strictNullChecks ? 6164448 /* FunctionStrictFacts */ : 8376288 /* FunctionFacts */ : strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */; } if (flags & (2048 /* Void */ | 4096 /* Undefined */)) { return 2457472 /* UndefinedFacts */; } if (flags & 8192 /* Null */) { return 2340752 /* NullFacts */; } if (flags & 1536 /* ESSymbolLike */) { return strictNullChecks ? 1981320 /* SymbolStrictFacts */ : 4193160 /* SymbolFacts */; } if (flags & 33554432 /* NonPrimitive */) { return strictNullChecks ? 6166480 /* ObjectStrictFacts */ : 8378320 /* ObjectFacts */; } if (flags & 1081344 /* TypeVariable */) { return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType); } if (flags & 393216 /* UnionOrIntersection */) { return getTypeFactsOfTypes(type.types); } return 8388607 /* All */; } function getTypeWithFacts(type, include) { if (type.flags & 1048576 /* IndexedAccess */) { // TODO (weswig): This is a substitute for a lazy negated type to remove the types indicated by the TypeFacts from the (potential) union the IndexedAccess refers to // - See discussion in https://github.com/Microsoft/TypeScript/pull/19275 for details, and test `strictNullNotNullIndexTypeShouldWork` for current behavior var baseConstraint = getBaseConstraintOfType(type) || emptyObjectType; var result = filterType(baseConstraint, function (t) { return (getTypeFacts(t) & include) !== 0; }); if (result !== baseConstraint) { return result; } return type; } return filterType(type, function (t) { return (getTypeFacts(t) & include) !== 0; }); } function getTypeWithDefault(type, defaultExpression) { if (defaultExpression) { var defaultType = getTypeOfExpression(defaultExpression); return getUnionType([getTypeWithFacts(type, 131072 /* NEUndefined */), defaultType]); } return type; } function getTypeOfDestructuredProperty(type, name) { var text = ts.getTextOfPropertyName(name); return getTypeOfPropertyOfType(type, text) || isNumericLiteralName(text) && getIndexTypeOfType(type, 1 /* Number */) || getIndexTypeOfType(type, 0 /* String */) || unknownType; } function getTypeOfDestructuredArrayElement(type, index) { return isTupleLikeType(type) && getTypeOfPropertyOfType(type, "" + index) || checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; } function getTypeOfDestructuredSpreadExpression(type) { return createArrayType(checkIteratedTypeOrElementType(type, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType); } function getAssignedTypeOfBinaryExpression(node) { var isDestructuringDefaultAssignment = node.parent.kind === 178 /* ArrayLiteralExpression */ && isDestructuringAssignmentTarget(node.parent) || node.parent.kind === 265 /* PropertyAssignment */ && isDestructuringAssignmentTarget(node.parent.parent); return isDestructuringDefaultAssignment ? getTypeWithDefault(getAssignedType(node), node.right) : getTypeOfExpression(node.right); } function isDestructuringAssignmentTarget(parent) { return parent.parent.kind === 195 /* BinaryExpression */ && parent.parent.left === parent || parent.parent.kind === 217 /* ForOfStatement */ && parent.parent.initializer === parent; } function getAssignedTypeOfArrayLiteralElement(node, element) { return getTypeOfDestructuredArrayElement(getAssignedType(node), ts.indexOf(node.elements, element)); } function getAssignedTypeOfSpreadExpression(node) { return getTypeOfDestructuredSpreadExpression(getAssignedType(node.parent)); } function getAssignedTypeOfPropertyAssignment(node) { return getTypeOfDestructuredProperty(getAssignedType(node.parent), node.name); } function getAssignedTypeOfShorthandPropertyAssignment(node) { return getTypeWithDefault(getAssignedTypeOfPropertyAssignment(node), node.objectAssignmentInitializer); } function getAssignedType(node) { var parent = node.parent; switch (parent.kind) { case 216 /* ForInStatement */: return stringType; case 217 /* ForOfStatement */: return checkRightHandSideOfForOf(parent.expression, parent.awaitModifier) || unknownType; case 195 /* BinaryExpression */: return getAssignedTypeOfBinaryExpression(parent); case 189 /* DeleteExpression */: return undefinedType; case 178 /* ArrayLiteralExpression */: return getAssignedTypeOfArrayLiteralElement(parent, node); case 199 /* SpreadElement */: return getAssignedTypeOfSpreadExpression(parent); case 265 /* PropertyAssignment */: return getAssignedTypeOfPropertyAssignment(parent); case 266 /* ShorthandPropertyAssignment */: return getAssignedTypeOfShorthandPropertyAssignment(parent); } return unknownType; } function getInitialTypeOfBindingElement(node) { var pattern = node.parent; var parentType = getInitialType(pattern.parent); var type = pattern.kind === 175 /* ObjectBindingPattern */ ? getTypeOfDestructuredProperty(parentType, node.propertyName || node.name) : !node.dotDotDotToken ? getTypeOfDestructuredArrayElement(parentType, ts.indexOf(pattern.elements, node)) : getTypeOfDestructuredSpreadExpression(parentType); return getTypeWithDefault(type, node.initializer); } function getTypeOfInitializer(node) { // Return the cached type if one is available. If the type of the variable was inferred // from its initializer, we'll already have cached the type. Otherwise we compute it now // without caching such that transient types are reflected. var links = getNodeLinks(node); return links.resolvedType || getTypeOfExpression(node); } function getInitialTypeOfVariableDeclaration(node) { if (node.initializer) { return getTypeOfInitializer(node.initializer); } if (node.parent.parent.kind === 216 /* ForInStatement */) { return stringType; } if (node.parent.parent.kind === 217 /* ForOfStatement */) { return checkRightHandSideOfForOf(node.parent.parent.expression, node.parent.parent.awaitModifier) || unknownType; } return unknownType; } function getInitialType(node) { return node.kind === 227 /* VariableDeclaration */ ? getInitialTypeOfVariableDeclaration(node) : getInitialTypeOfBindingElement(node); } function getInitialOrAssignedType(node) { return node.kind === 227 /* VariableDeclaration */ || node.kind === 177 /* BindingElement */ ? getInitialType(node) : getAssignedType(node); } function isEmptyArrayAssignment(node) { return node.kind === 227 /* VariableDeclaration */ && node.initializer && isEmptyArrayLiteral(node.initializer) || node.kind !== 177 /* BindingElement */ && node.parent.kind === 195 /* BinaryExpression */ && isEmptyArrayLiteral(node.parent.right); } function getReferenceCandidate(node) { switch (node.kind) { case 186 /* ParenthesizedExpression */: return getReferenceCandidate(node.expression); case 195 /* BinaryExpression */: switch (node.operatorToken.kind) { case 58 /* EqualsToken */: return getReferenceCandidate(node.left); case 26 /* CommaToken */: return getReferenceCandidate(node.right); } } return node; } function getReferenceRoot(node) { var parent = node.parent; return parent.kind === 186 /* ParenthesizedExpression */ || parent.kind === 195 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */ && parent.left === node || parent.kind === 195 /* BinaryExpression */ && parent.operatorToken.kind === 26 /* CommaToken */ && parent.right === node ? getReferenceRoot(parent) : node; } function getTypeOfSwitchClause(clause) { if (clause.kind === 261 /* CaseClause */) { var caseType = getRegularTypeOfLiteralType(getTypeOfExpression(clause.expression)); return isUnitType(caseType) ? caseType : undefined; } return neverType; } function getSwitchClauseTypes(switchStatement) { var links = getNodeLinks(switchStatement); if (!links.switchTypes) { // If all case clauses specify expressions that have unit types, we return an array // of those unit types. Otherwise we return an empty array. links.switchTypes = []; for (var _i = 0, _a = switchStatement.caseBlock.clauses; _i < _a.length; _i++) { var clause = _a[_i]; var type = getTypeOfSwitchClause(clause); if (type === undefined) { return links.switchTypes = ts.emptyArray; } links.switchTypes.push(type); } } return links.switchTypes; } function eachTypeContainedIn(source, types) { return source.flags & 131072 /* Union */ ? !ts.forEach(source.types, function (t) { return !ts.contains(types, t); }) : ts.contains(types, source); } function isTypeSubsetOf(source, target) { return source === target || target.flags & 131072 /* Union */ && isTypeSubsetOfUnion(source, target); } function isTypeSubsetOfUnion(source, target) { if (source.flags & 131072 /* Union */) { for (var _i = 0, _a = source.types; _i < _a.length; _i++) { var t = _a[_i]; if (!containsType(target.types, t)) { return false; } } return true; } if (source.flags & 256 /* EnumLiteral */ && getBaseTypeOfEnumLiteralType(source) === target) { return true; } return containsType(target.types, source); } function forEachType(type, f) { return type.flags & 131072 /* Union */ ? ts.forEach(type.types, f) : f(type); } function filterType(type, f) { if (type.flags & 131072 /* Union */) { var types = type.types; var filtered = ts.filter(types, f); return filtered === types ? type : getUnionTypeFromSortedList(filtered); } return f(type) ? type : neverType; } // Apply a mapping function to a type and return the resulting type. If the source type // is a union type, the mapping function is applied to each constituent type and a union // of the resulting types is returned. function mapType(type, mapper) { if (!(type.flags & 131072 /* Union */)) { return mapper(type); } var types = type.types; var mappedType; var mappedTypes; for (var _i = 0, types_14 = types; _i < types_14.length; _i++) { var current = types_14[_i]; var t = mapper(current); if (t) { if (!mappedType) { mappedType = t; } else if (!mappedTypes) { mappedTypes = [mappedType, t]; } else { mappedTypes.push(t); } } } return mappedTypes ? getUnionType(mappedTypes) : mappedType; } function extractTypesOfKind(type, kind) { return filterType(type, function (t) { return (t.flags & kind) !== 0; }); } // Return a new type in which occurrences of the string and number primitive types in // typeWithPrimitives have been replaced with occurrences of string literals and numeric // literals in typeWithLiterals, respectively. function replacePrimitivesWithLiterals(typeWithPrimitives, typeWithLiterals) { if (isTypeSubsetOf(stringType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 32 /* StringLiteral */) || isTypeSubsetOf(numberType, typeWithPrimitives) && maybeTypeOfKind(typeWithLiterals, 64 /* NumberLiteral */)) { return mapType(typeWithPrimitives, function (t) { return t.flags & 2 /* String */ ? extractTypesOfKind(typeWithLiterals, 2 /* String */ | 32 /* StringLiteral */) : t.flags & 4 /* Number */ ? extractTypesOfKind(typeWithLiterals, 4 /* Number */ | 64 /* NumberLiteral */) : t; }); } return typeWithPrimitives; } function isIncomplete(flowType) { return flowType.flags === 0; } function getTypeFromFlowType(flowType) { return flowType.flags === 0 ? flowType.type : flowType; } function createFlowType(type, incomplete) { return incomplete ? { flags: 0, type: type } : type; } // An evolving array type tracks the element types that have so far been seen in an // 'x.push(value)' or 'x[n] = value' operation along the control flow graph. Evolving // array types are ultimately converted into manifest array types (using getFinalArrayType) // and never escape the getFlowTypeOfReference function. function createEvolvingArrayType(elementType) { var result = createObjectType(256 /* EvolvingArray */); result.elementType = elementType; return result; } function getEvolvingArrayType(elementType) { return evolvingArrayTypes[elementType.id] || (evolvingArrayTypes[elementType.id] = createEvolvingArrayType(elementType)); } // When adding evolving array element types we do not perform subtype reduction. Instead, // we defer subtype reduction until the evolving array type is finalized into a manifest // array type. function addEvolvingArrayElementType(evolvingArrayType, node) { var elementType = getBaseTypeOfLiteralType(getContextFreeTypeOfExpression(node)); return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType])); } function createFinalArrayType(elementType) { return elementType.flags & 16384 /* Never */ ? autoArrayType : createArrayType(elementType.flags & 131072 /* Union */ ? getUnionType(elementType.types, /*subtypeReduction*/ true) : elementType); } // We perform subtype reduction upon obtaining the final array type from an evolving array type. function getFinalArrayType(evolvingArrayType) { return evolvingArrayType.finalArrayType || (evolvingArrayType.finalArrayType = createFinalArrayType(evolvingArrayType.elementType)); } function finalizeEvolvingArrayType(type) { return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? getFinalArrayType(type) : type; } function getElementTypeOfEvolvingArrayType(type) { return ts.getObjectFlags(type) & 256 /* EvolvingArray */ ? type.elementType : neverType; } function isEvolvingArrayTypeList(types) { var hasEvolvingArrayType = false; for (var _i = 0, types_15 = types; _i < types_15.length; _i++) { var t = types_15[_i]; if (!(t.flags & 16384 /* Never */)) { if (!(ts.getObjectFlags(t) & 256 /* EvolvingArray */)) { return false; } hasEvolvingArrayType = true; } } return hasEvolvingArrayType; } // At flow control branch or loop junctions, if the type along every antecedent code path // is an evolving array type, we construct a combined evolving array type. Otherwise we // finalize all evolving array types. function getUnionOrEvolvingArrayType(types, subtypeReduction) { return isEvolvingArrayTypeList(types) ? getEvolvingArrayType(getUnionType(ts.map(types, getElementTypeOfEvolvingArrayType))) : getUnionType(ts.sameMap(types, finalizeEvolvingArrayType), subtypeReduction); } // Return true if the given node is 'x' in an 'x.length', x.push(value)', 'x.unshift(value)' or // 'x[n] = value' operation, where 'n' is an expression of type any, undefined, or a number-like type. function isEvolvingArrayOperationTarget(node) { var root = getReferenceRoot(node); var parent = root.parent; var isLengthPushOrUnshift = parent.kind === 180 /* PropertyAccessExpression */ && (parent.name.escapedText === "length" || parent.parent.kind === 182 /* CallExpression */ && ts.isPushOrUnshiftIdentifier(parent.name)); var isElementAssignment = parent.kind === 181 /* ElementAccessExpression */ && parent.expression === root && parent.parent.kind === 195 /* BinaryExpression */ && parent.parent.operatorToken.kind === 58 /* EqualsToken */ && parent.parent.left === parent && !ts.isAssignmentTarget(parent.parent) && isTypeAssignableToKind(getTypeOfExpression(parent.argumentExpression), 84 /* NumberLike */); return isLengthPushOrUnshift || isElementAssignment; } function maybeTypePredicateCall(node) { var links = getNodeLinks(node); if (links.maybeTypePredicate === undefined) { links.maybeTypePredicate = getMaybeTypePredicate(node); } return links.maybeTypePredicate; } function getMaybeTypePredicate(node) { if (node.expression.kind !== 97 /* SuperKeyword */) { var funcType = checkNonNullExpression(node.expression); if (funcType !== silentNeverType) { var apparentType = getApparentType(funcType); if (apparentType !== unknownType) { var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */); return !!ts.forEach(callSignatures, function (sig) { return sig.typePredicate; }); } } } return false; } function reportFlowControlError(node) { var block = ts.findAncestor(node, ts.isFunctionOrModuleBlock); var sourceFile = ts.getSourceFileOfNode(node); var span = ts.getSpanOfTokenAtPosition(sourceFile, block.statements.pos); diagnostics.add(ts.createFileDiagnostic(sourceFile, span.start, span.length, ts.Diagnostics.The_containing_function_or_module_body_is_too_large_for_control_flow_analysis)); } function getFlowTypeOfReference(reference, declaredType, initialType, flowContainer, couldBeUninitialized) { if (initialType === void 0) { initialType = declaredType; } var key; var flowDepth = 0; if (flowAnalysisDisabled) { return unknownType; } if (!reference.flowNode || !couldBeUninitialized && !(declaredType.flags & 35620607 /* Narrowable */)) { return declaredType; } var sharedFlowStart = sharedFlowCount; var evolvedType = getTypeFromFlowType(getTypeAtFlowNode(reference.flowNode)); sharedFlowCount = sharedFlowStart; // When the reference is 'x' in an 'x.length', 'x.push(value)', 'x.unshift(value)' or x[n] = value' operation, // we give type 'any[]' to 'x' instead of using the type determined by control flow analysis such that operations // on empty arrays are possible without implicit any errors and new element types can be inferred without // type mismatch errors. var resultType = ts.getObjectFlags(evolvedType) & 256 /* EvolvingArray */ && isEvolvingArrayOperationTarget(reference) ? anyArrayType : finalizeEvolvingArrayType(evolvedType); if (reference.parent && reference.parent.kind === 204 /* NonNullExpression */ && getTypeWithFacts(resultType, 524288 /* NEUndefinedOrNull */).flags & 16384 /* Never */) { return declaredType; } return resultType; function getTypeAtFlowNode(flow) { if (flowDepth === 2500) { // We have made 2500 recursive invocations. To avoid overflowing the call stack we report an error // and disable further control flow analysis in the containing function or module body. flowAnalysisDisabled = true; reportFlowControlError(reference); return unknownType; } flowDepth++; while (true) { var flags = flow.flags; if (flags & 1024 /* Shared */) { // We cache results of flow type resolution for shared nodes that were previously visited in // the same getFlowTypeOfReference invocation. A node is considered shared when it is the // antecedent of more than one node. for (var i = sharedFlowStart; i < sharedFlowCount; i++) { if (sharedFlowNodes[i] === flow) { flowDepth--; return sharedFlowTypes[i]; } } } var type = void 0; if (flags & 4096 /* AfterFinally */) { // block flow edge: finally -> pre-try (for larger explanation check comment in binder.ts - bindTryStatement flow.locked = true; type = getTypeAtFlowNode(flow.antecedent); flow.locked = false; } else if (flags & 2048 /* PreFinally */) { // locked pre-finally flows are filtered out in getTypeAtFlowBranchLabel // so here just redirect to antecedent flow = flow.antecedent; continue; } else if (flags & 16 /* Assignment */) { type = getTypeAtFlowAssignment(flow); if (!type) { flow = flow.antecedent; continue; } } else if (flags & 96 /* Condition */) { type = getTypeAtFlowCondition(flow); } else if (flags & 128 /* SwitchClause */) { type = getTypeAtSwitchClause(flow); } else if (flags & 12 /* Label */) { if (flow.antecedents.length === 1) { flow = flow.antecedents[0]; continue; } type = flags & 4 /* BranchLabel */ ? getTypeAtFlowBranchLabel(flow) : getTypeAtFlowLoopLabel(flow); } else if (flags & 256 /* ArrayMutation */) { type = getTypeAtFlowArrayMutation(flow); if (!type) { flow = flow.antecedent; continue; } } else if (flags & 2 /* Start */) { // Check if we should continue with the control flow of the containing function. var container = flow.container; if (container && container !== flowContainer && reference.kind !== 180 /* PropertyAccessExpression */ && reference.kind !== 99 /* ThisKeyword */) { flow = container.flowNode; continue; } // At the top of the flow we have the initial type. type = initialType; } else { // Unreachable code errors are reported in the binding phase. Here we // simply return the non-auto declared type to reduce follow-on errors. type = convertAutoToAny(declaredType); } if (flags & 1024 /* Shared */) { // Record visited node and the associated type in the cache. sharedFlowNodes[sharedFlowCount] = flow; sharedFlowTypes[sharedFlowCount] = type; sharedFlowCount++; } flowDepth--; return type; } } function getTypeAtFlowAssignment(flow) { var node = flow.node; // Assignments only narrow the computed type if the declared type is a union type. Thus, we // only need to evaluate the assigned type if the declared type is a union type. if (isMatchingReference(reference, node)) { if (ts.getAssignmentTargetKind(node) === 2 /* Compound */) { var flowType = getTypeAtFlowNode(flow.antecedent); return createFlowType(getBaseTypeOfLiteralType(getTypeFromFlowType(flowType)), isIncomplete(flowType)); } if (declaredType === autoType || declaredType === autoArrayType) { if (isEmptyArrayAssignment(node)) { return getEvolvingArrayType(neverType); } var assignedType = getBaseTypeOfLiteralType(getInitialOrAssignedType(node)); return isTypeAssignableTo(assignedType, declaredType) ? assignedType : anyArrayType; } if (declaredType.flags & 131072 /* Union */) { return getAssignmentReducedType(declaredType, getInitialOrAssignedType(node)); } return declaredType; } // We didn't have a direct match. However, if the reference is a dotted name, this // may be an assignment to a left hand part of the reference. For example, for a // reference 'x.y.z', we may be at an assignment to 'x.y' or 'x'. In that case, // return the declared type. if (containsMatchingReference(reference, node)) { return declaredType; } // Assignment doesn't affect reference return undefined; } function getTypeAtFlowArrayMutation(flow) { if (declaredType === autoType || declaredType === autoArrayType) { var node = flow.node; var expr = node.kind === 182 /* CallExpression */ ? node.expression.expression : node.left.expression; if (isMatchingReference(reference, getReferenceCandidate(expr))) { var flowType = getTypeAtFlowNode(flow.antecedent); var type = getTypeFromFlowType(flowType); if (ts.getObjectFlags(type) & 256 /* EvolvingArray */) { var evolvedType_1 = type; if (node.kind === 182 /* CallExpression */) { for (var _i = 0, _a = node.arguments; _i < _a.length; _i++) { var arg = _a[_i]; evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, arg); } } else { var indexType = getTypeOfExpression(node.left.argumentExpression); if (isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { evolvedType_1 = addEvolvingArrayElementType(evolvedType_1, node.right); } } return evolvedType_1 === type ? flowType : createFlowType(evolvedType_1, isIncomplete(flowType)); } return flowType; } } return undefined; } function getTypeAtFlowCondition(flow) { var flowType = getTypeAtFlowNode(flow.antecedent); var type = getTypeFromFlowType(flowType); if (type.flags & 16384 /* Never */) { return flowType; } // If we have an antecedent type (meaning we're reachable in some way), we first // attempt to narrow the antecedent type. If that produces the never type, and if // the antecedent type is incomplete (i.e. a transient type in a loop), then we // take the type guard as an indication that control *could* reach here once we // have the complete type. We proceed by switching to the silent never type which // doesn't report errors when operators are applied to it. Note that this is the // *only* place a silent never type is ever generated. var assumeTrue = (flow.flags & 32 /* TrueCondition */) !== 0; var nonEvolvingType = finalizeEvolvingArrayType(type); var narrowedType = narrowType(nonEvolvingType, flow.expression, assumeTrue); if (narrowedType === nonEvolvingType) { return flowType; } var incomplete = isIncomplete(flowType); var resultType = incomplete && narrowedType.flags & 16384 /* Never */ ? silentNeverType : narrowedType; return createFlowType(resultType, incomplete); } function getTypeAtSwitchClause(flow) { var flowType = getTypeAtFlowNode(flow.antecedent); var type = getTypeFromFlowType(flowType); var expr = flow.switchStatement.expression; if (isMatchingReference(reference, expr)) { type = narrowTypeBySwitchOnDiscriminant(type, flow.switchStatement, flow.clauseStart, flow.clauseEnd); } else if (isMatchingReferenceDiscriminant(expr, type)) { type = narrowTypeByDiscriminant(type, expr, function (t) { return narrowTypeBySwitchOnDiscriminant(t, flow.switchStatement, flow.clauseStart, flow.clauseEnd); }); } return createFlowType(type, isIncomplete(flowType)); } function getTypeAtFlowBranchLabel(flow) { var antecedentTypes = []; var subtypeReduction = false; var seenIncomplete = false; for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) { var antecedent = _a[_i]; if (antecedent.flags & 2048 /* PreFinally */ && antecedent.lock.locked) { // if flow correspond to branch from pre-try to finally and this branch is locked - this means that // we initially have started following the flow outside the finally block. // in this case we should ignore this branch. continue; } var flowType = getTypeAtFlowNode(antecedent); var type = getTypeFromFlowType(flowType); // If the type at a particular antecedent path is the declared type and the // reference is known to always be assigned (i.e. when declared and initial types // are the same), there is no reason to process more antecedents since the only // possible outcome is subtypes that will be removed in the final union type anyway. if (type === declaredType && declaredType === initialType) { return type; } ts.pushIfUnique(antecedentTypes, type); // If an antecedent type is not a subset of the declared type, we need to perform // subtype reduction. This happens when a "foreign" type is injected into the control // flow using the instanceof operator or a user defined type predicate. if (!isTypeSubsetOf(type, declaredType)) { subtypeReduction = true; } if (isIncomplete(flowType)) { seenIncomplete = true; } } return createFlowType(getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction), seenIncomplete); } function getTypeAtFlowLoopLabel(flow) { // If we have previously computed the control flow type for the reference at // this flow loop junction, return the cached type. var id = getFlowNodeId(flow); var cache = flowLoopCaches[id] || (flowLoopCaches[id] = ts.createMap()); if (!key) { key = getFlowCacheKey(reference); // No cache key is generated when binding patterns are in unnarrowable situations if (!key) { return declaredType; } } var cached = cache.get(key); if (cached) { return cached; } // If this flow loop junction and reference are already being processed, return // the union of the types computed for each branch so far, marked as incomplete. // It is possible to see an empty array in cases where loops are nested and the // back edge of the outer loop reaches an inner loop that is already being analyzed. // In such cases we restart the analysis of the inner loop, which will then see // a non-empty in-process array for the outer loop and eventually terminate because // the first antecedent of a loop junction is always the non-looping control flow // path that leads to the top. for (var i = flowLoopStart; i < flowLoopCount; i++) { if (flowLoopNodes[i] === flow && flowLoopKeys[i] === key && flowLoopTypes[i].length) { return createFlowType(getUnionOrEvolvingArrayType(flowLoopTypes[i], /*subtypeReduction*/ false), /*incomplete*/ true); } } // Add the flow loop junction and reference to the in-process stack and analyze // each antecedent code path. var antecedentTypes = []; var subtypeReduction = false; var firstAntecedentType; flowLoopNodes[flowLoopCount] = flow; flowLoopKeys[flowLoopCount] = key; flowLoopTypes[flowLoopCount] = antecedentTypes; for (var _i = 0, _a = flow.antecedents; _i < _a.length; _i++) { var antecedent = _a[_i]; flowLoopCount++; var flowType = getTypeAtFlowNode(antecedent); flowLoopCount--; if (!firstAntecedentType) { firstAntecedentType = flowType; } var type = getTypeFromFlowType(flowType); // If we see a value appear in the cache it is a sign that control flow analysis // was restarted and completed by checkExpressionCached. We can simply pick up // the resulting type and bail out. var cached_1 = cache.get(key); if (cached_1) { return cached_1; } ts.pushIfUnique(antecedentTypes, type); // If an antecedent type is not a subset of the declared type, we need to perform // subtype reduction. This happens when a "foreign" type is injected into the control // flow using the instanceof operator or a user defined type predicate. if (!isTypeSubsetOf(type, declaredType)) { subtypeReduction = true; } // If the type at a particular antecedent path is the declared type there is no // reason to process more antecedents since the only possible outcome is subtypes // that will be removed in the final union type anyway. if (type === declaredType) { break; } } // The result is incomplete if the first antecedent (the non-looping control flow path) // is incomplete. var result = getUnionOrEvolvingArrayType(antecedentTypes, subtypeReduction); if (isIncomplete(firstAntecedentType)) { return createFlowType(result, /*incomplete*/ true); } cache.set(key, result); return result; } function isMatchingReferenceDiscriminant(expr, computedType) { return expr.kind === 180 /* PropertyAccessExpression */ && computedType.flags & 131072 /* Union */ && isMatchingReference(reference, expr.expression) && isDiscriminantProperty(computedType, expr.name.escapedText); } function narrowTypeByDiscriminant(type, propAccess, narrowType) { var propName = propAccess.name.escapedText; var propType = getTypeOfPropertyOfType(type, propName); var narrowedPropType = propType && narrowType(propType); return propType === narrowedPropType ? type : filterType(type, function (t) { return isTypeComparableTo(getTypeOfPropertyOfType(t, propName), narrowedPropType); }); } function narrowTypeByTruthiness(type, expr, assumeTrue) { if (isMatchingReference(reference, expr)) { return getTypeWithFacts(type, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */); } if (isMatchingReferenceDiscriminant(expr, declaredType)) { return narrowTypeByDiscriminant(type, expr, function (t) { return getTypeWithFacts(t, assumeTrue ? 1048576 /* Truthy */ : 2097152 /* Falsy */); }); } if (containsMatchingReferenceDiscriminant(reference, expr)) { return declaredType; } return type; } function narrowTypeByBinaryExpression(type, expr, assumeTrue) { switch (expr.operatorToken.kind) { case 58 /* EqualsToken */: return narrowTypeByTruthiness(type, expr.left, assumeTrue); case 32 /* EqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: var operator_1 = expr.operatorToken.kind; var left_1 = getReferenceCandidate(expr.left); var right_1 = getReferenceCandidate(expr.right); if (left_1.kind === 190 /* TypeOfExpression */ && right_1.kind === 9 /* StringLiteral */) { return narrowTypeByTypeof(type, left_1, operator_1, right_1, assumeTrue); } if (right_1.kind === 190 /* TypeOfExpression */ && left_1.kind === 9 /* StringLiteral */) { return narrowTypeByTypeof(type, right_1, operator_1, left_1, assumeTrue); } if (isMatchingReference(reference, left_1)) { return narrowTypeByEquality(type, operator_1, right_1, assumeTrue); } if (isMatchingReference(reference, right_1)) { return narrowTypeByEquality(type, operator_1, left_1, assumeTrue); } if (isMatchingReferenceDiscriminant(left_1, declaredType)) { return narrowTypeByDiscriminant(type, left_1, function (t) { return narrowTypeByEquality(t, operator_1, right_1, assumeTrue); }); } if (isMatchingReferenceDiscriminant(right_1, declaredType)) { return narrowTypeByDiscriminant(type, right_1, function (t) { return narrowTypeByEquality(t, operator_1, left_1, assumeTrue); }); } if (containsMatchingReferenceDiscriminant(reference, left_1) || containsMatchingReferenceDiscriminant(reference, right_1)) { return declaredType; } break; case 93 /* InstanceOfKeyword */: return narrowTypeByInstanceof(type, expr, assumeTrue); case 26 /* CommaToken */: return narrowType(type, expr.right, assumeTrue); } return type; } function narrowTypeByEquality(type, operator, value, assumeTrue) { if (type.flags & 1 /* Any */) { return type; } if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) { assumeTrue = !assumeTrue; } var valueType = getTypeOfExpression(value); if (valueType.flags & 12288 /* Nullable */) { if (!strictNullChecks) { return type; } var doubleEquals = operator === 32 /* EqualsEqualsToken */ || operator === 33 /* ExclamationEqualsToken */; var facts = doubleEquals ? assumeTrue ? 65536 /* EQUndefinedOrNull */ : 524288 /* NEUndefinedOrNull */ : value.kind === 95 /* NullKeyword */ ? assumeTrue ? 32768 /* EQNull */ : 262144 /* NENull */ : assumeTrue ? 16384 /* EQUndefined */ : 131072 /* NEUndefined */; return getTypeWithFacts(type, facts); } if (type.flags & 33620481 /* NotUnionOrUnit */) { return type; } if (assumeTrue) { var narrowedType = filterType(type, function (t) { return areTypesComparable(t, valueType); }); return narrowedType.flags & 16384 /* Never */ ? type : replacePrimitivesWithLiterals(narrowedType, valueType); } if (isUnitType(valueType)) { var regularType_1 = getRegularTypeOfLiteralType(valueType); return filterType(type, function (t) { return getRegularTypeOfLiteralType(t) !== regularType_1; }); } return type; } function narrowTypeByTypeof(type, typeOfExpr, operator, literal, assumeTrue) { // We have '==', '!=', '====', or !==' operator with 'typeof xxx' and string literal operands var target = getReferenceCandidate(typeOfExpr.expression); if (!isMatchingReference(reference, target)) { // For a reference of the form 'x.y', a 'typeof x === ...' type guard resets the // narrowed type of 'y' to its declared type. if (containsMatchingReference(reference, target)) { return declaredType; } return type; } if (operator === 33 /* ExclamationEqualsToken */ || operator === 35 /* ExclamationEqualsEqualsToken */) { assumeTrue = !assumeTrue; } if (assumeTrue && !(type.flags & 131072 /* Union */)) { // We narrow a non-union type to an exact primitive type if the non-union type // is a supertype of that primitive type. For example, type 'any' can be narrowed // to one of the primitive types. var targetType = typeofTypesByName.get(literal.text); if (targetType) { if (isTypeSubtypeOf(targetType, type)) { return targetType; } if (type.flags & 1081344 /* TypeVariable */) { var constraint = getBaseConstraintOfType(type) || anyType; if (isTypeSubtypeOf(targetType, constraint)) { return getIntersectionType([type, targetType]); } } } } var facts = assumeTrue ? typeofEQFacts.get(literal.text) || 64 /* TypeofEQHostObject */ : typeofNEFacts.get(literal.text) || 8192 /* TypeofNEHostObject */; return getTypeWithFacts(type, facts); } function narrowTypeBySwitchOnDiscriminant(type, switchStatement, clauseStart, clauseEnd) { // We only narrow if all case expressions specify values with unit types var switchTypes = getSwitchClauseTypes(switchStatement); if (!switchTypes.length) { return type; } var clauseTypes = switchTypes.slice(clauseStart, clauseEnd); var hasDefaultClause = clauseStart === clauseEnd || ts.contains(clauseTypes, neverType); var discriminantType = getUnionType(clauseTypes); var caseType = discriminantType.flags & 16384 /* Never */ ? neverType : replacePrimitivesWithLiterals(filterType(type, function (t) { return isTypeComparableTo(discriminantType, t); }), discriminantType); if (!hasDefaultClause) { return caseType; } var defaultType = filterType(type, function (t) { return !(isUnitType(t) && ts.contains(switchTypes, getRegularTypeOfLiteralType(t))); }); return caseType.flags & 16384 /* Never */ ? defaultType : getUnionType([caseType, defaultType]); } function narrowTypeByInstanceof(type, expr, assumeTrue) { var left = getReferenceCandidate(expr.left); if (!isMatchingReference(reference, left)) { // For a reference of the form 'x.y', an 'x instanceof T' type guard resets the // narrowed type of 'y' to its declared type. if (containsMatchingReference(reference, left)) { return declaredType; } return type; } // Check that right operand is a function type with a prototype property var rightType = getTypeOfExpression(expr.right); if (!isTypeSubtypeOf(rightType, globalFunctionType)) { return type; } var targetType; var prototypeProperty = getPropertyOfType(rightType, "prototype"); if (prototypeProperty) { // Target type is type of the prototype property var prototypePropertyType = getTypeOfSymbol(prototypeProperty); if (!isTypeAny(prototypePropertyType)) { targetType = prototypePropertyType; } } // Don't narrow from 'any' if the target type is exactly 'Object' or 'Function' if (isTypeAny(type) && (targetType === globalObjectType || targetType === globalFunctionType)) { return type; } if (!targetType) { // Target type is type of construct signature var constructSignatures = void 0; if (ts.getObjectFlags(rightType) & 2 /* Interface */) { constructSignatures = resolveDeclaredMembers(rightType).declaredConstructSignatures; } else if (ts.getObjectFlags(rightType) & 16 /* Anonymous */) { constructSignatures = getSignaturesOfType(rightType, 1 /* Construct */); } if (constructSignatures && constructSignatures.length) { targetType = getUnionType(ts.map(constructSignatures, function (signature) { return getReturnTypeOfSignature(getErasedSignature(signature)); })); } } if (targetType) { return getNarrowedType(type, targetType, assumeTrue, isTypeDerivedFrom); } return type; } function getNarrowedType(type, candidate, assumeTrue, isRelated) { if (!assumeTrue) { return filterType(type, function (t) { return !isRelated(t, candidate); }); } // If the current type is a union type, remove all constituents that couldn't be instances of // the candidate type. If one or more constituents remain, return a union of those. if (type.flags & 131072 /* Union */) { var assignableType = filterType(type, function (t) { return isRelated(t, candidate); }); if (!(assignableType.flags & 16384 /* Never */)) { return assignableType; } } // If the candidate type is a subtype of the target type, narrow to the candidate type. // Otherwise, if the target type is assignable to the candidate type, keep the target type. // Otherwise, if the candidate type is assignable to the target type, narrow to the candidate // type. Otherwise, the types are completely unrelated, so narrow to an intersection of the // two types. return isTypeSubtypeOf(candidate, type) ? candidate : isTypeAssignableTo(type, candidate) ? type : isTypeAssignableTo(candidate, type) ? candidate : getIntersectionType([type, candidate]); } function narrowTypeByTypePredicate(type, callExpression, assumeTrue) { if (!hasMatchingArgument(callExpression, reference) || !maybeTypePredicateCall(callExpression)) { return type; } var signature = getResolvedSignature(callExpression); var predicate = signature.typePredicate; if (!predicate) { return type; } // Don't narrow from 'any' if the predicate type is exactly 'Object' or 'Function' if (isTypeAny(type) && (predicate.type === globalObjectType || predicate.type === globalFunctionType)) { return type; } if (ts.isIdentifierTypePredicate(predicate)) { var predicateArgument = callExpression.arguments[predicate.parameterIndex - (signature.thisParameter ? 1 : 0)]; if (predicateArgument) { if (isMatchingReference(reference, predicateArgument)) { return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } if (containsMatchingReference(reference, predicateArgument)) { return declaredType; } } } else { var invokedExpression = ts.skipParentheses(callExpression.expression); if (invokedExpression.kind === 181 /* ElementAccessExpression */ || invokedExpression.kind === 180 /* PropertyAccessExpression */) { var accessExpression = invokedExpression; var possibleReference = ts.skipParentheses(accessExpression.expression); if (isMatchingReference(reference, possibleReference)) { return getNarrowedType(type, predicate.type, assumeTrue, isTypeSubtypeOf); } if (containsMatchingReference(reference, possibleReference)) { return declaredType; } } } return type; } // Narrow the given type based on the given expression having the assumed boolean value. The returned type // will be a subtype or the same type as the argument. function narrowType(type, expr, assumeTrue) { switch (expr.kind) { case 71 /* Identifier */: case 99 /* ThisKeyword */: case 97 /* SuperKeyword */: case 180 /* PropertyAccessExpression */: return narrowTypeByTruthiness(type, expr, assumeTrue); case 182 /* CallExpression */: return narrowTypeByTypePredicate(type, expr, assumeTrue); case 186 /* ParenthesizedExpression */: return narrowType(type, expr.expression, assumeTrue); case 195 /* BinaryExpression */: return narrowTypeByBinaryExpression(type, expr, assumeTrue); case 193 /* PrefixUnaryExpression */: if (expr.operator === 51 /* ExclamationToken */) { return narrowType(type, expr.operand, !assumeTrue); } break; } return type; } } function getTypeOfSymbolAtLocation(symbol, location) { symbol = symbol.exportSymbol || symbol; // If we have an identifier or a property access at the given location, if the location is // an dotted name expression, and if the location is not an assignment target, obtain the type // of the expression (which will reflect control flow analysis). If the expression indeed // resolved to the given symbol, return the narrowed type. if (location.kind === 71 /* Identifier */) { if (ts.isRightSideOfQualifiedNameOrPropertyAccess(location)) { location = location.parent; } if (ts.isExpressionNode(location) && !ts.isAssignmentTarget(location)) { var type = getTypeOfExpression(location); if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) { return type; } } } // The location isn't a reference to the given symbol, meaning we're being asked // a hypothetical question of what type the symbol would have if there was a reference // to it at the given location. Since we have no control flow information for the // hypothetical reference (control flow information is created and attached by the // binder), we simply return the declared type of the symbol. return getTypeOfSymbol(symbol); } function getControlFlowContainer(node) { return ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !ts.getImmediatelyInvokedFunctionExpression(node) || node.kind === 235 /* ModuleBlock */ || node.kind === 269 /* SourceFile */ || node.kind === 150 /* PropertyDeclaration */; }); } // Check if a parameter is assigned anywhere within its declaring function. function isParameterAssigned(symbol) { var func = ts.getRootDeclaration(symbol.valueDeclaration).parent; var links = getNodeLinks(func); if (!(links.flags & 4194304 /* AssignmentsMarked */)) { links.flags |= 4194304 /* AssignmentsMarked */; if (!hasParentWithAssignmentsMarked(func)) { markParameterAssignments(func); } } return symbol.isAssigned || false; } function hasParentWithAssignmentsMarked(node) { return !!ts.findAncestor(node.parent, function (node) { return ts.isFunctionLike(node) && !!(getNodeLinks(node).flags & 4194304 /* AssignmentsMarked */); }); } function markParameterAssignments(node) { if (node.kind === 71 /* Identifier */) { if (ts.isAssignmentTarget(node)) { var symbol = getResolvedSymbol(node); if (symbol.valueDeclaration && ts.getRootDeclaration(symbol.valueDeclaration).kind === 147 /* Parameter */) { symbol.isAssigned = true; } } } else { ts.forEachChild(node, markParameterAssignments); } } function isConstVariable(symbol) { return symbol.flags & 3 /* Variable */ && (getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */) !== 0 && getTypeOfSymbol(symbol) !== autoArrayType; } /** remove undefined from the annotated type of a parameter when there is an initializer (that doesn't include undefined) */ function removeOptionalityFromDeclaredType(declaredType, declaration) { var annotationIncludesUndefined = strictNullChecks && declaration.kind === 147 /* Parameter */ && declaration.initializer && getFalsyFlags(declaredType) & 4096 /* Undefined */ && !(getFalsyFlags(checkExpression(declaration.initializer)) & 4096 /* Undefined */); return annotationIncludesUndefined ? getTypeWithFacts(declaredType, 131072 /* NEUndefined */) : declaredType; } function isApparentTypePosition(node) { var parent = node.parent; return parent.kind === 180 /* PropertyAccessExpression */ || parent.kind === 182 /* CallExpression */ && parent.expression === node || parent.kind === 181 /* ElementAccessExpression */ && parent.expression === node; } function typeHasNullableConstraint(type) { return type.flags & 1081344 /* TypeVariable */ && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, 12288 /* Nullable */); } function getDeclaredOrApparentType(symbol, node) { // When a node is the left hand expression of a property access, element access, or call expression, // and the type of the node includes type variables with constraints that are nullable, we fetch the // apparent type of the node *before* performing control flow analysis such that narrowings apply to // the constraint type. var type = getTypeOfSymbol(symbol); if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) { return mapType(getWidenedType(type), getApparentType); } return type; } function checkIdentifier(node) { var symbol = getResolvedSymbol(node); if (symbol === unknownSymbol) { return unknownType; } // As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects. // Although in down-level emit of arrow function, we emit it using function expression which means that // arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects // will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior. // To avoid that we will give an error to users if they use arguments objects in arrow function so that they // can explicitly bound arguments objects if (symbol === argumentsSymbol) { var container = ts.getContainingFunction(node); if (languageVersion < 2 /* ES2015 */) { if (container.kind === 188 /* ArrowFunction */) { error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression); } else if (ts.hasModifier(container, 256 /* Async */)) { error(node, ts.Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_function_or_method_in_ES3_and_ES5_Consider_using_a_standard_function_or_method); } } getNodeLinks(container).flags |= 8192 /* CaptureArguments */; return getTypeOfSymbol(symbol); } // We should only mark aliases as referenced if there isn't a local value declaration // for the symbol. if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */) && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) { markAliasSymbolAsReferenced(symbol); } var localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); var declaration = localOrExportSymbol.valueDeclaration; if (localOrExportSymbol.flags & 32 /* Class */) { // Due to the emit for class decorators, any reference to the class from inside of the class body // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind // behavior of class names in ES6. if (declaration.kind === 230 /* ClassDeclaration */ && ts.nodeIsDecorated(declaration)) { var container = ts.getContainingClass(node); while (container !== undefined) { if (container === declaration && container.name !== node) { getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */; getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */; break; } container = ts.getContainingClass(container); } } else if (declaration.kind === 200 /* ClassExpression */) { // When we emit a class expression with static members that contain a reference // to the constructor in the initializer, we will need to substitute that // binding with an alias as the class name is not in scope. var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); while (container !== undefined) { if (container.parent === declaration) { if (container.kind === 150 /* PropertyDeclaration */ && ts.hasModifier(container, 32 /* Static */)) { getNodeLinks(declaration).flags |= 8388608 /* ClassWithConstructorReference */; getNodeLinks(node).flags |= 16777216 /* ConstructorReferenceInClass */; } break; } container = ts.getThisContainer(container, /*includeArrowFunctions*/ false); } } } checkCollisionWithCapturedSuperVariable(node, node); checkCollisionWithCapturedThisVariable(node, node); checkCollisionWithCapturedNewTargetVariable(node, node); checkNestedBlockScopedBinding(node, symbol); var type = getDeclaredOrApparentType(localOrExportSymbol, node); var assignmentKind = ts.getAssignmentTargetKind(node); if (assignmentKind) { if (!(localOrExportSymbol.flags & 3 /* Variable */)) { error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_not_a_variable, symbolToString(symbol)); return unknownType; } if (isReadonlySymbol(localOrExportSymbol)) { error(node, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, symbolToString(symbol)); return unknownType; } } var isAlias = localOrExportSymbol.flags & 2097152 /* Alias */; // We only narrow variables and parameters occurring in a non-assignment position. For all other // entities we simply return the declared type. if (localOrExportSymbol.flags & 3 /* Variable */) { if (assignmentKind === 1 /* Definite */) { return type; } } else if (isAlias) { declaration = ts.find(symbol.declarations, isSomeImportDeclaration); } else { return type; } if (!declaration) { return type; } // The declaration container is the innermost function that encloses the declaration of the variable // or parameter. The flow container is the innermost function starting with which we analyze the control // flow graph to determine the control flow based type. var isParameter = ts.getRootDeclaration(declaration).kind === 147 /* Parameter */; var declarationContainer = getControlFlowContainer(declaration); var flowContainer = getControlFlowContainer(node); var isOuterVariable = flowContainer !== declarationContainer; // When the control flow originates in a function expression or arrow function and we are referencing // a const variable or parameter from an outer function, we extend the origin of the control flow // analysis to include the immediately enclosing function. while (flowContainer !== declarationContainer && (flowContainer.kind === 187 /* FunctionExpression */ || flowContainer.kind === 188 /* ArrowFunction */ || ts.isObjectLiteralOrClassExpressionMethod(flowContainer)) && (isConstVariable(localOrExportSymbol) || isParameter && !isParameterAssigned(localOrExportSymbol))) { flowContainer = getControlFlowContainer(flowContainer); } // We only look for uninitialized variables in strict null checking mode, and only when we can analyze // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). var assumeInitialized = isParameter || isAlias || isOuterVariable || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & 1 /* Any */) !== 0 || isInTypeQuery(node) || node.parent.kind === 247 /* ExportSpecifier */) || node.parent.kind === 204 /* NonNullExpression */ || declaration.kind === 227 /* VariableDeclaration */ && declaration.exclamationToken || declaration.flags & 2097152 /* Ambient */; var initialType = assumeInitialized ? (isParameter ? removeOptionalityFromDeclaredType(type, ts.getRootDeclaration(declaration)) : type) : type === autoType || type === autoArrayType ? undefinedType : getOptionalType(type); var flowType = getFlowTypeOfReference(node, type, initialType, flowContainer, !assumeInitialized); // A variable is considered uninitialized when it is possible to analyze the entire control flow graph // from declaration to use, and when the variable's declared type doesn't include undefined but the // control flow based type does include undefined. if (type === autoType || type === autoArrayType) { if (flowType === autoType || flowType === autoArrayType) { if (noImplicitAny) { error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined, symbolToString(symbol), typeToString(flowType)); error(node, ts.Diagnostics.Variable_0_implicitly_has_an_1_type, symbolToString(symbol), typeToString(flowType)); } return convertAutoToAny(flowType); } } else if (!assumeInitialized && !(getFalsyFlags(type) & 4096 /* Undefined */) && getFalsyFlags(flowType) & 4096 /* Undefined */) { error(node, ts.Diagnostics.Variable_0_is_used_before_being_assigned, symbolToString(symbol)); // Return the declared type to reduce follow-on errors return type; } return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } function isInsideFunction(node, threshold) { return !!ts.findAncestor(node, function (n) { return n === threshold ? "quit" : ts.isFunctionLike(n); }); } function checkNestedBlockScopedBinding(node, symbol) { if (languageVersion >= 2 /* ES2015 */ || (symbol.flags & (2 /* BlockScopedVariable */ | 32 /* Class */)) === 0 || symbol.valueDeclaration.parent.kind === 264 /* 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 === 215 /* ForStatement */ && ts.getAncestor(symbol.valueDeclaration, 228 /* VariableDeclarationList */).parent === container && isAssignedInBodyOfForStatement(node, container)) { getNodeLinks(symbol.valueDeclaration).flags |= 2097152 /* NeedsLoopOutParameter */; } // set 'declared inside loop' bit on the block-scoped binding getNodeLinks(symbol.valueDeclaration).flags |= 262144 /* BlockScopedBindingInLoop */; } if (usedInFunction) { getNodeLinks(symbol.valueDeclaration).flags |= 131072 /* CapturedBlockScopedBinding */; } } function isAssignedInBodyOfForStatement(node, container) { // skip parenthesized nodes var current = node; while (current.parent.kind === 186 /* 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 === 193 /* PrefixUnaryExpression */ || current.parent.kind === 194 /* PostfixUnaryExpression */)) { var expr = current.parent; isAssigned = expr.operator === 43 /* PlusPlusToken */ || expr.operator === 44 /* MinusMinusToken */; } if (!isAssigned) { return false; } // at this point we know that node is the target of assignment // now check that modification happens inside the statement part of the ForStatement return !!ts.findAncestor(current, function (n) { return n === container ? "quit" : n === container.statement; }); } function captureLexicalThis(node, container) { getNodeLinks(node).flags |= 2 /* LexicalThis */; if (container.kind === 150 /* PropertyDeclaration */ || container.kind === 153 /* Constructor */) { var classNode = container.parent; getNodeLinks(classNode).flags |= 4 /* CaptureThis */; } else { getNodeLinks(container).flags |= 4 /* CaptureThis */; } } function findFirstSuperCall(n) { if (ts.isSuperCall(n)) { return n; } else if (ts.isFunctionLike(n)) { return undefined; } return ts.forEachChild(n, findFirstSuperCall); } /** * Return a cached result if super-statement is already found. * Otherwise, find a super statement in a given constructor function and cache the result in the node-links of the constructor * * @param constructor constructor-function to look for super statement */ function getSuperCallInConstructor(constructor) { var links = getNodeLinks(constructor); // Only trying to find super-call if we haven't yet tried to find one. Once we try, we will record the result if (links.hasSuperCall === undefined) { links.superCall = findFirstSuperCall(constructor.body); links.hasSuperCall = links.superCall ? true : false; } return links.superCall; } /** * Check if the given class-declaration extends null then return true. * Otherwise, return false * @param classDecl a class declaration to check if it extends null */ function classDeclarationExtendsNull(classDecl) { var classSymbol = getSymbolOfNode(classDecl); var classInstanceType = getDeclaredTypeOfSymbol(classSymbol); var baseConstructorType = getBaseConstructorTypeOfClass(classInstanceType); return baseConstructorType === nullWideningType; } function checkThisBeforeSuper(node, container, diagnosticMessage) { var containingClassDecl = container.parent; var baseTypeNode = ts.getClassExtendsHeritageClauseElement(containingClassDecl); // If a containing class does not have extends clause or the class extends null // skip checking whether super statement is called before "this" accessing. if (baseTypeNode && !classDeclarationExtendsNull(containingClassDecl)) { var superCall = getSuperCallInConstructor(container); // We should give an error in the following cases: // - No super-call // - "this" is accessing before super-call. // i.e super(this) // this.x; super(); // We want to make sure that super-call is done before accessing "this" so that // "this" is not accessed as a parameter of the super-call. if (!superCall || superCall.end > node.pos) { // In ES6, super inside constructor of class-declaration has to precede "this" accessing error(node, diagnosticMessage); } } } function checkThisExpression(node) { // Stop at the first arrow function so that we can // tell whether 'this' needs to be captured. var container = ts.getThisContainer(node, /* includeArrowFunctions */ true); var needToCaptureLexicalThis = false; if (container.kind === 153 /* Constructor */) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class); } // Now skip arrow functions to get the "real" owner of 'this'. if (container.kind === 188 /* ArrowFunction */) { container = ts.getThisContainer(container, /* includeArrowFunctions */ false); // When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code needToCaptureLexicalThis = (languageVersion < 2 /* ES2015 */); } switch (container.kind) { case 234 /* 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 233 /* 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 153 /* Constructor */: if (isInConstructorArgumentInitializer(node, container)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_constructor_arguments); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } break; case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: if (ts.hasModifier(container, 32 /* Static */)) { error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer); // do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks } break; case 145 /* ComputedPropertyName */: error(node, ts.Diagnostics.this_cannot_be_referenced_in_a_computed_property_name); break; } if (needToCaptureLexicalThis) { captureLexicalThis(node, container); } if (ts.isFunctionLike(container) && (!isInParameterInitializerBeforeContainingFunction(node) || ts.getThisParameter(container))) { // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated. // If this is a function in a JS file, it might be a class method. Check if it's the RHS // of a x.prototype.y = function [name]() { .... } if (container.kind === 187 /* FunctionExpression */ && container.parent.kind === 195 /* BinaryExpression */ && ts.getSpecialPropertyAssignmentKind(container.parent) === 3 /* PrototypeProperty */) { // Get the 'x' of 'x.prototype.y = f' (here, 'f' is 'container') var className = container.parent // x.prototype.y = f .left // x.prototype.y .expression // x.prototype .expression; // x var classSymbol = checkExpression(className).symbol; if (classSymbol && classSymbol.members && (classSymbol.flags & 16 /* Function */)) { return getInferredClassType(classSymbol); } } var thisType = getThisTypeOfDeclaration(container) || getContextualThisParameterType(container); if (thisType) { return thisType; } } if (ts.isClassLike(container.parent)) { var symbol = getSymbolOfNode(container.parent); var type = ts.hasModifier(container, 32 /* Static */) ? getTypeOfSymbol(symbol) : getDeclaredTypeOfSymbol(symbol).thisType; return getFlowTypeOfReference(node, type); } if (ts.isInJavaScriptFile(node)) { var type = getTypeForThisExpressionFromJSDoc(container); if (type && type !== unknownType) { return type; } } if (noImplicitThis) { // With noImplicitThis, functions may not reference 'this' if it has type 'any' error(node, ts.Diagnostics.this_implicitly_has_type_any_because_it_does_not_have_a_type_annotation); } return anyType; } function getTypeForThisExpressionFromJSDoc(node) { var jsdocType = ts.getJSDocType(node); if (jsdocType && jsdocType.kind === 277 /* JSDocFunctionType */) { var jsDocFunctionType = jsdocType; if (jsDocFunctionType.parameters.length > 0 && jsDocFunctionType.parameters[0].name && jsDocFunctionType.parameters[0].name.escapedText === "this") { return getTypeFromTypeNode(jsDocFunctionType.parameters[0].type); } } } function isInConstructorArgumentInitializer(node, constructorDecl) { return !!ts.findAncestor(node, function (n) { return n === constructorDecl ? "quit" : n.kind === 147 /* Parameter */; }); } function checkSuperExpression(node) { var isCallExpression = node.parent.kind === 182 /* CallExpression */ && node.parent.expression === node; var container = ts.getSuperContainer(node, /*stopOnFunctions*/ true); var needToCaptureLexicalThis = false; // adjust the container reference in case if super is used inside arrow functions with arbitrarily deep nesting if (!isCallExpression) { while (container && container.kind === 188 /* ArrowFunction */) { container = ts.getSuperContainer(container, /*stopOnFunctions*/ true); needToCaptureLexicalThis = languageVersion < 2 /* ES2015 */; } } var canUseSuperExpression = isLegalUsageOfSuperExpression(container); var nodeCheckFlag = 0; if (!canUseSuperExpression) { // issue more specific error if super is used in computed property name // class A { foo() { return "1" }} // class B { // [super.foo()]() {} // } var current = ts.findAncestor(node, function (n) { return n === container ? "quit" : n.kind === 145 /* ComputedPropertyName */; }); if (current && current.kind === 145 /* 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 === 179 /* ObjectLiteralExpression */)) { error(node, ts.Diagnostics.super_can_only_be_referenced_in_members_of_derived_classes_or_object_literal_expressions); } else { error(node, ts.Diagnostics.super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class); } return unknownType; } if (!isCallExpression && container.kind === 153 /* Constructor */) { checkThisBeforeSuper(node, container, ts.Diagnostics.super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class); } if (ts.hasModifier(container, 32 /* Static */) || isCallExpression) { nodeCheckFlag = 512 /* SuperStatic */; } else { nodeCheckFlag = 256 /* SuperInstance */; } getNodeLinks(node).flags |= nodeCheckFlag; // Due to how we emit async functions, we need to specialize the emit for an async method that contains a `super` reference. // This is due to the fact that we emit the body of an async function inside of a generator function. As generator // functions cannot reference `super`, we emit a helper inside of the method body, but outside of the generator. This helper // uses an arrow function, which is permitted to reference `super`. // // There are two primary ways we can access `super` from within an async method. The first is getting the value of a property // or indexed access on super, either as part of a right-hand-side expression or call expression. The second is when setting the value // of a property or indexed access, either as part of an assignment expression or destructuring assignment. // // The simplest case is reading a value, in which case we will emit something like the following: // // // ts // ... // async asyncMethod() { // let x = await super.asyncMethod(); // return x; // } // ... // // // js // ... // asyncMethod() { // const _super = name => super[name]; // return __awaiter(this, arguments, Promise, function *() { // let x = yield _super("asyncMethod").call(this); // return x; // }); // } // ... // // The more complex case is when we wish to assign a value, especially as part of a destructuring assignment. As both cases // are legal in ES6, but also likely less frequent, we emit the same more complex helper for both scenarios: // // // ts // ... // async asyncMethod(ar: Promise) { // [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 === 152 /* MethodDeclaration */ && ts.hasModifier(container, 256 /* Async */)) { if (ts.isSuperProperty(node.parent) && ts.isAssignmentTarget(node.parent)) { getNodeLinks(container).flags |= 4096 /* AsyncMethodWithSuperBinding */; } else { getNodeLinks(container).flags |= 2048 /* AsyncMethodWithSuper */; } } if (needToCaptureLexicalThis) { // call expressions are allowed only in constructors so they should always capture correct 'this' // super property access expressions can also appear in arrow functions - // in this case they should also use correct lexical this captureLexicalThis(node.parent, container); } if (container.parent.kind === 179 /* ObjectLiteralExpression */) { if (languageVersion < 2 /* ES2015 */) { error(node, ts.Diagnostics.super_is_only_allowed_in_members_of_object_literal_expressions_when_option_target_is_ES2015_or_higher); return unknownType; } else { // for object literal assume that type of 'super' is 'any' return anyType; } } // at this point the only legal case for parent is ClassLikeDeclaration var classLikeDeclaration = container.parent; if (!ts.getClassExtendsHeritageClauseElement(classLikeDeclaration)) { error(node, ts.Diagnostics.super_can_only_be_referenced_in_a_derived_class); return unknownType; } var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classLikeDeclaration)); var baseClassType = classType && getBaseTypes(classType)[0]; if (!baseClassType) { return unknownType; } if (container.kind === 153 /* 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 === 153 /* 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 === 179 /* ObjectLiteralExpression */) { if (ts.hasModifier(container, 32 /* Static */)) { return container.kind === 152 /* MethodDeclaration */ || container.kind === 151 /* MethodSignature */ || container.kind === 154 /* GetAccessor */ || container.kind === 155 /* SetAccessor */; } else { return container.kind === 152 /* MethodDeclaration */ || container.kind === 151 /* MethodSignature */ || container.kind === 154 /* GetAccessor */ || container.kind === 155 /* SetAccessor */ || container.kind === 150 /* PropertyDeclaration */ || container.kind === 149 /* PropertySignature */ || container.kind === 153 /* Constructor */; } } } return false; } } function getContainingObjectLiteral(func) { return (func.kind === 152 /* MethodDeclaration */ || func.kind === 154 /* GetAccessor */ || func.kind === 155 /* SetAccessor */) && func.parent.kind === 179 /* ObjectLiteralExpression */ ? func.parent : func.kind === 187 /* FunctionExpression */ && func.parent.kind === 265 /* PropertyAssignment */ ? func.parent.parent : undefined; } function getThisTypeArgument(type) { return ts.getObjectFlags(type) & 4 /* Reference */ && type.target === globalThisType ? type.typeArguments[0] : undefined; } function getThisTypeFromContextualType(type) { return mapType(type, function (t) { return t.flags & 262144 /* Intersection */ ? ts.forEach(t.types, getThisTypeArgument) : getThisTypeArgument(t); }); } function getContextualThisParameterType(func) { if (func.kind === 188 /* ArrowFunction */) { return undefined; } if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { var contextualSignature = getContextualSignature(func); if (contextualSignature) { var thisParameter = contextualSignature.thisParameter; if (thisParameter) { return getTypeOfSymbol(thisParameter); } } } var inJs = ts.isInJavaScriptFile(func); if (noImplicitThis || inJs) { var containingLiteral = getContainingObjectLiteral(func); if (containingLiteral) { // We have an object literal method. Check if the containing object literal has a contextual type // that includes a ThisType. If so, T is the contextual type for 'this'. We continue looking in // any directly enclosing object literals. var contextualType = getApparentTypeOfContextualType(containingLiteral); var literal = containingLiteral; var type = contextualType; while (type) { var thisType = getThisTypeFromContextualType(type); if (thisType) { return instantiateType(thisType, getContextualMapper(containingLiteral)); } if (literal.parent.kind !== 265 /* PropertyAssignment */) { break; } literal = literal.parent.parent; type = getApparentTypeOfContextualType(literal); } // There was no contextual ThisType for the containing object literal, so the contextual type // for 'this' is the non-null form of the contextual type for the containing object literal or // the type of the object literal itself. return contextualType ? getNonNullableType(contextualType) : checkExpressionCached(containingLiteral); } // In an assignment of the form 'obj.xxx = function(...)' or 'obj[xxx] = function(...)', the // contextual type for 'this' is 'obj'. var parent = func.parent; if (parent.kind === 195 /* BinaryExpression */ && parent.operatorToken.kind === 58 /* EqualsToken */) { var target = parent.left; if (target.kind === 180 /* PropertyAccessExpression */ || target.kind === 181 /* ElementAccessExpression */) { var expression = target.expression; // Don't contextually type `this` as `exports` in `exports.Point = function(x, y) { this.x = x; this.y = y; }` if (inJs && ts.isIdentifier(expression)) { var sourceFile = ts.getSourceFileOfNode(parent); if (sourceFile.commonJsModuleIndicator && getResolvedSymbol(expression) === sourceFile.symbol) { return undefined; } } return checkExpressionCached(expression); } } } return undefined; } // Return contextual type of parameter or undefined if no contextual type is available function getContextuallyTypedParameterType(parameter) { var func = parameter.parent; if (isContextSensitiveFunctionOrObjectLiteralMethod(func)) { var iife = ts.getImmediatelyInvokedFunctionExpression(func); if (iife && iife.arguments) { var indexOfParameter = ts.indexOf(func.parameters, parameter); if (parameter.dotDotDotToken) { var restTypes = []; for (var i = indexOfParameter; i < iife.arguments.length; i++) { restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i]))); } return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined; } var links = getNodeLinks(iife); var cached = links.resolvedSignature; links.resolvedSignature = anySignature; var type = indexOfParameter < iife.arguments.length ? getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) : parameter.initializer ? undefined : undefinedWideningType; links.resolvedSignature = cached; return type; } var contextualSignature = getContextualSignature(func); if (contextualSignature) { var funcHasRestParameters = ts.hasRestParameter(func); var len = func.parameters.length - (funcHasRestParameters ? 1 : 0); var indexOfParameter = ts.indexOf(func.parameters, parameter); if (ts.getThisParameter(func) !== undefined && !contextualSignature.thisParameter) { ts.Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`. indexOfParameter -= 1; } if (indexOfParameter < len) { return getTypeAtPosition(contextualSignature, indexOfParameter); } // If last parameter is contextually rest parameter get its type if (funcHasRestParameters && indexOfParameter === (func.parameters.length - 1) && isRestParameterIndex(contextualSignature, func.parameters.length - 1)) { return getTypeOfSymbol(ts.lastOrUndefined(contextualSignature.parameters)); } } } return undefined; } // In a variable, parameter or property declaration with a type annotation, // the contextual type of an initializer expression is the type of the variable, parameter or property. // Otherwise, in a parameter declaration of a contextually typed function expression, // the contextual type of an initializer expression is the contextual type of the parameter. // Otherwise, in a variable or parameter declaration with a binding pattern name, // the contextual type of an initializer expression is the type implied by the binding pattern. // Otherwise, in a binding pattern inside a variable or parameter declaration, // the contextual type of an initializer expression is the type annotation of the containing declaration, if present. function getContextualTypeForInitializerExpression(node) { var declaration = node.parent; if (node === declaration.initializer || node.kind === 58 /* EqualsToken */) { var typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode) { return getTypeFromTypeNode(typeNode); } if (declaration.kind === 147 /* Parameter */) { var type = getContextuallyTypedParameterType(declaration); if (type) { return type; } } if (ts.isBindingPattern(declaration.name)) { return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ true, /*reportErrors*/ false); } if (ts.isBindingPattern(declaration.parent)) { var parentDeclaration = declaration.parent.parent; var name = declaration.propertyName || declaration.name; if (parentDeclaration.kind !== 177 /* BindingElement */) { var parentTypeNode = ts.getEffectiveTypeAnnotationNode(parentDeclaration); if (parentTypeNode && !ts.isBindingPattern(name)) { var text = ts.getTextOfPropertyName(name); if (text) { return getTypeOfPropertyOfType(getTypeFromTypeNode(parentTypeNode), text); } } } } } return undefined; } function getContextualTypeForReturnExpression(node) { var func = ts.getContainingFunction(node); if (func) { var functionFlags = ts.getFunctionFlags(func); if (functionFlags & 1 /* Generator */) { return undefined; } var contextualReturnType = getContextualReturnType(func); return functionFlags & 2 /* Async */ ? contextualReturnType && getAwaitedTypeOfPromise(contextualReturnType) // Async function : contextualReturnType; // Regular function } return undefined; } function getContextualTypeForYieldOperand(node) { var func = ts.getContainingFunction(node); if (func) { var functionFlags = ts.getFunctionFlags(func); var contextualReturnType = getContextualReturnType(func); if (contextualReturnType) { return node.asteriskToken ? contextualReturnType : getIteratedTypeOfGenerator(contextualReturnType, (functionFlags & 2 /* Async */) !== 0); } } return undefined; } function isInParameterInitializerBeforeContainingFunction(node) { var inBindingInitializer = false; while (node.parent && !ts.isFunctionLike(node.parent)) { if (ts.isParameter(node.parent) && (inBindingInitializer || node.parent.initializer === node)) { return true; } if (ts.isBindingElement(node.parent) && node.parent.initializer === node) { inBindingInitializer = true; } node = node.parent; } return false; } function getContextualReturnType(functionDecl) { // If the containing function has a return type annotation, is a constructor, or is a get accessor whose // corresponding set accessor has a type annotation, return statements in the function are contextually typed if (functionDecl.kind === 153 /* Constructor */ || ts.getEffectiveReturnTypeNode(functionDecl) || isGetAccessorWithAnnotatedSetAccessor(functionDecl)) { return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl)); } // Otherwise, if the containing function is contextually typed by a function type with exactly one call signature // and that call signature is non-generic, return statements are contextually typed by the return type of the signature var signature = getContextualSignatureForFunctionLikeDeclaration(functionDecl); if (signature && !isResolvingReturnTypeOfSignature(signature)) { return getReturnTypeOfSignature(signature); } return undefined; } // In a typed function call, an argument or substitution expression is contextually typed by the type of the corresponding parameter. function getContextualTypeForArgument(callTarget, arg) { var args = getEffectiveCallArguments(callTarget); var argIndex = ts.indexOf(args, arg); if (argIndex >= 0) { // If we're already in the process of resolving the given signature, don't resolve again as // that could cause infinite recursion. Instead, return anySignature. var signature = getNodeLinks(callTarget).resolvedSignature === resolvingSignature ? resolvingSignature : getResolvedSignature(callTarget); return getTypeAtPosition(signature, argIndex); } return undefined; } function getContextualTypeForSubstitutionExpression(template, substitutionExpression) { if (template.parent.kind === 184 /* TaggedTemplateExpression */) { return getContextualTypeForArgument(template.parent, substitutionExpression); } return undefined; } function getContextualTypeForBinaryOperand(node) { var binaryExpression = node.parent; var left = binaryExpression.left, operatorToken = binaryExpression.operatorToken, right = binaryExpression.right; switch (operatorToken.kind) { case 58 /* EqualsToken */: return node === right && isContextSensitiveAssignment(binaryExpression) ? getTypeOfExpression(left) : undefined; case 54 /* BarBarToken */: // When an || expression has a contextual type, the operands are contextually typed by that type. When an || // expression has no contextual type, the right operand is contextually typed by the type of the left operand. var type = getContextualType(binaryExpression); return !type && node === right ? getTypeOfExpression(left, /*cache*/ true) : type; case 53 /* AmpersandAmpersandToken */: case 26 /* CommaToken */: return node === right ? getContextualType(binaryExpression) : undefined; case 34 /* EqualsEqualsEqualsToken */: case 32 /* EqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: // For completions after `x === ` return node === operatorToken ? getTypeOfExpression(binaryExpression.left) : undefined; default: return undefined; } } // In an assignment expression, the right operand is contextually typed by the type of the left operand. // Don't do this for special property assignments to avoid circularity. function isContextSensitiveAssignment(binaryExpression) { var kind = ts.getSpecialPropertyAssignmentKind(binaryExpression); switch (kind) { case 0 /* None */: return true; case 5 /* Property */: // If `binaryExpression.left` was assigned a symbol, then this is a new declaration; otherwise it is an assignment to an existing declaration. // See `bindStaticPropertyAssignment` in `binder.ts`. return !binaryExpression.left.symbol; case 1 /* ExportsProperty */: case 2 /* ModuleExports */: case 3 /* PrototypeProperty */: case 4 /* ThisProperty */: return false; default: ts.Debug.assertNever(kind); } } function getTypeOfPropertyOfContextualType(type, name) { return mapType(type, function (t) { var prop = t.flags & 458752 /* StructuredType */ ? getPropertyOfType(t, name) : undefined; return prop ? getTypeOfSymbol(prop) : undefined; }); } function getIndexTypeOfContextualType(type, kind) { return mapType(type, function (t) { return getIndexTypeOfStructuredType(t, kind); }); } // Return true if the given contextual type is a tuple-like type function contextualTypeIsTupleLikeType(type) { return !!(type.flags & 131072 /* 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 (node.flags & 4194304 /* InWithStatement */) { // 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 (!hasNonBindableDynamicName(element)) { // For a (non-symbol) computed property, there is no reason to look up the name // in the type. It will just be "__computed", which does not appear in any // SymbolTable. var symbolName_1 = getSymbolOfNode(element).escapedName; var propertyType = getTypeOfPropertyOfContextualType(type, symbolName_1); if (propertyType) { return propertyType; } } return isNumericName(element.name) && getIndexTypeOfContextualType(type, 1 /* Number */) || getIndexTypeOfContextualType(type, 0 /* String */); } return undefined; } // In an array literal contextually typed by a type T, the contextual type of an element expression at index N is // the type of the property with the numeric name N in T, if one exists. Otherwise, if T has a numeric index signature, // it is the type of the numeric index signature in T. Otherwise, in ES6 and higher, the contextual type is the iterated // type of T. function getContextualTypeForElementExpression(arrayContextualType, index) { return arrayContextualType && (getTypeOfPropertyOfContextualType(arrayContextualType, "" + index) || getIndexTypeOfContextualType(arrayContextualType, 1 /* Number */) || getIteratedTypeOrElementType(arrayContextualType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false)); } // In a contextually typed conditional expression, the true/false expressions are contextually typed by the same type. function getContextualTypeForConditionalOperand(node) { var conditional = node.parent; return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } function getContextualTypeForJsxExpression(node) { // JSX expression can appear in two position : JSX Element's children or JSX attribute var jsxAttributes = ts.isJsxAttributeLike(node.parent) ? node.parent.parent : ts.isJsxElement(node.parent) ? node.parent.openingElement.attributes : undefined; // node.parent is JsxFragment with no attributes if (!jsxAttributes) { return undefined; // don't check children of a fragment } // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type // which is a type of the parameter of the signature we are trying out. // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName var attributesType = getContextualType(jsxAttributes); if (!attributesType || isTypeAny(attributesType)) { return undefined; } if (ts.isJsxAttribute(node.parent)) { // JSX expression is in JSX attribute return getTypeOfPropertyOfContextualType(attributesType, node.parent.name.escapedText); } else if (node.parent.kind === 250 /* JsxElement */) { // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty) var jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : anyType; } else { // JSX expression is in JSX spread attribute return attributesType; } } function getContextualTypeForJsxAttribute(attribute) { // When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type // which is a type of the parameter of the signature we are trying out. // If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName var attributesType = getContextualType(attribute.parent); if (ts.isJsxAttribute(attribute)) { if (!attributesType || isTypeAny(attributesType)) { return undefined; } return getTypeOfPropertyOfContextualType(attributesType, attribute.name.escapedText); } else { return attributesType; } } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily // be "pushed" onto a node using the contextualType property. function getApparentTypeOfContextualType(node) { var contextualType = getContextualType(node); contextualType = contextualType && mapType(contextualType, getApparentType); if (!(contextualType && contextualType.flags & 131072 /* Union */ && ts.isObjectLiteralExpression(node))) { return contextualType; } // Keep the below up-to-date with the work done within `isRelatedTo` by `findMatchingDiscriminantType` var match; propLoop: for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; if (!prop.symbol) continue; if (prop.kind !== 265 /* PropertyAssignment */) continue; if (isDiscriminantProperty(contextualType, prop.symbol.escapedName)) { var discriminatingType = getTypeOfNode(prop.initializer); for (var _b = 0, _c = contextualType.types; _b < _c.length; _b++) { var type = _c[_b]; var targetType = getTypeOfPropertyOfType(type, prop.symbol.escapedName); if (targetType && checkTypeAssignableTo(discriminatingType, targetType, /*errorNode*/ undefined)) { if (match) { if (type === match) continue; // Finding multiple fields which discriminate to the same type is fine match = undefined; break propLoop; } match = type; } } } } return match || contextualType; } /** * 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 (node.flags & 4194304 /* InWithStatement */) { // 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 227 /* VariableDeclaration */: case 147 /* Parameter */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 177 /* BindingElement */: return getContextualTypeForInitializerExpression(node); case 188 /* ArrowFunction */: case 220 /* ReturnStatement */: return getContextualTypeForReturnExpression(node); case 198 /* YieldExpression */: return getContextualTypeForYieldOperand(parent); case 183 /* NewExpression */: if (node.kind === 94 /* NewKeyword */) { return getContextualType(parent); } // falls through case 182 /* CallExpression */: return getContextualTypeForArgument(parent, node); case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: return getTypeFromTypeNode(parent.type); case 195 /* BinaryExpression */: return getContextualTypeForBinaryOperand(node); case 265 /* PropertyAssignment */: case 266 /* ShorthandPropertyAssignment */: return getContextualTypeForObjectLiteralElement(parent); case 267 /* SpreadAssignment */: return getApparentTypeOfContextualType(parent.parent); case 178 /* ArrayLiteralExpression */: { var arrayLiteral = parent; var type = getApparentTypeOfContextualType(arrayLiteral); return getContextualTypeForElementExpression(type, ts.indexOfNode(arrayLiteral.elements, node)); } case 196 /* ConditionalExpression */: return getContextualTypeForConditionalOperand(node); case 206 /* TemplateSpan */: ts.Debug.assert(parent.parent.kind === 197 /* TemplateExpression */); return getContextualTypeForSubstitutionExpression(parent.parent, node); case 186 /* ParenthesizedExpression */: { // Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast. var tag = ts.isInJavaScriptFile(parent) ? ts.getJSDocTypeTag(parent) : undefined; return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent); } case 260 /* JsxExpression */: return getContextualTypeForJsxExpression(parent); case 257 /* JsxAttribute */: case 259 /* JsxSpreadAttribute */: return getContextualTypeForJsxAttribute(parent); case 252 /* JsxOpeningElement */: case 251 /* JsxSelfClosingElement */: return getAttributesTypeFromJsxOpeningLikeElement(parent); case 261 /* CaseClause */: { if (node.kind === 73 /* CaseKeyword */) { var switchStatement = parent.parent.parent; return getTypeOfExpression(switchStatement.expression); } } } return undefined; } function getContextualMapper(node) { node = ts.findAncestor(node, function (n) { return !!n.contextualMapper; }); return node ? node.contextualMapper : identityMapper; } // If the given type is an object or union type with a single signature, and if that signature has at // least as many parameters as the given function, return the signature. Otherwise return undefined. function getContextualCallSignature(type, node) { var signatures = getSignaturesOfStructuredType(type, 0 /* Call */); if (signatures.length === 1) { var signature = signatures[0]; if (!isAritySmaller(signature, node)) { return signature; } } } /** If the contextual signature has fewer parameters than the function expression, do not use it */ function isAritySmaller(signature, target) { var targetParameterCount = 0; for (; targetParameterCount < target.parameters.length; targetParameterCount++) { var param = target.parameters[targetParameterCount]; if (param.initializer || param.questionToken || param.dotDotDotToken || isJSDocOptionalParameter(param)) { break; } } if (target.parameters.length && ts.parameterIsThisKeyword(target.parameters[0])) { targetParameterCount--; } var sourceLength = signature.hasRestParameter ? Number.MAX_VALUE : signature.parameters.length; return sourceLength < targetParameterCount; } function isFunctionExpressionOrArrowFunction(node) { return node.kind === 187 /* FunctionExpression */ || node.kind === 188 /* 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 !== 152 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); var type = getContextualTypeForFunctionLikeDeclaration(node); if (!type) { return undefined; } if (!(type.flags & 131072 /* Union */)) { return getContextualCallSignature(type, node); } var signatureList; var types = type.types; for (var _i = 0, types_16 = types; _i < types_16.length; _i++) { var current = types_16[_i]; var signature = getContextualCallSignature(current, node); if (signature) { if (!signatureList) { // This signature will contribute to contextual union signature signatureList = [signature]; } else if (!compareSignaturesIdentical(signatureList[0], signature, /*partialMatch*/ false, /*ignoreThisTypes*/ true, /*ignoreReturnTypes*/ true, compareTypesIdentical)) { // Signatures aren't identical, do not use return undefined; } else { // Use this signature for contextual union signature signatureList.push(signature); } } } // Result is union of signatures collected (return type is union of return types of this signature set) var result; if (signatureList) { result = cloneSignature(signatureList[0]); // Clear resolved return type we possibly got from cloneSignature result.resolvedReturnType = undefined; result.unionSignatures = signatureList; } return result; } function checkSpreadExpression(node, checkMode) { if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, 1536 /* SpreadIncludes */); } var arrayOrIterableType = checkExpression(node.expression, checkMode); return checkIteratedTypeOrElementType(arrayOrIterableType, node.expression, /*allowStringInput*/ false, /*allowAsyncIterables*/ false); } function hasDefaultValue(node) { return (node.kind === 177 /* BindingElement */ && !!node.initializer) || (node.kind === 195 /* BinaryExpression */ && node.operatorToken.kind === 58 /* EqualsToken */); } function checkArrayLiteral(node, checkMode) { var elements = node.elements; var hasSpreadElement = false; var elementTypes = []; var inDestructuringPattern = ts.isAssignmentTarget(node); var contextualType = getApparentTypeOfContextualType(node); for (var index = 0; index < elements.length; index++) { var e = elements[index]; if (inDestructuringPattern && e.kind === 199 /* SpreadElement */) { // Given the following situation: // var c: {}; // [...c] = ["", 0]; // // c is represented in the tree as a spread element in an array literal. // But c really functions as a rest element, and its purpose is to provide // a contextual type for the right hand side of the assignment. Therefore, // instead of calling checkExpression on "...c", which will give an error // if c is not iterable/array-like, we need to act as if we are trying to // get the contextual element type from it. So we do something similar to // getContextualTypeForElementExpression, which will crucially not error // if there is no index type / iterated type. var restArrayType = checkExpression(e.expression, checkMode); var restElementType = getIndexTypeOfType(restArrayType, 1 /* Number */) || getIteratedTypeOrElementType(restArrayType, /*errorNode*/ undefined, /*allowStringInput*/ false, /*allowAsyncIterables*/ false, /*checkAssignability*/ false); if (restElementType) { elementTypes.push(restElementType); } } else { var elementContextualType = getContextualTypeForElementExpression(contextualType, index); var type = checkExpressionForMutableLocation(e, checkMode, elementContextualType); elementTypes.push(type); } hasSpreadElement = hasSpreadElement || e.kind === 199 /* SpreadElement */; } if (!hasSpreadElement) { // If array literal is actually a destructuring pattern, mark it as an implied type. We do this such // that we get the same behavior for "var [x, y] = []" and "[x, y] = []". if (inDestructuringPattern && elementTypes.length) { var type = cloneTypeReference(createTupleType(elementTypes)); type.pattern = node; return type; } 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 === 176 /* ArrayBindingPattern */ || pattern.kind === 178 /* ArrayLiteralExpression */)) { var patternElements = pattern.elements; for (var i = elementTypes.length; i < patternElements.length; i++) { var patternElement = patternElements[i]; if (hasDefaultValue(patternElement)) { elementTypes.push(contextualType.typeArguments[i]); } else { if (patternElement.kind !== 201 /* OmittedExpression */) { error(patternElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } elementTypes.push(unknownType); } } } if (elementTypes.length) { return createTupleType(elementTypes); } } } return createArrayType(elementTypes.length ? getUnionType(elementTypes, /*subtypeReduction*/ true) : strictNullChecks ? implicitNeverType : undefinedWideningType); } function isNumericName(name) { switch (name.kind) { case 145 /* ComputedPropertyName */: return isNumericComputedName(name); case 71 /* Identifier */: return isNumericLiteralName(name.escapedText); case 8 /* NumericLiteral */: case 9 /* StringLiteral */: return isNumericLiteralName(name.text); default: return false; } } function isNumericComputedName(name) { // It seems odd to consider an expression of type Any to result in a numeric name, // but this behavior is consistent with checkIndexedAccess return isTypeAssignableToKind(checkComputedPropertyName(name), 84 /* NumberLike */); } function isInfinityOrNaNString(name) { return name === "Infinity" || name === "-Infinity" || name === "NaN"; } function isNumericLiteralName(name) { // The intent of numeric names is that // - they are names with text in a numeric form, and that // - setting properties/indexing with them is always equivalent to doing so with the numeric literal 'numLit', // acquired by applying the abstract 'ToNumber' operation on the name's text. // // The subtlety is in the latter portion, as we cannot reliably say that anything that looks like a numeric literal is a numeric name. // In fact, it is the case that the text of the name must be equal to 'ToString(numLit)' for this to hold. // // Consider the property name '"0xF00D"'. When one indexes with '0xF00D', they are actually indexing with the value of 'ToString(0xF00D)' // according to the ECMAScript specification, so it is actually as if the user indexed with the string '"61453"'. // Thus, the text of all numeric literals equivalent to '61543' such as '0xF00D', '0xf00D', '0170015', etc. are not valid numeric names // because their 'ToString' representation is not equal to their original text. // This is motivated by ECMA-262 sections 9.3.1, 9.8.1, 11.1.5, and 11.2.1. // // Here, we test whether 'ToString(ToNumber(name))' is exactly equal to 'name'. // The '+' prefix operator is equivalent here to applying the abstract ToNumber operation. // Applying the 'toString()' method on a number gives us the abstract ToString operation on a number. // // Note that this accepts the values 'Infinity', '-Infinity', and 'NaN', and that this is intentional. // This is desired behavior, because when indexing with them as numeric entities, you are indexing // with the strings '"Infinity"', '"-Infinity"', and '"NaN"' respectively. return (+name).toString() === name; } function checkComputedPropertyName(node) { var links = getNodeLinks(node.expression); if (!links.resolvedType) { links.resolvedType = checkExpression(node.expression); // This will allow types number, string, symbol or any. It will also allow enums, the unknown // type, and any union of these types (like string | number). if (links.resolvedType.flags & 12288 /* Nullable */ || !isTypeAssignableToKind(links.resolvedType, 524322 /* StringLike */ | 84 /* NumberLike */ | 1536 /* ESSymbolLike */) && !isTypeAssignableTo(links.resolvedType, getUnionType([stringType, numberType, esSymbolType]))) { error(node, ts.Diagnostics.A_computed_property_name_must_be_of_type_string_number_symbol_or_any); } else { checkThatExpressionIsProperSymbolReference(node.expression, links.resolvedType, /*reportError*/ true); } } return links.resolvedType; } function getObjectLiteralIndexInfo(propertyNodes, offset, properties, kind) { var propTypes = []; for (var i = 0; i < properties.length; i++) { if (kind === 0 /* String */ || isNumericName(propertyNodes[i + offset].name)) { propTypes.push(getTypeOfSymbol(properties[i])); } } var unionType = propTypes.length ? getUnionType(propTypes, /*subtypeReduction*/ true) : undefinedType; return createIndexInfo(unionType, /*isReadonly*/ false); } function checkObjectLiteral(node, checkMode) { var inDestructuringPattern = ts.isAssignmentTarget(node); // Grammar checking checkGrammarObjectLiteralExpression(node, inDestructuringPattern); var propertiesTable = ts.createSymbolTable(); var propertiesArray = []; var spread = emptyObjectType; var propagatedFlags = 0; var contextualType = getApparentTypeOfContextualType(node); var contextualTypeHasPattern = contextualType && contextualType.pattern && (contextualType.pattern.kind === 175 /* ObjectBindingPattern */ || contextualType.pattern.kind === 179 /* ObjectLiteralExpression */); var isJSObjectLiteral = !contextualType && ts.isInJavaScriptFile(node); var typeFlags = 0; var patternWithComputedProperties = false; var hasComputedStringProperty = false; var hasComputedNumberProperty = false; var isInJSFile = ts.isInJavaScriptFile(node); var offset = 0; for (var i = 0; i < node.properties.length; i++) { var memberDecl = node.properties[i]; var member = getSymbolOfNode(memberDecl); var literalName = void 0; if (memberDecl.kind === 265 /* PropertyAssignment */ || memberDecl.kind === 266 /* ShorthandPropertyAssignment */ || ts.isObjectLiteralMethod(memberDecl)) { var jsdocType = void 0; if (isInJSFile) { jsdocType = getTypeForDeclarationFromJSDocComment(memberDecl); } var type = void 0; if (memberDecl.kind === 265 /* PropertyAssignment */) { if (memberDecl.name.kind === 145 /* ComputedPropertyName */) { var t = checkComputedPropertyName(memberDecl.name); if (t.flags & 224 /* Literal */) { literalName = ts.escapeLeadingUnderscores("" + t.value); } } type = checkPropertyAssignment(memberDecl, checkMode); } else if (memberDecl.kind === 152 /* MethodDeclaration */) { type = checkObjectLiteralMethod(memberDecl, checkMode); } else { ts.Debug.assert(memberDecl.kind === 266 /* ShorthandPropertyAssignment */); type = checkExpressionForMutableLocation(memberDecl.name, checkMode); } if (jsdocType) { checkTypeAssignableTo(type, jsdocType, memberDecl); type = jsdocType; } typeFlags |= type.flags; var nameType = hasLateBindableName(memberDecl) ? checkComputedPropertyName(memberDecl.name) : undefined; var prop = nameType && isTypeUsableAsLateBoundName(nameType) ? createSymbol(4 /* Property */ | member.flags, getLateBoundNameFromType(nameType), 1024 /* Late */) : createSymbol(4 /* Property */ | member.flags, literalName || member.escapedName); if (inDestructuringPattern) { // If object literal is an assignment pattern and if the assignment pattern specifies a default value // for the property, make the property optional. var isOptional = (memberDecl.kind === 265 /* PropertyAssignment */ && hasDefaultValue(memberDecl.initializer)) || (memberDecl.kind === 266 /* ShorthandPropertyAssignment */ && memberDecl.objectAssignmentInitializer); if (isOptional) { prop.flags |= 16777216 /* Optional */; } if (!literalName && ts.hasDynamicName(memberDecl)) { patternWithComputedProperties = true; } } else if (contextualTypeHasPattern && !(ts.getObjectFlags(contextualType) & 512 /* ObjectLiteralPatternWithComputedProperties */)) { // If object literal is contextually typed by the implied type of a binding pattern, and if the // binding pattern specifies a default value for the property, make the property optional. var impliedProp = getPropertyOfType(contextualType, member.escapedName); if (impliedProp) { prop.flags |= impliedProp.flags & 16777216 /* Optional */; } else if (!compilerOptions.suppressExcessPropertyErrors && !getIndexInfoOfType(contextualType, 0 /* String */)) { error(memberDecl.name, ts.Diagnostics.Object_literal_may_only_specify_known_properties_and_0_does_not_exist_in_type_1, symbolToString(member), typeToString(contextualType)); } } prop.declarations = member.declarations; prop.parent = member.parent; if (member.valueDeclaration) { prop.valueDeclaration = member.valueDeclaration; } prop.type = type; prop.target = member; member = prop; } else if (memberDecl.kind === 267 /* SpreadAssignment */) { if (languageVersion < 2 /* ES2015 */) { checkExternalEmitHelpers(memberDecl, 2 /* Assign */); } if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); propertiesArray = []; propertiesTable = ts.createSymbolTable(); hasComputedStringProperty = false; hasComputedNumberProperty = false; typeFlags = 0; } var type = checkExpression(memberDecl.expression); if (!isValidSpreadType(type)) { error(memberDecl, ts.Diagnostics.Spread_types_may_only_be_created_from_object_types); return unknownType; } spread = getSpreadType(spread, type, node.symbol, propagatedFlags); offset = i + 1; continue; } else { // TypeScript 1.0 spec (April 2014) // A get accessor declaration is processed in the same manner as // an ordinary function declaration(section 6.1) with no parameters. // A set accessor declaration is processed in the same manner // as an ordinary function declaration with a single parameter and a Void return type. ts.Debug.assert(memberDecl.kind === 154 /* GetAccessor */ || memberDecl.kind === 155 /* SetAccessor */); checkNodeDeferred(memberDecl); } if (!literalName && hasNonBindableDynamicName(memberDecl)) { if (isNumericName(memberDecl.name)) { hasComputedNumberProperty = true; } else { hasComputedStringProperty = true; } } else { propertiesTable.set(member.escapedName, member); } propertiesArray.push(member); } // If object literal is contextually typed by the implied type of a binding pattern, augment the result // type with those properties for which the binding pattern specifies a default value. if (contextualTypeHasPattern) { for (var _i = 0, _a = getPropertiesOfType(contextualType); _i < _a.length; _i++) { var prop = _a[_i]; if (!propertiesTable.get(prop.escapedName) && !(spread && getPropertyOfType(spread, prop.escapedName))) { if (!(prop.flags & 16777216 /* Optional */)) { error(prop.valueDeclaration || prop.bindingElement, ts.Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value); } propertiesTable.set(prop.escapedName, prop); propertiesArray.push(prop); } } } if (spread !== emptyObjectType) { if (propertiesArray.length > 0) { spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags); } return spread; } return createObjectLiteralType(); function createObjectLiteralType() { var stringIndexInfo = isJSObjectLiteral ? jsObjectLiteralIndexInfo : hasComputedStringProperty ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 0 /* String */) : undefined; var numberIndexInfo = hasComputedNumberProperty && !isJSObjectLiteral ? getObjectLiteralIndexInfo(node.properties, offset, propertiesArray, 1 /* Number */) : undefined; var result = createAnonymousType(node.symbol, propertiesTable, ts.emptyArray, ts.emptyArray, stringIndexInfo, numberIndexInfo); var freshObjectLiteralFlag = compilerOptions.suppressExcessPropertyErrors ? 0 : 2097152 /* FreshLiteral */; result.flags |= 8388608 /* ContainsObjectLiteral */ | freshObjectLiteralFlag | (typeFlags & 29360128 /* PropagatingFlags */); result.objectFlags |= 128 /* ObjectLiteral */; if (patternWithComputedProperties) { result.objectFlags |= 512 /* ObjectLiteralPatternWithComputedProperties */; } if (inDestructuringPattern) { result.pattern = node; } if (!(result.flags & 12288 /* Nullable */)) { propagatedFlags |= (result.flags & 29360128 /* PropagatingFlags */); } return result; } } function isValidSpreadType(type) { return !!(type.flags & (1 /* Any */ | 33554432 /* NonPrimitive */) || getFalsyFlags(type) & 14560 /* DefinitelyFalsy */ && isValidSpreadType(removeDefinitelyFalsyTypes(type)) || type.flags & 65536 /* Object */ && !isGenericMappedType(type) || type.flags & 393216 /* UnionOrIntersection */ && !ts.forEach(type.types, function (t) { return !isValidSpreadType(t); })); } function checkJsxSelfClosingElement(node) { checkJsxOpeningLikeElementOrOpeningFragment(node); return getJsxGlobalElementType() || anyType; } function checkJsxElement(node) { // Check attributes checkJsxOpeningLikeElementOrOpeningFragment(node.openingElement); // Perform resolution on the closing tag so that rename/go to definition/etc work if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) { getIntrinsicTagSymbol(node.closingElement); } else { checkExpression(node.closingElement.tagName); } return getJsxGlobalElementType() || anyType; } function checkJsxFragment(node) { checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment); if (compilerOptions.jsx === 2 /* React */ && compilerOptions.jsxFactory) { error(node, ts.Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory); } return getJsxGlobalElementType() || anyType; } /** * Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers */ function isUnhyphenatedJsxName(name) { // - is the only character supported in JSX attribute names that isn't valid in JavaScript identifiers return !ts.stringContains(name, "-"); } /** * Returns true iff React would emit this tag name as a string rather than an identifier or qualified name */ function isJsxIntrinsicIdentifier(tagName) { // TODO (yuisu): comment switch (tagName.kind) { case 180 /* PropertyAccessExpression */: case 99 /* ThisKeyword */: return false; case 71 /* Identifier */: return ts.isIntrinsicJsxName(tagName.escapedText); default: ts.Debug.fail(); } } /** * Get attributes type of the JSX opening-like element. The result is from resolving "attributes" property of the opening-like element. * * @param openingLikeElement a JSX opening-like element * @param filter a function to remove attributes that will not participate in checking whether attributes are assignable * @return an anonymous type (similar to the one returned by checkObjectLiteral) in which its properties are attributes property. * @remarks Because this function calls getSpreadType, it needs to use the same checks as checkObjectLiteral, * which also calls getSpreadType. */ function createJsxAttributesTypeFromAttributesProperty(openingLikeElement, filter, checkMode) { var attributes = openingLikeElement.attributes; var attributesTable = ts.createSymbolTable(); var spread = emptyObjectType; var attributesArray = []; var hasSpreadAnyType = false; var typeToIntersect; var explicitlySpecifyChildrenAttribute = false; var jsxChildrenPropertyName = getJsxElementChildrenPropertyname(); for (var _i = 0, _a = attributes.properties; _i < _a.length; _i++) { var attributeDecl = _a[_i]; var member = attributeDecl.symbol; if (ts.isJsxAttribute(attributeDecl)) { var exprType = attributeDecl.initializer ? checkExpression(attributeDecl.initializer, checkMode) : trueType; // is sugar for var attributeSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */ | member.flags, member.escapedName); attributeSymbol.declarations = member.declarations; attributeSymbol.parent = member.parent; if (member.valueDeclaration) { attributeSymbol.valueDeclaration = member.valueDeclaration; } attributeSymbol.type = exprType; attributeSymbol.target = member; attributesTable.set(attributeSymbol.escapedName, attributeSymbol); attributesArray.push(attributeSymbol); if (attributeDecl.name.escapedText === jsxChildrenPropertyName) { explicitlySpecifyChildrenAttribute = true; } } else { ts.Debug.assert(attributeDecl.kind === 259 /* JsxSpreadAttribute */); if (attributesArray.length > 0) { spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0); attributesArray = []; attributesTable = ts.createSymbolTable(); } var exprType = checkExpression(attributeDecl.expression); if (isTypeAny(exprType)) { hasSpreadAnyType = true; } if (isValidSpreadType(exprType)) { spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*propagatedFlags*/ 0); } else { typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType; } } } if (!hasSpreadAnyType) { if (spread !== emptyObjectType) { if (attributesArray.length > 0) { spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0); } attributesArray = getPropertiesOfType(spread); } attributesTable = ts.createSymbolTable(); for (var _b = 0, attributesArray_1 = attributesArray; _b < attributesArray_1.length; _b++) { var attr = attributesArray_1[_b]; if (!filter || filter(attr)) { attributesTable.set(attr.escapedName, attr); } } } // Handle children attribute var parent = openingLikeElement.parent.kind === 250 /* JsxElement */ ? openingLikeElement.parent : undefined; // We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) { var childrenTypes = checkJsxChildren(parent, checkMode); if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") { // Error if there is a attribute named "children" explicitly specified and children element. // This is because children element will overwrite the value from attributes. // Note: we will not warn "children" attribute overwritten if "children" attribute is specified in object spread. if (explicitlySpecifyChildrenAttribute) { error(attributes, ts.Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, ts.unescapeLeadingUnderscores(jsxChildrenPropertyName)); } // If there are children in the body of JSX element, create dummy attribute "children" with anyType so that it will pass the attribute checking process var childrenPropSymbol = createSymbol(4 /* Property */ | 33554432 /* Transient */, jsxChildrenPropertyName); childrenPropSymbol.type = childrenTypes.length === 1 ? childrenTypes[0] : createArrayType(getUnionType(childrenTypes, /*subtypeReduction*/ false)); attributesTable.set(jsxChildrenPropertyName, childrenPropSymbol); } } if (hasSpreadAnyType) { return anyType; } var attributeType = createJsxAttributesType(attributes.symbol, attributesTable); return typeToIntersect && attributesTable.size ? getIntersectionType([typeToIntersect, attributeType]) : typeToIntersect ? typeToIntersect : attributeType; /** * Create anonymous type from given attributes symbol table. * @param symbol a symbol of JsxAttributes containing attributes corresponding to attributesTable * @param attributesTable a symbol table of attributes property */ function createJsxAttributesType(symbol, attributesTable) { var result = createAnonymousType(symbol, attributesTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); result.flags |= 67108864 /* JsxAttributes */ | 8388608 /* ContainsObjectLiteral */; result.objectFlags |= 128 /* ObjectLiteral */; return result; } } function checkJsxChildren(node, checkMode) { var childrenTypes = []; for (var _i = 0, _a = node.children; _i < _a.length; _i++) { var child = _a[_i]; // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that // because then type of children property will have constituent of string type. if (child.kind === 10 /* JsxText */) { if (!child.containsOnlyWhiteSpaces) { childrenTypes.push(stringType); } } else { childrenTypes.push(checkExpression(child, checkMode)); } } return childrenTypes; } /** * Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element. * (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used) * @param node a JSXAttributes to be resolved of its type */ function checkJsxAttributes(node, checkMode) { return createJsxAttributesTypeFromAttributesProperty(node.parent, /*filter*/ undefined, checkMode); } function getJsxType(name) { var jsxType = jsxTypes.get(name); if (jsxType === undefined) { jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType); } return jsxType; } /** * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement). * May also return unknownSymbol if both of these lookups fail. */ function getIntrinsicTagSymbol(node) { var links = getNodeLinks(node); if (!links.resolvedSymbol) { var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); if (intrinsicElementsType !== unknownType) { // Property case if (!ts.isIdentifier(node.tagName)) throw ts.Debug.fail(); var intrinsicProp = getPropertyOfType(intrinsicElementsType, node.tagName.escapedText); if (intrinsicProp) { links.jsxFlags |= 1 /* IntrinsicNamedElement */; return links.resolvedSymbol = intrinsicProp; } // Intrinsic string indexer case var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */); if (indexSignatureType) { links.jsxFlags |= 2 /* IntrinsicIndexedElement */; return links.resolvedSymbol = intrinsicElementsType.symbol; } // Wasn't found error(node, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(node.tagName), "JSX." + JsxNames.IntrinsicElements); return links.resolvedSymbol = unknownSymbol; } else { if (noImplicitAny) { error(node, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, ts.unescapeLeadingUnderscores(JsxNames.IntrinsicElements)); } return links.resolvedSymbol = unknownSymbol; } } return links.resolvedSymbol; } /** * Given a JSX element that is a class element, finds the Element Instance Type. If the * element is not a class element, or the class element type cannot be determined, returns 'undefined'. * For example, in the element , the element instance type is `MyClass` (not `typeof MyClass`). */ function getJsxElementInstanceType(node, valueType) { ts.Debug.assert(!(valueType.flags & 131072 /* Union */)); if (isTypeAny(valueType)) { // Short-circuit if the class tag is using an element type 'any' return anyType; } // Resolve the signatures, preferring constructor var signatures = getSignaturesOfType(valueType, 1 /* Construct */); if (signatures.length === 0) { // No construct signatures, try call signatures signatures = getSignaturesOfType(valueType, 0 /* Call */); if (signatures.length === 0) { // We found no signatures at all, which is an error error(node.tagName, ts.Diagnostics.JSX_element_type_0_does_not_have_any_construct_or_call_signatures, ts.getTextOfNode(node.tagName)); return unknownType; } } var instantiatedSignatures = []; for (var _i = 0, signatures_3 = signatures; _i < signatures_3.length; _i++) { var signature = signatures_3[_i]; if (signature.typeParameters) { var isJavascript = ts.isInJavaScriptFile(node); var typeArguments = fillMissingTypeArguments(/*typeArguments*/ undefined, signature.typeParameters, /*minTypeArgumentCount*/ 0, isJavascript); instantiatedSignatures.push(getSignatureInstantiation(signature, typeArguments, isJavascript)); } else { instantiatedSignatures.push(signature); } } return getUnionType(ts.map(instantiatedSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); } /** * Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer. * Get a single property from that container if existed. Report an error if there are more than one property. * * @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer * if other string is given or the container doesn't exist, return undefined. */ function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer) { // JSX var jsxNamespace = getGlobalSymbol(JsxNames.JSX, 1920 /* Namespace */, /*diagnosticMessage*/ undefined); // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol] var jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, 793064 /* Type */); // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type] var jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym); // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute var propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType); if (propertiesOfJsxElementAttribPropInterface) { // Element Attributes has zero properties, so the element attributes type will be the class instance type if (propertiesOfJsxElementAttribPropInterface.length === 0) { return ""; } else if (propertiesOfJsxElementAttribPropInterface.length === 1) { return propertiesOfJsxElementAttribPropInterface[0].escapedName; } else if (propertiesOfJsxElementAttribPropInterface.length > 1) { // More than one property on ElementAttributesProperty is an error error(jsxElementAttribPropInterfaceSym.declarations[0], ts.Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, ts.unescapeLeadingUnderscores(nameOfAttribPropContainer)); } } return undefined; } /// e.g. "props" for React.d.ts, /// or 'undefined' if ElementAttributesProperty doesn't exist (which means all /// non-intrinsic elements' attributes type is 'any'), /// or '' if it has 0 properties (which means every /// non-intrinsic elements' attributes type is the element instance type) function getJsxElementPropertiesName() { if (!_hasComputedJsxElementPropertiesName) { _hasComputedJsxElementPropertiesName = true; _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer); } return _jsxElementPropertiesName; } function getJsxElementChildrenPropertyname() { if (!_hasComputedJsxElementChildrenPropertyName) { _hasComputedJsxElementChildrenPropertyName = true; _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer); } return _jsxElementChildrenPropertyName; } function getApparentTypeOfJsxPropsType(propsType) { if (!propsType) { return undefined; } if (propsType.flags & 262144 /* Intersection */) { var propsApparentType = []; for (var _i = 0, _a = propsType.types; _i < _a.length; _i++) { var t = _a[_i]; propsApparentType.push(getApparentType(t)); } return getIntersectionType(propsApparentType); } return getApparentType(propsType); } /** * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component. * Return only attributes type of successfully resolved call signature. * This function assumes that the caller handled other possible element type of the JSX element (e.g. stateful component) * Unlike tryGetAllJsxStatelessFunctionAttributesType, this function is a default behavior of type-checkers. * @param openingLikeElement a JSX opening-like element to find attributes type * @param elementType a type of the opening-like element. This elementType can't be an union type * @param elemInstanceType an element instance type (the result of newing or invoking this tag) * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global */ function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) { ts.Debug.assert(!(elementType.flags & 131072 /* Union */)); if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { var jsxStatelessElementType = getJsxGlobalStatelessElementType(); if (jsxStatelessElementType) { // We don't call getResolvedSignature here because we have already resolve the type of JSX Element. var callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined); if (callSignature !== unknownSignature) { var callReturnType = callSignature && getReturnTypeOfSignature(callSignature); var paramType = callReturnType && (callSignature.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(callSignature.parameters[0])); paramType = getApparentTypeOfJsxPropsType(paramType); if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { // Intersect in JSX.IntrinsicAttributes if it exists var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); if (intrinsicAttributes !== unknownType) { paramType = intersectTypes(intrinsicAttributes, paramType); } return paramType; } } } } return undefined; } /** * Get JSX attributes type by trying to resolve openingLikeElement as a stateless function component. * Return all attributes type of resolved call signature including candidate signatures. * This function assumes that the caller handled other possible element type of the JSX element. * This function is a behavior used by language service when looking up completion in JSX element. * @param openingLikeElement a JSX opening-like element to find attributes type * @param elementType a type of the opening-like element. This elementType can't be an union type * @param elemInstanceType an element instance type (the result of newing or invoking this tag) * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global */ function tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) { ts.Debug.assert(!(elementType.flags & 131072 /* Union */)); if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) { // Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type var jsxStatelessElementType = getJsxGlobalStatelessElementType(); if (jsxStatelessElementType) { // We don't call getResolvedSignature because here we have already resolve the type of JSX Element. var candidatesOutArray = []; getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray); var result = void 0; var allMatchingAttributesType = void 0; for (var _i = 0, candidatesOutArray_1 = candidatesOutArray; _i < candidatesOutArray_1.length; _i++) { var candidate = candidatesOutArray_1[_i]; var callReturnType = getReturnTypeOfSignature(candidate); var paramType = callReturnType && (candidate.parameters.length === 0 ? emptyObjectType : getTypeOfSymbol(candidate.parameters[0])); paramType = getApparentTypeOfJsxPropsType(paramType); if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) { var shouldBeCandidate = true; for (var _a = 0, _b = openingLikeElement.attributes.properties; _a < _b.length; _a++) { var attribute = _b[_a]; if (ts.isJsxAttribute(attribute) && isUnhyphenatedJsxName(attribute.name.escapedText) && !getPropertyOfType(paramType, attribute.name.escapedText)) { shouldBeCandidate = false; break; } } if (shouldBeCandidate) { result = intersectTypes(result, paramType); } allMatchingAttributesType = intersectTypes(allMatchingAttributesType, paramType); } } // If we can't find any matching, just return everything. if (!result) { result = allMatchingAttributesType; } // Intersect in JSX.IntrinsicAttributes if it exists var intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes); if (intrinsicAttributes !== unknownType) { result = intersectTypes(intrinsicAttributes, result); } return result; } } return undefined; } /** * Resolve attributes type of the given opening-like element. The attributes type is a type of attributes associated with the given elementType. * For instance: * declare function Foo(attr: { p1: string}): JSX.Element; * ; // This function will try resolve "Foo" and return an attributes type of "Foo" which is "{ p1: string }" * * The function is intended to initially be called from getAttributesTypeFromJsxOpeningLikeElement which already handle JSX-intrinsic-element.. * This function will try to resolve custom JSX attributes type in following order: string literal, stateless function, and stateful component * * @param openingLikeElement a non-intrinsic JSXOPeningLikeElement * @param shouldIncludeAllStatelessAttributesType a boolean indicating whether to include all attributes types from all stateless function signature * @param elementType an instance type of the given opening-like element. If undefined, the function will check type openinglikeElement's tagname. * @param elementClassType a JSX-ElementClass type. This is a result of looking up ElementClass interface in the JSX global (imported from react.d.ts) * @return attributes type if able to resolve the type of node * anyType if there is no type ElementAttributesProperty or there is an error * emptyObjectType if there is no "prop" in the element instance type */ function resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, elementType, elementClassType) { if (elementType === void 0) { elementType = checkExpression(openingLikeElement.tagName); } if (elementType.flags & 131072 /* Union */) { var types = elementType.types; return getUnionType(types.map(function (type) { return resolveCustomJsxElementAttributesType(openingLikeElement, shouldIncludeAllStatelessAttributesType, type, elementClassType); }), /*subtypeReduction*/ true); } // If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type if (elementType.flags & 2 /* String */) { return anyType; } else if (elementType.flags & 32 /* StringLiteral */) { // If the elemType is a stringLiteral type, we can then provide a check to make sure that the string literal type is one of the Jsx intrinsic element type // For example: // var CustomTag: "h1" = "h1"; // Hello World var intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements); if (intrinsicElementsType !== unknownType) { var stringLiteralTypeName = elementType.value; var intrinsicProp = getPropertyOfType(intrinsicElementsType, ts.escapeLeadingUnderscores(stringLiteralTypeName)); if (intrinsicProp) { return getTypeOfSymbol(intrinsicProp); } var indexSignatureType = getIndexTypeOfType(intrinsicElementsType, 0 /* String */); if (indexSignatureType) { return indexSignatureType; } error(openingLikeElement, ts.Diagnostics.Property_0_does_not_exist_on_type_1, stringLiteralTypeName, "JSX." + JsxNames.IntrinsicElements); } // If we need to report an error, we already done so here. So just return any to prevent any more error downstream return anyType; } // Get the element instance type (the result of newing or invoking this tag) var elemInstanceType = getJsxElementInstanceType(openingLikeElement, elementType); // If we should include all stateless attributes type, then get all attributes type from all stateless function signature. // Otherwise get only attributes type from the signature picked by choose-overload logic. var statelessAttributesType = shouldIncludeAllStatelessAttributesType ? tryGetAllJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType) : defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement, elementType, elemInstanceType, elementClassType); if (statelessAttributesType) { return statelessAttributesType; } // Issue an error if this return type isn't assignable to JSX.ElementClass if (elementClassType) { checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, ts.Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements); } if (isTypeAny(elemInstanceType)) { return elemInstanceType; } var propsName = getJsxElementPropertiesName(); if (propsName === undefined) { // There is no type ElementAttributesProperty, return 'any' return anyType; } else if (propsName === "") { // If there is no e.g. 'props' member in ElementAttributesProperty, use the element class type instead return elemInstanceType; } else { var attributesType = getTypeOfPropertyOfType(elemInstanceType, propsName); if (!attributesType) { // There is no property named 'props' on this instance type return emptyObjectType; } else if (isTypeAny(attributesType) || (attributesType === unknownType)) { // Props is of type 'any' or unknown return attributesType; } else { // Normal case -- add in IntrinsicClassElements and IntrinsicElements var apparentAttributesType = attributesType; var intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes); if (intrinsicClassAttribs !== unknownType) { var typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol); if (typeParams) { if (typeParams.length === 1) { apparentAttributesType = intersectTypes(createTypeReference(intrinsicClassAttribs, [elemInstanceType]), apparentAttributesType); } } else { apparentAttributesType = intersectTypes(attributesType, intrinsicClassAttribs); } } var intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes); if (intrinsicAttribs !== unknownType) { apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType); } return apparentAttributesType; } } } /** * Get attributes type of the given intrinsic opening-like Jsx element by resolving the tag name. * The function is intended to be called from a function which has checked that the opening element is an intrinsic element. * @param node an intrinsic JSX opening-like element */ function getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node) { ts.Debug.assert(isJsxIntrinsicIdentifier(node.tagName)); var links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { var symbol = getIntrinsicTagSymbol(node); if (links.jsxFlags & 1 /* IntrinsicNamedElement */) { return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol); } else if (links.jsxFlags & 2 /* IntrinsicIndexedElement */) { return links.resolvedJsxElementAttributesType = getIndexInfoOfSymbol(symbol, 0 /* String */).type; } else { return links.resolvedJsxElementAttributesType = unknownType; } } return links.resolvedJsxElementAttributesType; } /** * Get attributes type of the given custom opening-like JSX element. * This function is intended to be called from a caller that handles intrinsic JSX element already. * @param node a custom JSX opening-like element * @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component */ function getCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType) { var links = getNodeLinks(node); var linkLocation = shouldIncludeAllStatelessAttributesType ? "resolvedJsxElementAllAttributesType" : "resolvedJsxElementAttributesType"; if (!links[linkLocation]) { var elemClassType = getJsxGlobalElementClassType(); return links[linkLocation] = resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, /*elementType*/ undefined, elemClassType); } return links[linkLocation]; } /** * Get all possible attributes type, especially from an overload stateless function component, of the given JSX opening-like element. * This function is called by language service (see: completions-tryGetGlobalSymbols). * @param node a JSX opening-like element to get attributes type for */ function getAllAttributesTypeFromJsxOpeningLikeElement(node) { if (isJsxIntrinsicIdentifier(node.tagName)) { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); } else { // Because in language service, the given JSX opening-like element may be incomplete and therefore, // we can't resolve to exact signature if the element is a stateless function component so the best thing to do is return all attributes type from all overloads. return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ true); } } /** * Get the attributes type, which indicates the attributes that are valid on the given JSXOpeningLikeElement. * @param node a JSXOpeningLikeElement node * @return an attributes type of the given node */ function getAttributesTypeFromJsxOpeningLikeElement(node) { if (isJsxIntrinsicIdentifier(node.tagName)) { return getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node); } else { return getCustomJsxElementAttributesType(node, /*shouldIncludeAllStatelessAttributesType*/ false); } } /** * Given a JSX attribute, returns the symbol for the corresponds property * of the element attributes type. Will return unknownSymbol for attributes * that have no matching element attributes type property. */ function getJsxAttributePropertySymbol(attrib) { var attributesType = getAttributesTypeFromJsxOpeningLikeElement(attrib.parent.parent); var prop = getPropertyOfType(attributesType, attrib.name.escapedText); return prop || unknownSymbol; } function getJsxGlobalElementClassType() { if (!deferredJsxElementClassType) { deferredJsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass); } return deferredJsxElementClassType; } function getJsxGlobalElementType() { if (!deferredJsxElementType) { deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element); } return deferredJsxElementType; } function getJsxGlobalStatelessElementType() { if (!deferredJsxStatelessElementType) { var jsxElementType = getJsxGlobalElementType(); if (jsxElementType) { deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]); } } return deferredJsxStatelessElementType; } /** * Returns all the properties of the Jsx.IntrinsicElements interface */ function getJsxIntrinsicTagNames() { var intrinsics = getJsxType(JsxNames.IntrinsicElements); return intrinsics ? getPropertiesOfType(intrinsics) : ts.emptyArray; } function checkJsxPreconditions(errorNode) { // Preconditions for using JSX if ((compilerOptions.jsx || 0 /* None */) === 0 /* None */) { error(errorNode, ts.Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided); } if (getJsxGlobalElementType() === undefined) { if (noImplicitAny) { error(errorNode, ts.Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist); } } } function checkJsxOpeningLikeElementOrOpeningFragment(node) { var isNodeOpeningLikeElement = ts.isJsxOpeningLikeElement(node); if (isNodeOpeningLikeElement) { checkGrammarJsxElement(node); } checkJsxPreconditions(node); // The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import. // And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error. var reactRefErr = diagnostics && compilerOptions.jsx === 2 /* React */ ? ts.Diagnostics.Cannot_find_name_0 : undefined; var reactNamespace = getJsxNamespace(); var reactLocation = isNodeOpeningLikeElement ? node.tagName : node; var reactSym = resolveName(reactLocation, reactNamespace, 107455 /* Value */, reactRefErr, reactNamespace, /*isUse*/ true); if (reactSym) { // Mark local symbol as referenced here because it might not have been marked // if jsx emit was not react as there wont be error being emitted reactSym.isReferenced = true; // If react symbol is alias, mark it as refereced if (reactSym.flags & 2097152 /* Alias */ && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) { markAliasSymbolAsReferenced(reactSym); } } if (isNodeOpeningLikeElement) { checkJsxAttributesAssignableToTagNameAttributes(node); } else { checkJsxChildren(node.parent); } } /** * Check if a property with the given name is known anywhere in the given type. In an object type, a property * is considered known if * 1. the object type is empty and the check is for assignability, or * 2. if the object type has index signatures, or * 3. if the property is actually declared in the object type * (this means that 'toString', for example, is not usually a known property). * 4. In a union or intersection type, * a property is considered known if it is known in any constituent type. * @param targetType a type to search a given name in * @param name a property name to search * @param isComparingJsxAttributes a boolean flag indicating whether we are searching in JsxAttributesType */ function isKnownProperty(targetType, name, isComparingJsxAttributes) { if (targetType.flags & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(targetType); if (resolved.stringIndexInfo || resolved.numberIndexInfo && isNumericLiteralName(name) || getPropertyOfObjectType(targetType, name) || isComparingJsxAttributes && !isUnhyphenatedJsxName(name)) { // For JSXAttributes, if the attribute has a hyphenated name, consider that the attribute to be known. return true; } } else if (targetType.flags & 393216 /* UnionOrIntersection */) { for (var _i = 0, _a = targetType.types; _i < _a.length; _i++) { var t = _a[_i]; if (isKnownProperty(t, name, isComparingJsxAttributes)) { return true; } } } return false; } /** * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" * Check assignablity between given attributes property, "source attributes", and the "target attributes" * @param openingLikeElement an opening-like JSX element to check its JSXAttributes */ function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement) { // The function involves following steps: // 1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType. // During these steps, we will try to resolve the tagName as intrinsic name, stateless function, stateful component (in the order) // 2. Solved JSX attributes type given by users, sourceAttributesType, which is by resolving "attributes" property of the JSX opening-like element. // 3. Check if the two are assignable to each other // targetAttributesType is a type of an attributes from resolving tagName of an opening-like JSX element. var targetAttributesType = isJsxIntrinsicIdentifier(openingLikeElement.tagName) ? getIntrinsicAttributesTypeFromJsxOpeningLikeElement(openingLikeElement) : getCustomJsxElementAttributesType(openingLikeElement, /*shouldIncludeAllStatelessAttributesType*/ false); // sourceAttributesType is a type of an attributes properties. // i.e
// attr1 and attr2 are treated as JSXAttributes attached in the JsxOpeningLikeElement as "attributes". var sourceAttributesType = createJsxAttributesTypeFromAttributesProperty(openingLikeElement, function (attribute) { return isUnhyphenatedJsxName(attribute.escapedName) || !!(getPropertyOfType(targetAttributesType, attribute.escapedName)); }); // If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type. // but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass. if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || sourceAttributesType.properties.length > 0)) { error(openingLikeElement, ts.Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, ts.unescapeLeadingUnderscores(getJsxElementPropertiesName())); } else { // Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties var isSourceAttributeTypeAssignableToTarget = checkTypeAssignableTo(sourceAttributesType, targetAttributesType, openingLikeElement.attributes.properties.length > 0 ? openingLikeElement.attributes : openingLikeElement); // After we check for assignability, we will do another pass to check that all explicitly specified attributes have correct name corresponding in targetAttributeType. // This will allow excess properties in spread type as it is very common pattern to spread outter attributes into React component in its render method. if (isSourceAttributeTypeAssignableToTarget && !isTypeAny(sourceAttributesType) && !isTypeAny(targetAttributesType)) { for (var _i = 0, _a = openingLikeElement.attributes.properties; _i < _a.length; _i++) { var attribute = _a[_i]; if (ts.isJsxAttribute(attribute) && !isKnownProperty(targetAttributesType, attribute.name.escapedText, /*isComparingJsxAttributes*/ true)) { error(attribute, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.idText(attribute.name), typeToString(targetAttributesType)); // We break here so that errors won't be cascading break; } } } } } function checkJsxExpression(node, checkMode) { if (node.expression) { var type = checkExpression(node.expression, checkMode); if (node.dotDotDotToken && type !== anyType && !isArrayType(type)) { error(node, ts.Diagnostics.JSX_spread_child_must_be_an_array_type); } return type; } else { return unknownType; } } // If a symbol is a synthesized symbol with no value declaration, we assume it is a property. Example of this are the synthesized // '.prototype' property as well as synthesized tuple index properties. function getDeclarationKindFromSymbol(s) { return s.valueDeclaration ? s.valueDeclaration.kind : 150 /* PropertyDeclaration */; } function getDeclarationNodeFlagsFromSymbol(s) { return s.valueDeclaration ? ts.getCombinedNodeFlags(s.valueDeclaration) : 0; } function isMethodLike(symbol) { return !!(symbol.flags & 8192 /* Method */ || ts.getCheckFlags(symbol) & 4 /* SyntheticMethod */); } /** * Check whether the requested property access is valid. * Returns true if node is a valid property access, and false otherwise. * @param node The node to be checked. * @param left The left hand side of the property access (e.g.: the super in `super.foo`). * @param type The type of left. * @param prop The symbol for the right hand side of the property access. */ function checkPropertyAccessibility(node, left, type, prop) { var flags = ts.getDeclarationModifierFlagsFromSymbol(prop); var errorNode = node.kind === 180 /* PropertyAccessExpression */ || node.kind === 227 /* VariableDeclaration */ ? node.name : node.right; if (ts.getCheckFlags(prop) & 256 /* ContainsPrivate */) { // Synthetic property with private constituent property error(errorNode, ts.Diagnostics.Property_0_has_conflicting_declarations_and_is_inaccessible_in_type_1, symbolToString(prop), typeToString(type)); return false; } if (left.kind === 97 /* SuperKeyword */) { // TS 1.0 spec (April 2014): 4.8.2 // - In a constructor, instance member function, instance member accessor, or // instance member variable initializer where this references a derived class instance, // a super property access is permitted and must specify a public instance member function of the base class. // - In a static member function or static member accessor // where this references the constructor function object of a derived class, // a super property access is permitted and must specify a public static member function of the base class. if (languageVersion < 2 /* ES2015 */) { if (symbolHasNonMethodDeclaration(prop)) { error(errorNode, ts.Diagnostics.Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword); return false; } } if (flags & 128 /* Abstract */) { // A method cannot be accessed in a super property access if the method is abstract. // This error could mask a private property access error. But, a member // cannot simultaneously be private and abstract, so this will trigger an // additional error elsewhere. error(errorNode, ts.Diagnostics.Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression, symbolToString(prop), typeToString(getDeclaringClass(prop))); return false; } } // Referencing abstract properties within their own constructors is not allowed if ((flags & 128 /* Abstract */) && ts.isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) { var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) { error(errorNode, ts.Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), ts.getTextOfIdentifierOrLiteral(declaringClassDeclaration.name)); return false; } } // Public properties are otherwise accessible. if (!(flags & 24 /* NonPublicAccessibilityModifier */)) { return true; } // Property is known to be private or protected at this point // Private property is accessible if the property is within the declaring class if (flags & 8 /* Private */) { var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)); if (!isNodeWithinClass(node, declaringClassDeclaration)) { error(errorNode, ts.Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop))); return false; } return true; } // Property is known to be protected at this point // All protected properties of a supertype are accessible in a super access if (left.kind === 97 /* SuperKeyword */) { return true; } // Find the first enclosing class that has the declaring classes of the protected constituents // of the property as base classes var enclosingClass = forEachEnclosingClass(node, function (enclosingDeclaration) { var enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)); return isClassDerivedFromDeclaringClasses(enclosingClass, prop) ? enclosingClass : undefined; }); // A protected property is accessible if the property is within the declaring class or classes derived from it if (!enclosingClass) { error(errorNode, ts.Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(getDeclaringClass(prop) || type)); return false; } // No further restrictions for static properties if (flags & 32 /* Static */) { return true; } if (type.flags & 32768 /* TypeParameter */) { // get the original type -- represented as the type constraint of the 'this' type type = type.isThisType ? getConstraintOfTypeParameter(type) : getBaseConstraintOfType(type); } if (!type || !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 symbolHasNonMethodDeclaration(symbol) { return forEachProperty(symbol, function (prop) { var propKind = getDeclarationKindFromSymbol(prop); return propKind !== 152 /* MethodDeclaration */ && propKind !== 151 /* MethodSignature */; }); } function checkNonNullExpression(node) { return checkNonNullType(checkExpression(node), node); } function checkNonNullType(type, errorNode) { var kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & 12288 /* Nullable */; if (kind) { error(errorNode, kind & 4096 /* Undefined */ ? kind & 8192 /* Null */ ? ts.Diagnostics.Object_is_possibly_null_or_undefined : ts.Diagnostics.Object_is_possibly_undefined : ts.Diagnostics.Object_is_possibly_null); var t = getNonNullableType(type); return t.flags & (12288 /* Nullable */ | 16384 /* Never */) ? unknownType : t; } return type; } function checkPropertyAccessExpression(node) { return checkPropertyAccessExpressionOrQualifiedName(node, node.expression, node.name); } function checkQualifiedName(node) { return checkPropertyAccessExpressionOrQualifiedName(node, node.left, node.right); } function checkPropertyAccessExpressionOrQualifiedName(node, left, right) { var propType; var leftSymbol = getNodeLinks(left) && getNodeLinks(left).resolvedSymbol; var leftWasReferenced = leftSymbol && getSymbolLinks(leftSymbol).referenced; var leftType = checkNonNullExpression(left); var apparentType = getApparentType(getWidenedType(leftType)); if (isTypeAny(apparentType) || apparentType === silentNeverType) { return apparentType; } var assignmentKind = ts.getAssignmentTargetKind(node); var prop = getPropertyOfType(apparentType, right.escapedText); if (!prop) { var indexInfo = getIndexInfoOfType(apparentType, 0 /* String */); if (!(indexInfo && indexInfo.type)) { if (right.escapedText && !checkAndReportErrorForExtendingInterface(node)) { reportNonexistentProperty(right, leftType.flags & 32768 /* TypeParameter */ && leftType.isThisType ? apparentType : leftType); } return unknownType; } if (indexInfo.isReadonly && (ts.isAssignmentTarget(node) || ts.isDeleteTarget(node))) { error(node, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(apparentType)); } propType = indexInfo.type; } else { checkPropertyNotUsedBeforeDeclaration(prop, node, right); markPropertyAsReferenced(prop, node, left.kind === 99 /* ThisKeyword */); // Reset the referenced-ness of the LHS expression if this access refers to a const enum or const enum only module leftSymbol = getNodeLinks(left) && getNodeLinks(left).resolvedSymbol; if (leftSymbol && !leftWasReferenced && getSymbolLinks(leftSymbol).referenced && !(isNonLocalAlias(leftSymbol, /*excludes*/ 107455 /* Value */) && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(prop))) { getSymbolLinks(leftSymbol).referenced = undefined; } getNodeLinks(node).resolvedSymbol = prop; checkPropertyAccessibility(node, left, apparentType, prop); if (assignmentKind) { if (isReferenceToReadonlyEntity(node, prop) || isReferenceThroughNamespaceImport(node)) { error(right, ts.Diagnostics.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property, ts.idText(right)); return unknownType; } } propType = getDeclaredOrApparentType(prop, node); } // 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 !== 180 /* PropertyAccessExpression */ || assignmentKind === 1 /* Definite */ || prop && !(prop.flags & (3 /* Variable */ | 4 /* Property */ | 98304 /* Accessor */)) && !(prop.flags & 8192 /* Method */ && propType.flags & 131072 /* Union */)) { return propType; } // If strict null checks and strict property initialization checks are enabled, if we have // a this.xxx property access, if the property is an instance property without an initializer, // and if we are in a constructor of the same class as the property declaration, assume that // the property is uninitialized at the top of the control flow. var assumeUninitialized = false; if (strictNullChecks && strictPropertyInitialization && left.kind === 99 /* ThisKeyword */) { var declaration = prop && prop.valueDeclaration; if (declaration && isInstancePropertyWithoutInitializer(declaration)) { var flowContainer = getControlFlowContainer(node); if (flowContainer.kind === 153 /* Constructor */ && flowContainer.parent === declaration.parent) { assumeUninitialized = true; } } } var flowType = getFlowTypeOfReference(node, propType, assumeUninitialized ? getOptionalType(propType) : propType); if (assumeUninitialized && !(getFalsyFlags(propType) & 4096 /* Undefined */) && getFalsyFlags(flowType) & 4096 /* Undefined */) { error(right, ts.Diagnostics.Property_0_is_used_before_being_assigned, symbolToString(prop)); // Return the declared type to reduce follow-on errors return propType; } return assignmentKind ? getBaseTypeOfLiteralType(flowType) : flowType; } function checkPropertyNotUsedBeforeDeclaration(prop, node, right) { var valueDeclaration = prop.valueDeclaration; if (!valueDeclaration) { return; } if (isInPropertyInitializer(node) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) && !isPropertyDeclaredInAncestorClass(prop)) { error(right, ts.Diagnostics.Block_scoped_variable_0_used_before_its_declaration, ts.idText(right)); } else if (valueDeclaration.kind === 230 /* ClassDeclaration */ && node.parent.kind !== 160 /* TypeReference */ && !(valueDeclaration.flags & 2097152 /* Ambient */) && !isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) { error(right, ts.Diagnostics.Class_0_used_before_its_declaration, ts.idText(right)); } } function isInPropertyInitializer(node) { return !!ts.findAncestor(node, function (node) { switch (node.kind) { case 150 /* PropertyDeclaration */: return true; case 265 /* PropertyAssignment */: // We might be in `a = { b: this.b }`, so keep looking. See `tests/cases/compiler/useBeforeDeclaration_propertyAssignment.ts`. return false; default: return ts.isExpressionNode(node) ? false : "quit"; } }); } /** * It's possible that "prop.valueDeclaration" is a local declaration, but the property was also declared in a superclass. * In that case we won't consider it used before its declaration, because it gets its value from the superclass' declaration. */ function isPropertyDeclaredInAncestorClass(prop) { var classType = getTypeOfSymbol(prop.parent); while (true) { classType = getSuperClass(classType); if (!classType) { return false; } var superProperty = getPropertyOfObjectType(classType, prop.escapedName); if (superProperty && superProperty.valueDeclaration) { return true; } } } function getSuperClass(classType) { var x = getBaseTypes(classType); if (x.length === 0) { return undefined; } ts.Debug.assert(x.length === 1); return x[0]; } function reportNonexistentProperty(propNode, containingType) { var errorInfo; if (containingType.flags & 131072 /* Union */ && !(containingType.flags & 16382 /* Primitive */)) { for (var _i = 0, _a = containingType.types; _i < _a.length; _i++) { var subtype = _a[_i]; if (!getPropertyOfType(subtype, propNode.escapedText)) { errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(subtype)); break; } } } var suggestion = getSuggestionForNonexistentProperty(propNode, containingType); if (suggestion !== undefined) { errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2, ts.declarationNameToString(propNode), typeToString(containingType), suggestion); } else { errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Property_0_does_not_exist_on_type_1, ts.declarationNameToString(propNode), typeToString(containingType)); } diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(propNode, errorInfo)); } function getSuggestionForNonexistentProperty(node, containingType) { var suggestion = getSpellingSuggestionForName(ts.idText(node), getPropertiesOfType(containingType), 107455 /* Value */); return suggestion && ts.symbolName(suggestion); } function getSuggestionForNonexistentSymbol(location, outerName, meaning) { ts.Debug.assert(outerName !== undefined, "outername should always be defined"); var result = resolveNameHelper(location, outerName, meaning, /*nameNotFoundMessage*/ undefined, outerName, /*isUse*/ false, function (symbols, name, meaning) { ts.Debug.assertEqual(outerName, name, "name should equal outerName"); var symbol = getSymbol(symbols, name, meaning); // Sometimes the symbol is found when location is a return type of a function: `typeof x` and `x` is declared in the body of the function // So the table *contains* `x` but `x` isn't actually in scope. // However, resolveNameHelper will continue and call this callback again, so we'll eventually get a correct suggestion. return symbol || getSpellingSuggestionForName(ts.unescapeLeadingUnderscores(name), ts.arrayFrom(symbols.values()), meaning); }); return result && ts.symbolName(result); } /** * Given a name and a list of symbols whose names are *not* equal to the name, return a spelling suggestion if there is one that is close enough. * Names less than length 3 only check for case-insensitive equality, not levenshtein distance. * * If there is a candidate that's the same except for case, return that. * If there is a candidate that's within one edit of the name, return that. * Otherwise, return the candidate with the smallest Levenshtein distance, * except for candidates: * * With no name * * Whose meaning doesn't match the `meaning` parameter. * * Whose length differs from the target name by more than 0.34 of the length of the name. * * Whose levenshtein distance is more than 0.4 of the length of the name * (0.4 allows 1 substitution/transposition for every 5 characters, * and 1 insertion/deletion at 3 characters) */ function getSpellingSuggestionForName(name, symbols, meaning) { var maximumLengthDifference = Math.min(2, Math.floor(name.length * 0.34)); var bestDistance = Math.floor(name.length * 0.4) + 1; // If the best result isn't better than this, don't bother. var bestCandidate; var justCheckExactMatches = false; var nameLowerCase = name.toLowerCase(); for (var _i = 0, symbols_3 = symbols; _i < symbols_3.length; _i++) { var candidate = symbols_3[_i]; var candidateName = ts.symbolName(candidate); if (!(candidate.flags & meaning && Math.abs(candidateName.length - nameLowerCase.length) <= maximumLengthDifference)) { continue; } var candidateNameLowerCase = candidateName.toLowerCase(); if (candidateNameLowerCase === nameLowerCase) { return candidate; } if (justCheckExactMatches) { continue; } if (candidateName.length < 3) { // Don't bother, user would have noticed a 2-character name having an extra character continue; } // Only care about a result better than the best so far. var distance = levenshteinWithMax(nameLowerCase, candidateNameLowerCase, bestDistance - 1); if (distance === undefined) { continue; } if (distance < 3) { justCheckExactMatches = true; bestCandidate = candidate; } else { ts.Debug.assert(distance < bestDistance); // Else `levenshteinWithMax` should return undefined bestDistance = distance; bestCandidate = candidate; } } return bestCandidate; } function levenshteinWithMax(s1, s2, max) { var previous = new Array(s2.length + 1); var current = new Array(s2.length + 1); /** Represents any value > max. We don't care about the particular value. */ var big = max + 1; for (var i = 0; i <= s2.length; i++) { previous[i] = i; } for (var i = 1; i <= s1.length; i++) { var c1 = s1.charCodeAt(i - 1); var minJ = i > max ? i - max : 1; var maxJ = s2.length > max + i ? max + i : s2.length; current[0] = i; /** Smallest value of the matrix in the ith column. */ var colMin = i; for (var j = 1; j < minJ; j++) { current[j] = big; } for (var j = minJ; j <= maxJ; j++) { var dist = c1 === s2.charCodeAt(j - 1) ? previous[j - 1] : Math.min(/*delete*/ previous[j] + 1, /*insert*/ current[j - 1] + 1, /*substitute*/ previous[j - 1] + 2); current[j] = dist; colMin = Math.min(colMin, dist); } for (var j = maxJ + 1; j <= s2.length; j++) { current[j] = big; } if (colMin > max) { // Give up -- everything in this column is > max and it can't get better in future columns. return undefined; } var temp = previous; previous = current; current = temp; } var res = previous[s2.length]; return res > max ? undefined : res; } function markPropertyAsReferenced(prop, nodeForCheckWriteOnly, isThisAccess) { if (prop && noUnusedIdentifiers && (prop.flags & 106500 /* ClassMember */) && prop.valueDeclaration && ts.hasModifier(prop.valueDeclaration, 8 /* Private */) && !(nodeForCheckWriteOnly && ts.isWriteOnlyAccess(nodeForCheckWriteOnly))) { if (isThisAccess) { // Find any FunctionLikeDeclaration because those create a new 'this' binding. But this should only matter for methods (or getters/setters). var containingMethod = ts.findAncestor(nodeForCheckWriteOnly, ts.isFunctionLikeDeclaration); if (containingMethod && containingMethod.symbol === prop) { return; } } if (ts.getCheckFlags(prop) & 1 /* Instantiated */) { getSymbolLinks(prop).target.isReferenced = true; } else { prop.isReferenced = true; } } } function isValidPropertyAccess(node, propertyName) { var left = node.kind === 180 /* PropertyAccessExpression */ ? node.expression : node.left; return isValidPropertyAccessWithType(node, left, propertyName, getWidenedType(checkExpression(left))); } function isValidPropertyAccessWithType(node, left, propertyName, type) { if (type !== unknownType && !isTypeAny(type)) { var prop = getPropertyOfType(type, propertyName); if (prop) { return checkPropertyAccessibility(node, left, type, prop); } // In js files properties of unions are allowed in completion if (ts.isInJavaScriptFile(left) && (type.flags & 131072 /* Union */)) { for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var elementType = _a[_i]; if (isValidPropertyAccessWithType(node, left, propertyName, elementType)) { return true; } } } return false; } return true; } /** * Return the symbol of the for-in variable declared or referenced by the given for-in statement. */ function getForInVariableSymbol(node) { var initializer = node.initializer; if (initializer.kind === 228 /* VariableDeclarationList */) { var variable = initializer.declarations[0]; if (variable && !ts.isBindingPattern(variable.name)) { return getSymbolOfNode(variable); } } else if (initializer.kind === 71 /* Identifier */) { return getResolvedSymbol(initializer); } return undefined; } /** * Return true if the given type is considered to have numeric property names. */ function hasNumericPropertyNames(type) { return getIndexTypeOfType(type, 1 /* Number */) && !getIndexTypeOfType(type, 0 /* String */); } /** * Return true if given node is an expression consisting of an identifier (possibly parenthesized) * that references a for-in variable for an object with numeric property names. */ function isForInVariableForNumericPropertyNames(expr) { var e = ts.skipParentheses(expr); if (e.kind === 71 /* Identifier */) { var symbol = getResolvedSymbol(e); if (symbol.flags & 3 /* Variable */) { var child = expr; var node = expr.parent; while (node) { if (node.kind === 216 /* ForInStatement */ && child === node.statement && getForInVariableSymbol(node) === symbol && hasNumericPropertyNames(getTypeOfExpression(node.expression))) { return true; } child = node; node = node.parent; } } } return false; } function checkIndexedAccess(node) { var objectType = checkNonNullExpression(node.expression); var indexExpression = node.argumentExpression; if (!indexExpression) { var sourceFile = ts.getSourceFileOfNode(node); if (node.parent.kind === 183 /* NewExpression */ && node.parent.expression === node) { var start = ts.skipTrivia(sourceFile.text, node.expression.end); var end = node.end; grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.new_T_cannot_be_used_to_create_an_array_Use_new_Array_T_instead); } else { var start = node.end - "]".length; var end = node.end; grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Expression_expected); } return unknownType; } var indexType = isForInVariableForNumericPropertyNames(indexExpression) ? numberType : checkExpression(indexExpression); if (objectType === unknownType || objectType === silentNeverType) { return objectType; } if (isConstEnumObjectType(objectType) && indexExpression.kind !== 9 /* StringLiteral */) { error(indexExpression, ts.Diagnostics.A_const_enum_member_can_only_be_accessed_using_a_string_literal); return unknownType; } return checkIndexedAccessIndexType(getIndexedAccessType(objectType, indexType, node), node); } function checkThatExpressionIsProperSymbolReference(expression, expressionType, reportError) { if (expressionType === unknownType) { // There is already an error, so no need to report one. return false; } if (!ts.isWellKnownSymbolSyntactically(expression)) { return false; } // Make sure the property type is the primitive symbol type if ((expressionType.flags & 1536 /* ESSymbolLike */) === 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., so make sure Symbol actually resolves to the // global Symbol object var leftHandSide = expression.expression; var leftHandSideSymbol = getResolvedSymbol(leftHandSide); if (!leftHandSideSymbol) { return false; } var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ true); if (!globalESSymbol) { // Already errored when we tried to look up the symbol return false; } if (leftHandSideSymbol !== globalESSymbol) { if (reportError) { error(leftHandSide, ts.Diagnostics.Symbol_reference_does_not_refer_to_the_global_Symbol_constructor_object); } return false; } return true; } function callLikeExpressionMayHaveTypeArguments(node) { // TODO: Also include tagged templates (https://github.com/Microsoft/TypeScript/issues/11947) return ts.isCallOrNewExpression(node); } function resolveUntypedCall(node) { if (callLikeExpressionMayHaveTypeArguments(node)) { // Check type arguments even though we will give an error that untyped calls may not accept type arguments. // This gets us diagnostics for the type arguments and marks them as referenced. ts.forEach(node.typeArguments, checkSourceElement); } if (node.kind === 184 /* TaggedTemplateExpression */) { checkExpression(node.template); } else if (node.kind !== 148 /* Decorator */) { ts.forEach(node.arguments, function (argument) { checkExpression(argument); }); } return anySignature; } function resolveErrorCall(node) { resolveUntypedCall(node); return unknownSignature; } // Re-order candidate signatures into the result array. Assumes the result array to be empty. // The candidate list orders groups in reverse, but within a group signatures are kept in declaration order // A nit here is that we reorder only signatures that belong to the same symbol, // so order how inherited signatures are processed is still preserved. // interface A { (x: string): void } // interface B extends A { (x: 'foo'): string } // const b: B; // b('foo') // <- here overloads should be processed as [(x:'foo'): string, (x: string): void] function reorderCandidates(signatures, result) { var lastParent; var lastSymbol; var cutoffIndex = 0; var index; var specializedIndex = -1; var spliceIndex; ts.Debug.assert(!result.length); for (var _i = 0, signatures_4 = signatures; _i < signatures_4.length; _i++) { var signature = signatures_4[_i]; var symbol = signature.declaration && getSymbolOfNode(signature.declaration); var parent = signature.declaration && signature.declaration.parent; if (!lastSymbol || symbol === lastSymbol) { if (lastParent && parent === lastParent) { index++; } else { lastParent = parent; index = cutoffIndex; } } else { // current declaration belongs to a different symbol // set cutoffIndex so re-orderings in the future won't change result set from 0 to cutoffIndex index = cutoffIndex = result.length; lastParent = parent; } lastSymbol = symbol; // specialized signatures always need to be placed before non-specialized signatures regardless // of the cutoff position; see GH#1133 if (signature.hasLiteralTypes) { specializedIndex++; spliceIndex = specializedIndex; // The cutoff index always needs to be greater than or equal to the specialized signature index // in order to prevent non-specialized signatures from being added before a specialized // signature. cutoffIndex++; } else { spliceIndex = index; } result.splice(spliceIndex, 0, signature); } } function getSpreadArgumentIndex(args) { for (var i = 0; i < args.length; i++) { var arg = args[i]; if (arg && arg.kind === 199 /* SpreadElement */) { return i; } } return -1; } function hasCorrectArity(node, args, signature, signatureHelpTrailingComma) { if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } var argCount; // Apparent number of arguments we will have in this call var typeArguments; // Type arguments (undefined if none) var callIsIncomplete; // In incomplete call we want to be lenient when we have too few arguments var spreadArgIndex = -1; if (ts.isJsxOpeningLikeElement(node)) { // The arity check will be done in "checkApplicableSignatureForJsxOpeningLikeElement". return true; } if (node.kind === 184 /* 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 === 197 /* TemplateExpression */) { // If a tagged template expression lacks a tail literal, the call is incomplete. // Specifically, a template only can end in a TemplateTail or a Missing literal. var templateExpression = tagExpression.template; var lastSpan = ts.lastOrUndefined(templateExpression.templateSpans); ts.Debug.assert(lastSpan !== undefined); // we should always have at least one span. callIsIncomplete = ts.nodeIsMissing(lastSpan.literal) || !!lastSpan.literal.isUnterminated; } else { // If the template didn't end in a backtick, or its beginning occurred right prior to EOF, // then this might actually turn out to be a TemplateHead in the future; // so we consider the call to be incomplete. var templateLiteral = tagExpression.template; ts.Debug.assert(templateLiteral.kind === 13 /* NoSubstitutionTemplateLiteral */); callIsIncomplete = !!templateLiteral.isUnterminated; } } else if (node.kind === 148 /* Decorator */) { typeArguments = undefined; argCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); } else { var callExpression = node; if (!callExpression.arguments) { // This only happens when we have something of the form: 'new C' ts.Debug.assert(callExpression.kind === 183 /* NewExpression */); return signature.minArgumentCount === 0; } argCount = signatureHelpTrailingComma ? args.length + 1 : args.length; // If we are missing the close parenthesis, the call is incomplete. callIsIncomplete = callExpression.arguments.end === callExpression.end; typeArguments = callExpression.typeArguments; spreadArgIndex = getSpreadArgumentIndex(args); } // If the user supplied type arguments, but the number of type arguments does not match // the declared number of type parameters, the call has an incorrect arity. var numTypeParameters = ts.length(signature.typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(signature.typeParameters); var hasRightNumberOfTypeArgs = !typeArguments || (typeArguments.length >= minTypeArgumentCount && typeArguments.length <= numTypeParameters); if (!hasRightNumberOfTypeArgs) { return false; } // If a spread argument is present, check that it corresponds to a rest parameter or at least that it's in the valid range. if (spreadArgIndex >= 0) { return isRestParameterIndex(signature, spreadArgIndex) || signature.minArgumentCount <= spreadArgIndex && spreadArgIndex < signature.parameters.length; } // 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 & 65536 /* Object */) { var resolved = resolveStructuredTypeMembers(type); if (resolved.callSignatures.length === 1 && resolved.constructSignatures.length === 0 && resolved.properties.length === 0 && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { return resolved.callSignatures[0]; } } return undefined; } // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec) function instantiateSignatureInContextOf(signature, contextualSignature, contextualMapper, compareTypes) { var context = createInferenceContext(signature, 1 /* InferUnionTypes */, compareTypes); forEachMatchingParameterType(contextualSignature, signature, function (source, target) { // Type parameters from outer context referenced by source type are fixed by instantiation of the source type inferTypes(context.inferences, instantiateType(source, contextualMapper || identityMapper), target); }); if (!contextualMapper) { inferTypes(context.inferences, getReturnTypeOfSignature(contextualSignature), getReturnTypeOfSignature(signature), 8 /* ReturnType */); } return getSignatureInstantiation(signature, getInferredTypes(context), ts.isInJavaScriptFile(contextualSignature.declaration)); } function inferTypeArguments(node, signature, args, excludeArgument, context) { // Clear out all the inference results from the last time inferTypeArguments was called on this context for (var _i = 0, _a = context.inferences; _i < _a.length; _i++) { var inference = _a[_i]; // As an optimization, we don't have to clear (and later recompute) inferred types // for type parameters that have already been fixed on the previous call to inferTypeArguments. // It would be just as correct to reset all of them. But then we'd be repeating the same work // for the type parameters that were fixed, namely the work done by getInferredType. if (!inference.isFixed) { inference.inferredType = undefined; } } // If a contextual type is available, infer from that type to the return type of the call expression. For // example, given a 'function wrap(cb: (x: T) => U): (x: T) => U' and a call expression // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the // return type of 'wrap'. if (node.kind !== 148 /* Decorator */) { var contextualType = getContextualType(node); if (contextualType) { // We clone the contextual mapper to avoid disturbing a resolution in progress for an // outer call expression. Effectively we just want a snapshot of whatever has been // inferred for any outer call expression so far. var instantiatedType = instantiateType(contextualType, cloneTypeMapper(getContextualMapper(node))); // If the contextual type is a generic function type with a single call signature, we // instantiate the type with its own type parameters and type arguments. This ensures that // the type parameters are not erased to type any during type inference such that they can // be inferred as actual types from the contextual type. For example: // declare function arrayMap(f: (x: T) => U): (a: T[]) => U[]; // const boxElements: (a: A[]) => { value: A }[] = arrayMap(value => ({ value })); // Above, the type of the 'value' parameter is inferred to be 'A'. var contextualSignature = getSingleCallSignature(instantiatedType); var inferenceSourceType = contextualSignature && contextualSignature.typeParameters ? getOrCreateTypeFromSignature(getSignatureInstantiation(contextualSignature, contextualSignature.typeParameters, ts.isInJavaScriptFile(node))) : instantiatedType; var inferenceTargetType = getReturnTypeOfSignature(signature); // Inferences made from return types have lower priority than all other inferences. inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, 8 /* ReturnType */); } } var thisType = getThisTypeOfSignature(signature); if (thisType) { var thisArgumentNode = getThisArgumentOfCall(node); var thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; inferTypes(context.inferences, thisArgumentType, thisType); } // We perform two passes over the arguments. In the first pass we infer from all arguments, but use // wildcards for all context sensitive function expressions. var argCount = getEffectiveArgumentCount(node, args, signature); for (var i = 0; i < argCount; i++) { var arg = getEffectiveArgument(node, args, i); // If the effective argument is 'undefined', then it is an argument that is present but is synthetic. if (arg === undefined || arg.kind !== 201 /* OmittedExpression */) { var paramType = getTypeAtPosition(signature, i); var argType = getEffectiveArgumentType(node, i); // If the effective argument type is 'undefined', there is no synthetic type // for the argument. In that case, we should check the argument. if (argType === undefined) { // For context sensitive arguments we pass the identityMapper, which is a signal to treat all // context sensitive function expressions as wildcards var mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : context; argType = checkExpressionWithContextualType(arg, paramType, mapper); } inferTypes(context.inferences, argType, paramType); } } // In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this // time treating function expressions normally (which may cause previously inferred type arguments to be fixed // as we construct types for contextually typed parameters) // Decorators will not have `excludeArgument`, as their arguments cannot be contextually typed. // Tagged template expressions will always have `undefined` for `excludeArgument[0]`. if (excludeArgument) { for (var i = 0; i < argCount; i++) { // No need to check for omitted args and template expressions, their exclusion value is always undefined if (excludeArgument[i] === false) { var arg = args[i]; var paramType = getTypeAtPosition(signature, i); inferTypes(context.inferences, checkExpressionWithContextualType(arg, paramType, context), paramType); } } } return getInferredTypes(context); } function checkTypeArguments(signature, typeArgumentNodes, reportErrors, headMessage) { var isJavascript = ts.isInJavaScriptFile(signature.declaration); var typeParameters = signature.typeParameters; var typeArgumentTypes = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript); var mapper; for (var i = 0; i < typeArgumentNodes.length; i++) { ts.Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments"); var constraint = getConstraintOfTypeParameter(typeParameters[i]); if (!constraint) continue; var errorInfo = reportErrors && headMessage && ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); var typeArgumentHeadMessage = headMessage || ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1; if (!mapper) { mapper = createTypeMapper(typeParameters, typeArgumentTypes); } var typeArgument = typeArgumentTypes[i]; if (!checkTypeAssignableTo(typeArgument, getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument), reportErrors ? typeArgumentNodes[i] : undefined, typeArgumentHeadMessage, errorInfo)) { return false; } } return typeArgumentTypes; } /** * Check if the given signature can possibly be a signature called by the JSX opening-like element. * @param node a JSX opening-like element we are trying to figure its call signature * @param signature a candidate signature we are trying whether it is a call signature * @param relation a relationship to check parameter and argument type * @param excludeArgument */ function checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation) { // JSX opening-like element has correct arity for stateless-function component if the one of the following condition is true: // 1. callIsIncomplete // 2. attributes property has same number of properties as the parameter object type. // We can figure that out by resolving attributes property and check number of properties in the resolved type // If the call has correct arity, we will then check if the argument type and parameter type is assignable var callIsIncomplete = node.attributes.end === node.end; // If we are missing the close "/>", the call is incomplete if (callIsIncomplete) { return true; } var headMessage = ts.Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; // Stateless function components can have maximum of three arguments: "props", "context", and "updater". // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, // can be specified by users through attributes property. var paramType = getTypeAtPosition(signature, 0); var attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*contextualMapper*/ undefined); var argProperties = getPropertiesOfType(attributesType); for (var _i = 0, argProperties_1 = argProperties; _i < argProperties_1.length; _i++) { var arg = argProperties_1[_i]; if (!getPropertyOfType(paramType, arg.escapedName) && isUnhyphenatedJsxName(arg.escapedName)) { return false; } } return checkTypeRelatedTo(attributesType, paramType, relation, /*errorNode*/ undefined, headMessage); } function checkApplicableSignature(node, args, signature, relation, excludeArgument, reportErrors) { if (ts.isJsxOpeningLikeElement(node)) { return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation); } var thisType = getThisTypeOfSignature(signature); if (thisType && thisType !== voidType && node.kind !== 183 /* 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 !== 201 /* OmittedExpression */) { // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter) var paramType = getTypeAtPosition(signature, i); // If the effective argument type is undefined, there is no synthetic type for the argument. // In that case, we should check the argument. var argType = getEffectiveArgumentType(node, i) || checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); // If one or more arguments are still excluded (as indicated by a non-null excludeArgument parameter), // we obtain the regular type of any object literal arguments because we may not have inferred complete // parameter types yet and therefore excess property checks may yield false positives (see #17041). var checkArgType = excludeArgument ? getRegularTypeOfObjectLiteral(argType) : argType; // Use argument expression as error location when reporting errors var errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined; if (!checkTypeRelatedTo(checkArgType, paramType, relation, errorNode, headMessage)) { return false; } } } return true; } /** * Returns the this argument in calls like x.f(...) and x[f](...). Undefined otherwise. */ function getThisArgumentOfCall(node) { if (node.kind === 182 /* CallExpression */) { var callee = node.expression; if (callee.kind === 180 /* PropertyAccessExpression */) { return callee.expression; } else if (callee.kind === 181 /* ElementAccessExpression */) { return callee.expression; } } } /** * Returns the effective arguments for an expression that works like a function invocation. * * If 'node' is a CallExpression or a NewExpression, then its argument list is returned. * If 'node' is a TaggedTemplateExpression, a new argument list is constructed from the substitution * expressions, where the first element of the list is `undefined`. * If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types * will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`. */ function getEffectiveCallArguments(node) { if (node.kind === 184 /* TaggedTemplateExpression */) { var template = node.template; var args_4 = [undefined]; if (template.kind === 197 /* TemplateExpression */) { ts.forEach(template.templateSpans, function (span) { args_4.push(span.expression); }); } return args_4; } else if (node.kind === 148 /* Decorator */) { // For a decorator, we return undefined as we will determine // the number and types of arguments for a decorator using // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below. return undefined; } else if (ts.isJsxOpeningLikeElement(node)) { return node.attributes.properties.length > 0 ? [node.attributes] : ts.emptyArray; } else { return node.arguments || ts.emptyArray; } } /** * Returns the effective argument count for a node that works like a function invocation. * If 'node' is a Decorator, the number of arguments is derived from the decoration * target and the signature: * If 'node.target' is a class declaration or class expression, the effective argument * count is 1. * If 'node.target' is a parameter declaration, the effective argument count is 3. * If 'node.target' is a property declaration, the effective argument count is 2. * If 'node.target' is a method or accessor declaration, the effective argument count * is 3, although it can be 2 if the signature only accepts two arguments, allowing * us to match a property decorator. * Otherwise, the argument count is the length of the 'args' array. */ function getEffectiveArgumentCount(node, args, signature) { if (node.kind === 148 /* Decorator */) { switch (node.parent.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: // A class decorator will have one argument (see `ClassDecorator` in core.d.ts) return 1; case 150 /* PropertyDeclaration */: // A property declaration decorator will have two arguments (see // `PropertyDecorator` in core.d.ts) return 2; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* 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 147 /* 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 === 230 /* 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 === 147 /* Parameter */) { // For a parameter decorator, the `target` is the parent type of the // parameter's containing method. node = node.parent; if (node.kind === 153 /* Constructor */) { var classSymbol = getSymbolOfNode(node); return getTypeOfSymbol(classSymbol); } } if (node.kind === 150 /* PropertyDeclaration */ || node.kind === 152 /* MethodDeclaration */ || node.kind === 154 /* GetAccessor */ || node.kind === 155 /* 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 === 230 /* ClassDeclaration */) { ts.Debug.fail("Class decorators should not have a second synthetic argument."); return unknownType; } if (node.kind === 147 /* Parameter */) { node = node.parent; if (node.kind === 153 /* Constructor */) { // For a constructor parameter decorator, the `propertyKey` will be `undefined`. return anyType; } // For a non-constructor parameter decorator, the `propertyKey` will be either // a string or a symbol, based on the name of the parameter's containing method. } if (node.kind === 150 /* PropertyDeclaration */ || node.kind === 152 /* MethodDeclaration */ || node.kind === 154 /* GetAccessor */ || node.kind === 155 /* SetAccessor */) { // The `propertyKey` for a property or method decorator will be a // string literal type if the member name is an identifier, number, or string; // otherwise, if the member name is a computed property name it will // be either string or symbol. var element = node; switch (element.name.kind) { case 71 /* Identifier */: return getLiteralType(ts.idText(element.name)); case 8 /* NumericLiteral */: case 9 /* StringLiteral */: return getLiteralType(element.name.text); case 145 /* ComputedPropertyName */: var nameType = checkComputedPropertyName(element.name); if (isTypeAssignableToKind(nameType, 1536 /* ESSymbolLike */)) { 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` 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 === 230 /* ClassDeclaration */) { ts.Debug.fail("Class decorators should not have a third synthetic argument."); return unknownType; } if (node.kind === 147 /* Parameter */) { // The `parameterIndex` for a parameter decorator is always a number return numberType; } if (node.kind === 150 /* PropertyDeclaration */) { ts.Debug.fail("Property decorators should not have a third synthetic argument."); return unknownType; } if (node.kind === 152 /* MethodDeclaration */ || node.kind === 154 /* GetAccessor */ || node.kind === 155 /* SetAccessor */) { // The `descriptor` for a method decorator will be a `TypedPropertyDescriptor` // for the type of the member. var propertyType = getTypeOfNode(node); return createTypedPropertyDescriptorType(propertyType); } ts.Debug.fail("Unsupported decorator target."); return unknownType; } /** * Returns the effective argument type for the provided argument to a decorator. */ function getEffectiveDecoratorArgumentType(node, argIndex) { if (argIndex === 0) { return getEffectiveDecoratorFirstArgumentType(node.parent); } else if (argIndex === 1) { return getEffectiveDecoratorSecondArgumentType(node.parent); } else if (argIndex === 2) { return getEffectiveDecoratorThirdArgumentType(node.parent); } ts.Debug.fail("Decorators should not have a fourth synthetic argument."); return unknownType; } /** * Gets the effective argument type for an argument in a call expression. */ function getEffectiveArgumentType(node, argIndex) { // Decorators provide special arguments, a tagged template expression provides // a special first argument, and string literals get string literal types // unless we're reporting errors if (node.kind === 148 /* Decorator */) { return getEffectiveDecoratorArgumentType(node, argIndex); } else if (argIndex === 0 && node.kind === 184 /* 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 === 148 /* Decorator */ || (argIndex === 0 && node.kind === 184 /* 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 === 148 /* Decorator */) { // For a decorator, we use the expression of the decorator for error reporting. return node.expression; } else if (argIndex === 0 && node.kind === 184 /* TaggedTemplateExpression */) { // For a the first argument of a tagged template expression, we use the template of the tag for error reporting. return node.template; } else { return arg; } } function resolveCall(node, signatures, candidatesOutArray, fallbackError) { var isTaggedTemplate = node.kind === 184 /* TaggedTemplateExpression */; var isDecorator = node.kind === 148 /* Decorator */; var isJsxOpeningOrSelfClosingElement = ts.isJsxOpeningLikeElement(node); var typeArguments; if (!isTaggedTemplate && !isDecorator && !isJsxOpeningOrSelfClosingElement) { typeArguments = node.typeArguments; // We already perform checking on the type arguments on the class declaration itself. if (node.expression.kind !== 97 /* SuperKeyword */) { ts.forEach(typeArguments, checkSourceElement); } } var candidates = candidatesOutArray || []; // reorderCandidates fills up the candidates array directly reorderCandidates(signatures, candidates); if (!candidates.length) { diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Call_target_does_not_contain_any_signatures)); return resolveErrorCall(node); } var args = getEffectiveCallArguments(node); // The following applies to any value of 'excludeArgument[i]': // - true: the argument at 'i' is susceptible to a one-time permanent contextual typing. // - undefined: the argument at 'i' is *not* susceptible to permanent contextual typing. // - false: the argument at 'i' *was* and *has been* permanently contextually typed. // // The idea is that we will perform type argument inference & assignability checking once // without using the susceptible parameters that are functions, and once more for each of those // parameters, contextually typing each as we go along. // // For a tagged template, then the first argument be 'undefined' if necessary // because it represents a TemplateStringsArray. // // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. var isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; var excludeArgument; var excludeCount = 0; if (!isDecorator && !isSingleNonGenericCandidate) { // We do not need to call `getEffectiveArgumentCount` here as it only // applies when calculating the number of arguments for a decorator. for (var i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { if (isContextSensitive(args[i])) { if (!excludeArgument) { excludeArgument = new Array(args.length); } excludeArgument[i] = true; excludeCount++; } } } // The following variables are captured and modified by calls to chooseOverload. // If overload resolution or type argument inference fails, we want to report the // best error possible. The best error is one which says that an argument was not // assignable to a parameter. This implies that everything else about the overload // was fine. So if there is any overload that is only incorrect because of an // argument, we will report an error on that one. // // function foo(s: string): void; // function foo(n: number): void; // Report argument error on this overload // function foo(): void; // foo(true); // // If none of the overloads even made it that far, there are two possibilities. // There was a problem with type arguments for some overload, in which case // report an error on that. Or none of the overloads even had correct arity, // in which case give an arity error. // // function foo(x: T): void; // Report type argument error // function foo(): void; // foo(0); // var candidateForArgumentError; var candidateForTypeArgumentError; var result; // If we are in signature help, a trailing comma indicates that we intend to provide another argument, // so we will only accept overloads with arity at least 1 higher than the current number of provided arguments. var signatureHelpTrailingComma = candidatesOutArray && node.kind === 182 /* CallExpression */ && node.arguments.hasTrailingComma; // Section 4.12.1: // if the candidate list contains one or more signatures for which the type of each argument // expression is a subtype of each corresponding parameter type, the return type of the first // of those signatures becomes the return type of the function call. // Otherwise, the return type of the first signature in the candidate list becomes the return // type of the function call. // // Whether the call is an error is determined by assignability of the arguments. The subtype pass // is just important for choosing the best signature. So in the case where there is only one // signature, the subtype pass is useless. So skipping it is an optimization. if (candidates.length > 1) { result = chooseOverload(candidates, subtypeRelation, signatureHelpTrailingComma); } if (!result) { result = chooseOverload(candidates, assignableRelation, signatureHelpTrailingComma); } if (result) { return result; } // No signatures were applicable. Now report errors based on the last applicable signature with // no arguments excluded from assignability checks. // If candidate is undefined, it means that no candidates had a suitable arity. In that case, // skip the checkApplicableSignature check. if (candidateForArgumentError) { if (isJsxOpeningOrSelfClosingElement) { // We do not report any error here because any error will be handled in "resolveCustomJsxElementAttributesType". return candidateForArgumentError; } // excludeArgument is undefined, in this case also equivalent to [undefined, undefined, ...] // The importance of excludeArgument is to prevent us from typing function expression parameters // in arguments too early. If possible, we'd like to only type them once we know the correct // overload. However, this matters for the case where the call is correct. When the call is // an error, we don't need to exclude any arguments, although it would cause no harm to do so. checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { checkTypeArguments(candidateForTypeArgumentError, node.typeArguments, /*reportErrors*/ true, fallbackError); } else if (typeArguments && ts.every(signatures, function (sig) { return ts.length(sig.typeParameters) !== typeArguments.length; })) { var min = Number.POSITIVE_INFINITY; var max = Number.NEGATIVE_INFINITY; for (var _i = 0, signatures_5 = signatures; _i < signatures_5.length; _i++) { var sig = signatures_5[_i]; min = Math.min(min, getMinTypeArgumentCount(sig.typeParameters)); max = Math.max(max, ts.length(sig.typeParameters)); } var paramCount = min < max ? min + "-" + max : min; diagnostics.add(ts.createDiagnosticForNode(node, ts.Diagnostics.Expected_0_type_arguments_but_got_1, paramCount, typeArguments.length)); } else if (args) { var min = Number.POSITIVE_INFINITY; var max = Number.NEGATIVE_INFINITY; for (var _a = 0, signatures_6 = signatures; _a < signatures_6.length; _a++) { var sig = signatures_6[_a]; min = Math.min(min, sig.minArgumentCount); max = Math.max(max, sig.parameters.length); } var hasRestParameter_1 = ts.some(signatures, function (sig) { return sig.hasRestParameter; }); var hasSpreadArgument = getSpreadArgumentIndex(args) > -1; var paramCount = hasRestParameter_1 ? min : min < max ? min + "-" + max : min; var argCount = args.length; if (argCount <= max && hasSpreadArgument) { argCount--; } var error_1 = hasRestParameter_1 && hasSpreadArgument ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more : hasRestParameter_1 ? ts.Diagnostics.Expected_at_least_0_arguments_but_got_1 : hasSpreadArgument ? ts.Diagnostics.Expected_0_arguments_but_got_1_or_more : ts.Diagnostics.Expected_0_arguments_but_got_1; diagnostics.add(ts.createDiagnosticForNode(node, error_1, paramCount, argCount)); } else if (fallbackError) { diagnostics.add(ts.createDiagnosticForNode(node, fallbackError)); } // No signature was applicable. We have already reported the errors for the invalid signature. // If this is a type resolution session, e.g. Language Service, try to get better information than anySignature. // Pick the longest signature. This way we can get a contextual type for cases like: // declare function f(a: { xa: number; xb: number; }, b: number); // f({ | // Also, use explicitly-supplied type arguments if they are provided, so we can get a contextual signature in cases like: // declare function f(k: keyof T); // f(" if (!produceDiagnostics) { ts.Debug.assert(candidates.length > 0); // Else would have exited above. var bestIndex = getLongestCandidateIndex(candidates, apparentArgumentCount === undefined ? args.length : apparentArgumentCount); var candidate = candidates[bestIndex]; var typeParameters = candidate.typeParameters; if (typeParameters && callLikeExpressionMayHaveTypeArguments(node) && node.typeArguments) { var typeArguments_1 = node.typeArguments.map(getTypeOfNode); while (typeArguments_1.length > typeParameters.length) { typeArguments_1.pop(); } while (typeArguments_1.length < typeParameters.length) { typeArguments_1.push(getDefaultTypeArgumentType(ts.isInJavaScriptFile(node))); } var instantiated = createSignatureInstantiation(candidate, typeArguments_1); candidates[bestIndex] = instantiated; return instantiated; } return candidate; } return resolveErrorCall(node); function chooseOverload(candidates, relation, signatureHelpTrailingComma) { if (signatureHelpTrailingComma === void 0) { signatureHelpTrailingComma = false; } candidateForArgumentError = undefined; candidateForTypeArgumentError = undefined; if (isSingleNonGenericCandidate) { var candidate = candidates[0]; if (!hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { return undefined; } if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { candidateForArgumentError = candidate; return undefined; } return candidate; } for (var candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { var originalCandidate = candidates[candidateIndex]; if (!hasCorrectArity(node, args, originalCandidate, signatureHelpTrailingComma)) { continue; } var candidate = void 0; var inferenceContext = originalCandidate.typeParameters ? createInferenceContext(originalCandidate, /*flags*/ ts.isInJavaScriptFile(node) ? 4 /* AnyDefault */ : 0) : undefined; while (true) { candidate = originalCandidate; if (candidate.typeParameters) { var typeArgumentTypes = void 0; if (typeArguments) { var typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); if (typeArgumentResult) { typeArgumentTypes = typeArgumentResult; } else { candidateForTypeArgumentError = originalCandidate; break; } } else { typeArgumentTypes = inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext); } var isJavascript = ts.isInJavaScriptFile(candidate.declaration); candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript); } if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { candidateForArgumentError = candidate; break; } if (excludeCount === 0) { candidates[candidateIndex] = candidate; return candidate; } excludeCount--; if (excludeCount > 0) { excludeArgument[ts.indexOf(excludeArgument, /*value*/ true)] = false; } else { excludeArgument = undefined; } } } return undefined; } } function getLongestCandidateIndex(candidates, argsCount) { var maxParamsIndex = -1; var maxParams = -1; for (var i = 0; i < candidates.length; i++) { var candidate = candidates[i]; if (candidate.hasRestParameter || candidate.parameters.length >= argsCount) { return i; } if (candidate.parameters.length > maxParams) { maxParams = candidate.parameters.length; maxParamsIndex = i; } } return maxParamsIndex; } function resolveCallExpression(node, candidatesOutArray) { if (node.expression.kind === 97 /* SuperKeyword */) { var superType = checkSuperExpression(node.expression); if (superType !== unknownType) { // In super call, the candidate signatures are the matching arity signatures of the base constructor function instantiated // with the type arguments specified in the extends clause. var baseTypeNode = ts.getClassExtendsHeritageClauseElement(ts.getContainingClass(node)); if (baseTypeNode) { var baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode); return resolveCall(node, baseConstructors, candidatesOutArray); } } return resolveUntypedCall(node); } var funcType = checkNonNullExpression(node.expression); if (funcType === silentNeverType) { return silentNeverSignature; } var apparentType = getApparentType(funcType); if (apparentType === unknownType) { // Another error has already been reported return resolveErrorCall(node); } // Technically, this signatures list may be incomplete. We are taking the apparent type, // but we are not including call signatures that may have been added to the Object or // Function interface, since they have none by default. This is a bit of a leap of faith // that the user will not add any. var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */); var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */); // TS 1.0 Spec: 4.12 // In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual // types are provided for the argument expressions, and the result is always of type Any. if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) { // The unknownType indicates that an error already occurred (and was reported). No // need to report another error in this case. if (funcType !== unknownType && node.typeArguments) { error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); } // If FuncExpr's apparent type(section 3.8.1) is a function type, the call is a typed function call. // TypeScript employs overload resolution in typed function calls in order to support functions // with multiple call signatures. if (!callSignatures.length) { if (constructSignatures.length) { error(node, ts.Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType)); } else { error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); } return resolveErrorCall(node); } return resolveCall(node, callSignatures, candidatesOutArray); } /** * TS 1.0 spec: 4.12 * If FuncExpr is of type Any, or of an object type that has no call or construct signatures * but is a subtype of the Function interface, the call is an untyped function call. */ function isUntypedFunctionCall(funcType, apparentFuncType, numCallSignatures, numConstructSignatures) { // We exclude union types because we may have a union of function types that happen to have no common signatures. return isTypeAny(funcType) || isTypeAny(apparentFuncType) && funcType.flags & 32768 /* TypeParameter */ || !numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (131072 /* Union */ | 16384 /* Never */)) && isTypeAssignableTo(funcType, globalFunctionType); } function resolveNewExpression(node, candidatesOutArray) { if (node.arguments && languageVersion < 1 /* ES5 */) { var spreadIndex = getSpreadArgumentIndex(node.arguments); if (spreadIndex >= 0) { error(node.arguments[spreadIndex], ts.Diagnostics.Spread_operator_in_new_expressions_is_only_available_when_targeting_ECMAScript_5_and_higher); } } var expressionType = checkNonNullExpression(node.expression); if (expressionType === silentNeverType) { return silentNeverSignature; } // If expressionType's apparent type(section 3.8.1) is an object type with one or // more construct signatures, the expression is processed in the same manner as a // function call, but using the construct signatures as the initial set of candidate // signatures for overload resolution. The result type of the function call becomes // the result type of the operation. expressionType = getApparentType(expressionType); if (expressionType === unknownType) { // Another error has already been reported return resolveErrorCall(node); } // TS 1.0 spec: 4.11 // If expressionType is of type Any, Args can be any argument // list and the result of the operation is of type Any. if (isTypeAny(expressionType)) { if (node.typeArguments) { error(node, ts.Diagnostics.Untyped_function_calls_may_not_accept_type_arguments); } return resolveUntypedCall(node); } // Technically, this signatures list may be incomplete. We are taking the apparent type, // but we are not including construct signatures that may have been added to the Object or // Function interface, since they have none by default. This is a bit of a leap of faith // that the user will not add any. var constructSignatures = getSignaturesOfType(expressionType, 1 /* Construct */); if (constructSignatures.length) { if (!isConstructorAccessible(node, constructSignatures[0])) { return resolveErrorCall(node); } // If the expression is a class of abstract type, then it cannot be instantiated. // Note, only class declarations can be declared abstract. // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. var valueDecl = expressionType.symbol && ts.getClassLikeDeclarationOfSymbol(expressionType.symbol); if (valueDecl && ts.hasModifier(valueDecl, 128 /* Abstract */)) { error(node, ts.Diagnostics.Cannot_create_an_instance_of_an_abstract_class); return resolveErrorCall(node); } return resolveCall(node, constructSignatures, candidatesOutArray); } // If expressionType's apparent type is an object type with no construct signatures but // one or more call signatures, the expression is processed as a function call. A compile-time // error occurs if the result of the function call is not Void. The type of the result of the // operation is Any. It is an error to have a Void this type. var callSignatures = getSignaturesOfType(expressionType, 0 /* Call */); if (callSignatures.length) { var signature = resolveCall(node, callSignatures, candidatesOutArray); if (!isJavaScriptConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) { error(node, ts.Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword); } if (getThisTypeOfSignature(signature) === voidType) { error(node, ts.Diagnostics.A_function_that_is_called_with_the_new_keyword_cannot_have_a_this_type_that_is_void); } return signature; } error(node, ts.Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature); return resolveErrorCall(node); } function isConstructorAccessible(node, signature) { if (!signature || !signature.declaration) { return true; } var declaration = signature.declaration; var modifiers = ts.getSelectedModifierFlags(declaration, 24 /* NonPublicAccessibilityModifier */); // Public constructor is accessible. if (!modifiers) { return true; } var declaringClassDeclaration = ts.getClassLikeDeclarationOfSymbol(declaration.parent.symbol); var declaringClass = getDeclaredTypeOfSymbol(declaration.parent.symbol); // A private or protected constructor can only be instantiated within its own class (or a subclass, for protected) if (!isNodeWithinClass(node, declaringClassDeclaration)) { var containingClass = ts.getContainingClass(node); if (containingClass) { var containingType = getTypeOfNode(containingClass); var baseTypes = getBaseTypes(containingType); while (baseTypes.length) { var baseType = baseTypes[0]; if (modifiers & 16 /* Protected */ && baseType.symbol === declaration.parent.symbol) { return true; } baseTypes = getBaseTypes(baseType); } } if (modifiers & 8 /* Private */) { error(node, ts.Diagnostics.Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } if (modifiers & 16 /* Protected */) { error(node, ts.Diagnostics.Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration, typeToString(declaringClass)); } return false; } return true; } function resolveTaggedTemplateExpression(node, candidatesOutArray) { var tagType = checkExpression(node.tag); var apparentType = getApparentType(tagType); if (apparentType === unknownType) { // Another error has already been reported return resolveErrorCall(node); } var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */); var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */); if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) { return resolveUntypedCall(node); } if (!callSignatures.length) { error(node, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); return resolveErrorCall(node); } return resolveCall(node, callSignatures, candidatesOutArray); } /** * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression. */ function getDiagnosticHeadMessageForDecoratorResolution(node) { switch (node.parent.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return ts.Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression; case 147 /* Parameter */: return ts.Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression; case 150 /* PropertyDeclaration */: return ts.Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return ts.Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression; } } /** * Resolves a decorator as if it were a call expression. */ function resolveDecorator(node, candidatesOutArray) { var funcType = checkExpression(node.expression); var apparentType = getApparentType(funcType); if (apparentType === unknownType) { return resolveErrorCall(node); } var callSignatures = getSignaturesOfType(apparentType, 0 /* Call */); var constructSignatures = getSignaturesOfType(apparentType, 1 /* Construct */); if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) { return resolveUntypedCall(node); } if (isPotentiallyUncalledDecorator(node, callSignatures)) { var nodeStr = ts.getTextOfNode(node.expression, /*includeTrivia*/ false); error(node, ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0, nodeStr); return resolveErrorCall(node); } var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); if (!callSignatures.length) { var errorInfo = void 0; errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures, typeToString(apparentType)); errorInfo = ts.chainDiagnosticMessages(errorInfo, headMessage); diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(node, errorInfo)); return resolveErrorCall(node); } return resolveCall(node, callSignatures, candidatesOutArray, headMessage); } /** * Sometimes, we have a decorator that could accept zero arguments, * but is receiving too many arguments as part of the decorator invocation. * In those cases, a user may have meant to *call* the expression before using it as a decorator. */ function isPotentiallyUncalledDecorator(decorator, signatures) { return signatures.length && ts.every(signatures, function (signature) { return signature.minArgumentCount === 0 && !signature.hasRestParameter && signature.parameters.length < getEffectiveArgumentCount(decorator, /*args*/ undefined, signature); }); } /** * This function is similar to getResolvedSignature but is exclusively for trying to resolve JSX stateless-function component. * The main reason we have to use this function instead of getResolvedSignature because, the caller of this function will already check the type of openingLikeElement's tagName * and pass the type as elementType. The elementType can not be a union (as such case should be handled by the caller of this function) * Note: at this point, we are still not sure whether the opening-like element is a stateless function component or not. * @param openingLikeElement an opening-like JSX element to try to resolve as JSX stateless function * @param elementType an element type of the opneing-like element by checking opening-like element's tagname. * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service; * the function will fill it up with appropriate candidate signatures */ function getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, candidatesOutArray) { ts.Debug.assert(!(elementType.flags & 131072 /* Union */)); return resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray); } /** * Try treating a given opening-like element as stateless function component and resolve a tagName to a function signature. * @param openingLikeElement an JSX opening-like element we want to try resolve its stateless function if possible * @param elementType a type of the opening-like JSX element, a result of resolving tagName in opening-like element. * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service; * the function will fill it up with appropriate candidate signatures * @return a resolved signature if we can find function matching function signature through resolve call or a first signature in the list of functions. * otherwise return undefined if tag-name of the opening-like element doesn't have call signatures */ function resolveStatelessJsxOpeningLikeElement(openingLikeElement, elementType, candidatesOutArray) { // If this function is called from language service, elementType can be a union type. This is not possible if the function is called from compiler (see: resolveCustomJsxElementAttributesType) if (elementType.flags & 131072 /* Union */) { var types = elementType.types; var result = void 0; for (var _i = 0, types_17 = types; _i < types_17.length; _i++) { var type = types_17[_i]; result = result || resolveStatelessJsxOpeningLikeElement(openingLikeElement, type, candidatesOutArray); } return result; } var callSignatures = elementType && getSignaturesOfType(elementType, 0 /* Call */); if (callSignatures && callSignatures.length > 0) { return resolveCall(openingLikeElement, callSignatures, candidatesOutArray); } return undefined; } function resolveSignature(node, candidatesOutArray) { switch (node.kind) { case 182 /* CallExpression */: return resolveCallExpression(node, candidatesOutArray); case 183 /* NewExpression */: return resolveNewExpression(node, candidatesOutArray); case 184 /* TaggedTemplateExpression */: return resolveTaggedTemplateExpression(node, candidatesOutArray); case 148 /* Decorator */: return resolveDecorator(node, candidatesOutArray); case 252 /* JsxOpeningElement */: case 251 /* JsxSelfClosingElement */: // This code-path is called by language service return resolveStatelessJsxOpeningLikeElement(node, checkExpression(node.tagName), candidatesOutArray) || unknownSignature; } ts.Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable."); } /** * Resolve a signature of a given call-like expression. * @param node a call-like expression to try resolve a signature for * @param candidatesOutArray an array of signature to be filled in by the function. It is passed by signature help in the language service; * the function will fill it up with appropriate candidate signatures * @return a signature of the call-like expression or undefined if one can't be found */ function getResolvedSignature(node, candidatesOutArray) { var links = getNodeLinks(node); // If getResolvedSignature has already been called, we will have cached the resolvedSignature. // However, it is possible that either candidatesOutArray was not passed in the first time, // or that a different candidatesOutArray was passed in. Therefore, we need to redo the work // to correctly fill the candidatesOutArray. var cached = links.resolvedSignature; if (cached && cached !== resolvingSignature && !candidatesOutArray) { return cached; } links.resolvedSignature = resolvingSignature; var result = resolveSignature(node, candidatesOutArray); // If signature resolution originated in control flow type analysis (for example to compute the // assigned type in a flow assignment) we don't cache the result as it may be based on temporary // types from the control flow analysis. links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached; return result; } /** * Indicates whether a declaration can be treated as a constructor in a JavaScript * file. */ function isJavaScriptConstructor(node) { if (node && ts.isInJavaScriptFile(node)) { // If the node has a @class tag, treat it like a constructor. if (ts.getJSDocClassTag(node)) return true; // If the symbol of the node has members, treat it like a constructor. var symbol = ts.isFunctionDeclaration(node) || ts.isFunctionExpression(node) ? getSymbolOfNode(node) : ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : undefined; return symbol && symbol.members !== undefined; } return false; } function getJavaScriptClassType(symbol) { if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { symbol = getSymbolOfNode(symbol.valueDeclaration.initializer); } if (isJavaScriptConstructor(symbol.valueDeclaration)) { return getInferredClassType(symbol); } if (symbol.flags & 3 /* Variable */) { var valueType = getTypeOfSymbol(symbol); if (valueType.symbol && !isInferredClassType(valueType) && isJavaScriptConstructor(valueType.symbol.valueDeclaration)) { return getInferredClassType(valueType.symbol); } } } function getInferredClassType(symbol) { var links = getSymbolLinks(symbol); if (!links.inferredClassType) { links.inferredClassType = createAnonymousType(symbol, getMembersOfSymbol(symbol) || emptySymbols, ts.emptyArray, ts.emptyArray, /*stringIndexType*/ undefined, /*numberIndexType*/ undefined); } return links.inferredClassType; } function isInferredClassType(type) { return type.symbol && ts.getObjectFlags(type) & 16 /* Anonymous */ && getSymbolLinks(type.symbol).inferredClassType === type; } /** * Syntactically and semantically checks a call or new expression. * @param node The call/new expression to be checked. * @returns On success, the expression's signature's return type. On failure, anyType. */ function checkCallExpression(node) { if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments); var signature = getResolvedSignature(node); if (node.expression.kind === 97 /* SuperKeyword */) { return voidType; } if (node.kind === 183 /* NewExpression */) { var declaration = signature.declaration; if (declaration && declaration.kind !== 153 /* Constructor */ && declaration.kind !== 157 /* ConstructSignature */ && declaration.kind !== 162 /* ConstructorType */ && !ts.isJSDocConstructSignature(declaration)) { // When resolved signature is a call signature (and not a construct signature) the result type is any, unless // the declaring function had members created through 'x.prototype.y = expr' or 'this.y = expr' psuedodeclarations // in a JS file // Note:JS inferred classes might come from a variable declaration instead of a function declaration. // In this case, using getResolvedSymbol directly is required to avoid losing the members from the declaration. var funcSymbol = checkExpression(node.expression).symbol; if (!funcSymbol && node.expression.kind === 71 /* Identifier */) { funcSymbol = getResolvedSymbol(node.expression); } var type = funcSymbol && getJavaScriptClassType(funcSymbol); if (type) { return type; } if (noImplicitAny) { error(node, ts.Diagnostics.new_expression_whose_target_lacks_a_construct_signature_implicitly_has_an_any_type); } return anyType; } } // In JavaScript files, calls to any identifier 'require' are treated as external module imports if (ts.isInJavaScriptFile(node) && isCommonJsRequire(node)) { return resolveExternalModuleTypeByLiteral(node.arguments[0]); } var returnType = getReturnTypeOfSignature(signature); // Treat any call to the global 'Symbol' function that is part of a const variable or readonly property // as a fresh unique symbol literal type. if (returnType.flags & 1536 /* ESSymbolLike */ && isSymbolOrSymbolForCall(node)) { return getESSymbolLikeTypeForNode(ts.walkUpParenthesizedExpressions(node.parent)); } return returnType; } function isSymbolOrSymbolForCall(node) { if (!ts.isCallExpression(node)) return false; var left = node.expression; if (ts.isPropertyAccessExpression(left) && left.name.escapedText === "for") { left = left.expression; } if (!ts.isIdentifier(left) || left.escapedText !== "Symbol") { return false; } // make sure `Symbol` is the global symbol var globalESSymbol = getGlobalESSymbolConstructorSymbol(/*reportErrors*/ false); if (!globalESSymbol) { return false; } return globalESSymbol === resolveName(left, "Symbol", 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); } function checkImportCallExpression(node) { // Check grammar of dynamic import if (!checkGrammarArguments(node.arguments)) checkGrammarImportCallExpression(node); if (node.arguments.length === 0) { return createPromiseReturnType(node, anyType); } var specifier = node.arguments[0]; var specifierType = checkExpressionCached(specifier); // Even though multiple arugments is grammatically incorrect, type-check extra arguments for completion for (var i = 1; i < node.arguments.length; ++i) { checkExpressionCached(node.arguments[i]); } if (specifierType.flags & 4096 /* Undefined */ || specifierType.flags & 8192 /* Null */ || !isTypeAssignableTo(specifierType, stringType)) { error(specifier, ts.Diagnostics.Dynamic_import_s_specifier_must_be_of_type_string_but_here_has_type_0, typeToString(specifierType)); } // resolveExternalModuleName will return undefined if the moduleReferenceExpression is not a string literal var moduleSymbol = resolveExternalModuleName(node, specifier); if (moduleSymbol) { var esModuleSymbol = resolveESModuleSymbol(moduleSymbol, specifier, /*dontRecursivelyResolve*/ true); if (esModuleSymbol) { return createPromiseReturnType(node, getTypeWithSyntheticDefaultImportType(getTypeOfSymbol(esModuleSymbol), esModuleSymbol)); } } return createPromiseReturnType(node, anyType); } function getTypeWithSyntheticDefaultImportType(type, symbol) { if (allowSyntheticDefaultImports && type && type !== unknownType) { var synthType = type; if (!synthType.syntheticType) { if (!getPropertyOfType(type, "default" /* Default */)) { var memberTable = ts.createSymbolTable(); var newSymbol = createSymbol(2097152 /* Alias */, "default" /* Default */); newSymbol.target = resolveSymbol(symbol); memberTable.set("default" /* Default */, newSymbol); var anonymousSymbol = createSymbol(2048 /* TypeLiteral */, "__type" /* Type */); var defaultContainingObject = createAnonymousType(anonymousSymbol, memberTable, ts.emptyArray, ts.emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined); anonymousSymbol.type = defaultContainingObject; synthType.syntheticType = getIntersectionType([type, defaultContainingObject]); } else { synthType.syntheticType = type; } } return synthType.syntheticType; } return type; } function isCommonJsRequire(node) { if (!ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { return false; } // Make sure require is not a local function if (!ts.isIdentifier(node.expression)) throw ts.Debug.fail(); var resolvedRequire = resolveName(node.expression, node.expression.escapedText, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); if (!resolvedRequire) { // project does not contain symbol named 'require' - assume commonjs require return true; } // project includes symbol named 'require' - make sure that it it ambient and local non-alias if (resolvedRequire.flags & 2097152 /* Alias */) { return false; } var targetDeclarationKind = resolvedRequire.flags & 16 /* Function */ ? 229 /* FunctionDeclaration */ : resolvedRequire.flags & 3 /* Variable */ ? 227 /* VariableDeclaration */ : 0 /* Unknown */; if (targetDeclarationKind !== 0 /* Unknown */) { var decl = ts.getDeclarationOfKind(resolvedRequire, targetDeclarationKind); // function/variable declaration should be ambient return !!decl && !!(decl.flags & 2097152 /* Ambient */); } return false; } function checkTaggedTemplateExpression(node) { if (languageVersion < 2 /* ES2015 */) { checkExternalEmitHelpers(node, 65536 /* MakeTemplateObject */); } return getReturnTypeOfSignature(getResolvedSignature(node)); } function checkAssertion(node) { return checkAssertionWorker(node, node.type, node.expression); } function checkAssertionWorker(errNode, type, expression, checkMode) { var exprType = getRegularTypeOfObjectLiteral(getBaseTypeOfLiteralType(checkExpression(expression, checkMode))); checkSourceElement(type); var targetType = getTypeFromTypeNode(type); if (produceDiagnostics && targetType !== unknownType) { var widenedType = getWidenedType(exprType); if (!isTypeComparableTo(targetType, widenedType)) { checkTypeComparableTo(exprType, targetType, errNode, ts.Diagnostics.Type_0_cannot_be_converted_to_type_1); } } return targetType; } function checkNonNullAssertion(node) { return getNonNullableType(checkExpression(node.expression)); } function checkMetaProperty(node) { checkGrammarMetaProperty(node); var container = ts.getNewTargetContainer(node); if (!container) { error(node, ts.Diagnostics.Meta_property_0_is_only_allowed_in_the_body_of_a_function_declaration_function_expression_or_constructor, "new.target"); return unknownType; } else if (container.kind === 153 /* Constructor */) { var symbol = getSymbolOfNode(container.parent); return getTypeOfSymbol(symbol); } else { var symbol = getSymbolOfNode(container); return getTypeOfSymbol(symbol); } } function getTypeOfParameter(symbol) { var type = getTypeOfSymbol(symbol); if (strictNullChecks) { var declaration = symbol.valueDeclaration; if (declaration && declaration.initializer) { return getOptionalType(type); } } return type; } function getTypeAtPosition(signature, pos) { return signature.hasRestParameter ? pos < signature.parameters.length - 1 ? getTypeOfParameter(signature.parameters[pos]) : getRestTypeOfSignature(signature) : pos < signature.parameters.length ? getTypeOfParameter(signature.parameters[pos]) : anyType; } function getTypeOfFirstParameterOfSignature(signature) { return signature.parameters.length > 0 ? getTypeAtPosition(signature, 0) : neverType; } function inferFromAnnotatedParameters(signature, context, mapper) { var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); for (var i = 0; i < len; i++) { var declaration = signature.parameters[i].valueDeclaration; if (declaration.type) { var typeNode = ts.getEffectiveTypeAnnotationNode(declaration); if (typeNode) { inferTypes(mapper.inferences, getTypeFromTypeNode(typeNode), getTypeAtPosition(context, i)); } } } } function assignContextualParameterTypes(signature, context) { signature.typeParameters = context.typeParameters; if (context.thisParameter) { var parameter = signature.thisParameter; if (!parameter || parameter.valueDeclaration && !parameter.valueDeclaration.type) { if (!parameter) { signature.thisParameter = createSymbolWithType(context.thisParameter, /*type*/ undefined); } assignTypeToParameterAndFixTypeParameters(signature.thisParameter, getTypeOfSymbol(context.thisParameter)); } } var len = signature.parameters.length - (signature.hasRestParameter ? 1 : 0); for (var i = 0; i < len; i++) { var parameter = signature.parameters[i]; if (!ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) { var contextualParameterType = getTypeAtPosition(context, i); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType); } } if (signature.hasRestParameter && isRestParameterIndex(context, signature.parameters.length - 1)) { // parameter might be a transient symbol generated by use of `arguments` in the function body. var parameter = ts.lastOrUndefined(signature.parameters); if (isTransientSymbol(parameter) || !ts.getEffectiveTypeAnnotationNode(parameter.valueDeclaration)) { var contextualParameterType = getTypeOfSymbol(ts.lastOrUndefined(context.parameters)); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType); } } } // When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push // the destructured type into the contained binding elements. function assignBindingElementTypes(pattern) { for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { if (element.name.kind === 71 /* Identifier */) { getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element); } else { assignBindingElementTypes(element.name); } } } } function assignTypeToParameterAndFixTypeParameters(parameter, contextualType) { var links = getSymbolLinks(parameter); if (!links.type) { links.type = contextualType; var decl = parameter.valueDeclaration; if (decl.name.kind !== 71 /* Identifier */) { // if inference didn't come up with anything but {}, fall back to the binding pattern if present. if (links.type === emptyObjectType) { links.type = getTypeFromBindingPattern(decl.name); } assignBindingElementTypes(decl.name); } } } function createPromiseType(promisedType) { // creates a `Promise` type where `T` is the promisedType argument var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType) { // if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type promisedType = getAwaitedType(promisedType) || emptyObjectType; return createTypeReference(globalPromiseType, [promisedType]); } return emptyObjectType; } function createPromiseReturnType(func, promisedType) { var promiseType = createPromiseType(promisedType); if (promiseType === emptyObjectType) { error(func, ts.isImportCall(func) ? ts.Diagnostics.A_dynamic_import_call_returns_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option : ts.Diagnostics.An_async_function_or_method_must_return_a_Promise_Make_sure_you_have_a_declaration_for_Promise_or_include_ES2015_in_your_lib_option); return unknownType; } else if (!getGlobalPromiseConstructorSymbol(/*reportErrors*/ true)) { error(func, ts.isImportCall(func) ? ts.Diagnostics.A_dynamic_import_call_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option : ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } return promiseType; } function getReturnTypeFromBody(func, checkMode) { var contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func); if (!func.body) { return unknownType; } var functionFlags = ts.getFunctionFlags(func); var type; if (func.body.kind !== 208 /* Block */) { type = checkExpressionCached(func.body, checkMode); if (functionFlags & 2 /* Async */) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which we will wrap in // the native Promise type later in this function. type = checkAwaitedType(type, /*errorNode*/ func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } } else { var types = void 0; if (functionFlags & 1 /* Generator */) { types = ts.concatenate(checkAndAggregateYieldOperandTypes(func, checkMode), checkAndAggregateReturnExpressionTypes(func, checkMode)); if (!types || types.length === 0) { var iterableIteratorAny = functionFlags & 2 /* Async */ ? createAsyncIterableIteratorType(anyType) // AsyncGenerator function : createIterableIteratorType(anyType); // Generator function if (noImplicitAny) { error(func.asteriskToken, ts.Diagnostics.Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type, typeToString(iterableIteratorAny)); } return iterableIteratorAny; } } else { types = checkAndAggregateReturnExpressionTypes(func, checkMode); if (!types) { // For an async function, the return type will not be never, but rather a Promise for never. return functionFlags & 2 /* Async */ ? createPromiseReturnType(func, neverType) // Async function : neverType; // Normal function } if (types.length === 0) { // For an async function, the return type will not be void, but rather a Promise for void. return functionFlags & 2 /* Async */ ? createPromiseReturnType(func, voidType) // Async function : voidType; // Normal function } } // Return a union of the return expression types. type = getUnionType(types, /*subtypeReduction*/ true); } if (!contextualSignature) { reportErrorsFromWidening(func, type); } if (isUnitType(type)) { var contextualType = !contextualSignature ? undefined : contextualSignature === getSignatureFromDeclaration(func) ? type : getReturnTypeOfSignature(contextualSignature); if (contextualType) { switch (functionFlags & 3 /* AsyncGenerator */) { case 3 /* AsyncGenerator */: contextualType = getIteratedTypeOfGenerator(contextualType, /*isAsyncGenerator*/ true); break; case 1 /* Generator */: contextualType = getIteratedTypeOfGenerator(contextualType, /*isAsyncGenerator*/ false); break; case 2 /* Async */: contextualType = getPromisedTypeOfPromise(contextualType); break; } } type = getWidenedLiteralLikeTypeForContextualType(type, contextualType); } var widenedType = getWidenedType(type); switch (functionFlags & 3 /* AsyncGenerator */) { case 3 /* AsyncGenerator */: return createAsyncIterableIteratorType(widenedType); case 1 /* Generator */: return createIterableIteratorType(widenedType); case 2 /* Async */: // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body is awaited type of the body, wrapped in a native Promise type. return createPromiseType(widenedType); default: return widenedType; } } function checkAndAggregateYieldOperandTypes(func, checkMode) { var aggregatedTypes = []; var functionFlags = ts.getFunctionFlags(func); ts.forEachYieldExpression(func.body, function (yieldExpression) { var expr = yieldExpression.expression; if (expr) { var type = checkExpressionCached(expr, checkMode); if (yieldExpression.asteriskToken) { // A yield* expression effectively yields everything that its operand yields type = checkIteratedTypeOrElementType(type, yieldExpression.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0); } if (functionFlags & 2 /* Async */) { type = checkAwaitedType(type, expr, yieldExpression.asteriskToken ? ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member : ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } ts.pushIfUnique(aggregatedTypes, type); } }); return aggregatedTypes; } function isExhaustiveSwitchStatement(node) { if (!node.possiblyExhaustive) { return false; } var type = getTypeOfExpression(node.expression); if (!isLiteralType(type)) { return false; } var switchTypes = getSwitchClauseTypes(node); if (!switchTypes.length) { return false; } return eachTypeContainedIn(mapType(type, getRegularTypeOfLiteralType), switchTypes); } function functionHasImplicitReturn(func) { if (!(func.flags & 128 /* HasImplicitReturn */)) { return false; } if (ts.some(func.body.statements, function (statement) { return statement.kind === 222 /* SwitchStatement */ && isExhaustiveSwitchStatement(statement); })) { return false; } return true; } function checkAndAggregateReturnExpressionTypes(func, checkMode) { var functionFlags = ts.getFunctionFlags(func); var aggregatedTypes = []; var hasReturnWithNoExpression = functionHasImplicitReturn(func); var hasReturnOfTypeNever = false; ts.forEachReturnStatement(func.body, function (returnStatement) { var expr = returnStatement.expression; if (expr) { var type = checkExpressionCached(expr, checkMode); if (functionFlags & 2 /* Async */) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the // return type of the body should be unwrapped to its awaited type, which should be wrapped in // the native Promise type by the caller. type = checkAwaitedType(type, func, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } if (type.flags & 16384 /* Never */) { hasReturnOfTypeNever = true; } ts.pushIfUnique(aggregatedTypes, type); } else { hasReturnWithNoExpression = true; } }); if (aggregatedTypes.length === 0 && !hasReturnWithNoExpression && (hasReturnOfTypeNever || func.kind === 187 /* FunctionExpression */ || func.kind === 188 /* ArrowFunction */)) { return undefined; } if (strictNullChecks && aggregatedTypes.length && hasReturnWithNoExpression) { ts.pushIfUnique(aggregatedTypes, undefinedType); } return aggregatedTypes; } /** * TypeScript Specification 1.0 (6.3) - July 2014 * An explicitly typed function whose return type isn't the Void type, * the Any type, or a union type containing the Void or Any type as a constituent * must have at least one return statement somewhere in its body. * An exception to this rule is if the function implementation consists of a single 'throw' statement. * * @param returnType - return type of the function, can be undefined if return type is not explicitly specified */ function checkAllCodePathsInNonVoidFunctionReturnOrThrow(func, returnType) { if (!produceDiagnostics) { return; } // Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions. if (returnType && maybeTypeOfKind(returnType, 1 /* Any */ | 2048 /* 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 !== 208 /* Block */ || !functionHasImplicitReturn(func)) { return; } var hasExplicitReturn = func.flags & 256 /* HasExplicitReturn */; if (returnType && returnType.flags & 16384 /* Never */) { error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_returning_never_cannot_have_a_reachable_end_point); } else if (returnType && !hasExplicitReturn) { // minimal check: function has syntactic return type annotation and no explicit return statements in the body // this function does not conform to the specification. // NOTE: having returnType !== undefined is a precondition for entering this branch so func.type will always be present error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.A_function_whose_declared_type_is_neither_void_nor_any_must_return_a_value); } else if (returnType && strictNullChecks && !isTypeAssignableTo(undefinedType, returnType)) { error(ts.getEffectiveReturnTypeNode(func), ts.Diagnostics.Function_lacks_ending_return_statement_and_return_type_does_not_include_undefined); } else if (compilerOptions.noImplicitReturns) { if (!returnType) { // If return type annotation is omitted check if function has any explicit return statements. // If it does not have any - its inferred return type is void - don't do any checks. // Otherwise get inferred return type from function body and report error only if it is not void / anytype if (!hasExplicitReturn) { return; } var inferredReturnType = getReturnTypeOfSignature(getSignatureFromDeclaration(func)); if (isUnwrappedReturnTypeVoidOrAny(func, inferredReturnType)) { return; } } error(ts.getEffectiveReturnTypeNode(func) || func, ts.Diagnostics.Not_all_code_paths_return_a_value); } } function checkFunctionExpressionOrObjectLiteralMethod(node, checkMode) { ts.Debug.assert(node.kind !== 152 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); // The identityMapper object is used to indicate that function expressions are wildcards if (checkMode === 1 /* SkipContextSensitive */ && isContextSensitive(node)) { checkNodeDeferred(node); return anyFunctionType; } // Grammar checking var hasGrammarError = checkGrammarFunctionLikeDeclaration(node); if (!hasGrammarError && node.kind === 187 /* FunctionExpression */) { checkGrammarForGenerator(node); } var links = getNodeLinks(node); var type = getTypeOfSymbol(node.symbol); // Check if function expression is contextually typed and assign parameter types if so. if (!(links.flags & 1024 /* ContextChecked */)) { var contextualSignature = getContextualSignature(node); // If a type check is started at a function expression that is an argument of a function call, obtaining the // contextual type may recursively get back to here during overload resolution of the call. If so, we will have // already assigned contextual types. if (!(links.flags & 1024 /* ContextChecked */)) { links.flags |= 1024 /* ContextChecked */; if (contextualSignature) { var signature = getSignaturesOfType(type, 0 /* Call */)[0]; if (isContextSensitive(node)) { var contextualMapper = getContextualMapper(node); if (checkMode === 2 /* Inferential */) { inferFromAnnotatedParameters(signature, contextualSignature, contextualMapper); } var instantiatedContextualSignature = contextualMapper === identityMapper ? contextualSignature : instantiateSignature(contextualSignature, contextualMapper); assignContextualParameterTypes(signature, instantiatedContextualSignature); } if (!ts.getEffectiveReturnTypeNode(node) && !signature.resolvedReturnType) { var returnType = getReturnTypeFromBody(node, checkMode); if (!signature.resolvedReturnType) { signature.resolvedReturnType = returnType; } } } checkSignatureDeclaration(node); checkNodeDeferred(node); } } if (produceDiagnostics && node.kind !== 152 /* MethodDeclaration */) { checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); } return type; } function checkFunctionExpressionOrObjectLiteralMethodDeferred(node) { ts.Debug.assert(node.kind !== 152 /* MethodDeclaration */ || ts.isObjectLiteralMethod(node)); var functionFlags = ts.getFunctionFlags(node); var returnTypeNode = ts.getEffectiveReturnTypeNode(node); var returnOrPromisedType = returnTypeNode && ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ ? checkAsyncFunctionReturnType(node) : // Async function getTypeFromTypeNode(returnTypeNode)); // AsyncGenerator function, Generator function, or normal function if ((functionFlags & 1 /* Generator */) === 0) { // return is not necessary in the body of generators checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType); } if (node.body) { if (!returnTypeNode) { // There are some checks that are only performed in getReturnTypeFromBody, that may produce errors // we need. An example is the noImplicitAny errors resulting from widening the return expression // of a function. Because checking of function expression bodies is deferred, there was never an // appropriate time to do this during the main walk of the file (see the comment at the top of // checkFunctionExpressionBodies). So it must be done now. getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } if (node.body.kind === 208 /* Block */) { checkSourceElement(node.body); } else { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so we // should not be checking assignability of a promise to the return type. Instead, we need to // check assignability of the awaited type of the expression body against the promised type of // its return type annotation. var exprType = checkExpression(node.body); if (returnOrPromisedType) { if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */) { var awaitedType = checkAwaitedType(exprType, node.body, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body); } else { checkTypeAssignableTo(exprType, returnOrPromisedType, node.body); } } } registerForUnusedIdentifiersCheck(node); } } function checkArithmeticOperandType(operand, type, diagnostic) { if (!isTypeAssignableToKind(type, 84 /* NumberLike */)) { error(operand, diagnostic); return false; } return true; } function isReadonlySymbol(symbol) { // The following symbols are considered read-only: // Properties with a 'readonly' modifier // Variables declared with 'const' // Get accessors without matching set accessors // Enum members // Unions and intersections of the above (unions and intersections eagerly set isReadonly on creation) return !!(ts.getCheckFlags(symbol) & 8 /* Readonly */ || symbol.flags & 4 /* Property */ && ts.getDeclarationModifierFlagsFromSymbol(symbol) & 64 /* Readonly */ || symbol.flags & 3 /* Variable */ && getDeclarationNodeFlagsFromSymbol(symbol) & 2 /* Const */ || symbol.flags & 98304 /* Accessor */ && !(symbol.flags & 65536 /* SetAccessor */) || symbol.flags & 8 /* EnumMember */); } function isReferenceToReadonlyEntity(expr, symbol) { if (isReadonlySymbol(symbol)) { // Allow assignments to readonly properties within constructors of the same class declaration. if (symbol.flags & 4 /* Property */ && (expr.kind === 180 /* PropertyAccessExpression */ || expr.kind === 181 /* ElementAccessExpression */) && expr.expression.kind === 99 /* ThisKeyword */) { // Look for if this is the constructor for the class that `symbol` is a property of. var func = ts.getContainingFunction(expr); if (!(func && func.kind === 153 /* 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 === 180 /* PropertyAccessExpression */ || expr.kind === 181 /* ElementAccessExpression */) { var node = ts.skipParentheses(expr.expression); if (node.kind === 71 /* Identifier */) { var symbol = getNodeLinks(node).resolvedSymbol; if (symbol.flags & 2097152 /* Alias */) { var declaration = getDeclarationOfAliasSymbol(symbol); return declaration && declaration.kind === 241 /* NamespaceImport */; } } } return false; } function checkReferenceExpression(expr, invalidReferenceMessage) { // References are combinations of identifiers, parentheses, and property accesses. var node = ts.skipOuterExpressions(expr, 2 /* Assertions */ | 1 /* Parentheses */); if (node.kind !== 71 /* Identifier */ && node.kind !== 180 /* PropertyAccessExpression */ && node.kind !== 181 /* ElementAccessExpression */) { error(expr, invalidReferenceMessage); return false; } return true; } function checkDeleteExpression(node) { checkExpression(node.expression); var expr = ts.skipParentheses(node.expression); if (expr.kind !== 180 /* PropertyAccessExpression */ && expr.kind !== 181 /* ElementAccessExpression */) { error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_must_be_a_property_reference); return booleanType; } var links = getNodeLinks(expr); var symbol = getExportSymbolOfValueSymbolIfExported(links.resolvedSymbol); if (symbol && isReadonlySymbol(symbol)) { error(expr, ts.Diagnostics.The_operand_of_a_delete_operator_cannot_be_a_read_only_property); } return booleanType; } function checkTypeOfExpression(node) { checkExpression(node.expression); return typeofType; } function checkVoidExpression(node) { checkExpression(node.expression); return undefinedWideningType; } function checkAwaitExpression(node) { // Grammar checking if (produceDiagnostics) { if (!(node.flags & 16384 /* AwaitContext */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.await_expression_is_only_allowed_within_an_async_function); } if (isInParameterInitializerBeforeContainingFunction(node)) { error(node, ts.Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer); } } var operandType = checkExpression(node.expression); return checkAwaitedType(operandType, node, ts.Diagnostics.Type_of_await_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } function checkPrefixUnaryExpression(node) { var operandType = checkExpression(node.operand); if (operandType === silentNeverType) { return silentNeverType; } if (node.operand.kind === 8 /* NumericLiteral */) { if (node.operator === 38 /* MinusToken */) { return getFreshTypeOfLiteralType(getLiteralType(-node.operand.text)); } else if (node.operator === 37 /* PlusToken */) { return getFreshTypeOfLiteralType(getLiteralType(+node.operand.text)); } } switch (node.operator) { case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: checkNonNullType(operandType, node.operand); if (maybeTypeOfKind(operandType, 1536 /* ESSymbolLike */)) { error(node.operand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(node.operator)); } return numberType; case 51 /* ExclamationToken */: var facts = getTypeFacts(operandType) & (1048576 /* Truthy */ | 2097152 /* Falsy */); return facts === 1048576 /* Truthy */ ? falseType : facts === 2097152 /* Falsy */ ? trueType : booleanType; case 43 /* PlusPlusToken */: case 44 /* MinusMinusToken */: var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); } return numberType; } return unknownType; } function checkPostfixUnaryExpression(node) { var operandType = checkExpression(node.operand); if (operandType === silentNeverType) { return silentNeverType; } var ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), ts.Diagnostics.An_arithmetic_operand_must_be_of_type_any_number_or_an_enum_type); if (ok) { // run check only if former checks succeeded to avoid reporting cascading errors checkReferenceExpression(node.operand, ts.Diagnostics.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access); } return numberType; } // Return true if type might be of the given kind. A union or intersection type might be of a given // kind if at least one constituent type is of the given kind. function maybeTypeOfKind(type, kind) { if (type.flags & kind) { return true; } if (type.flags & 393216 /* UnionOrIntersection */) { var types = type.types; for (var _i = 0, types_18 = types; _i < types_18.length; _i++) { var t = types_18[_i]; if (maybeTypeOfKind(t, kind)) { return true; } } } return false; } function isTypeAssignableToKind(source, kind, strict) { if (source.flags & kind) { return true; } if (strict && source.flags & (1 /* Any */ | 2048 /* Void */ | 4096 /* Undefined */ | 8192 /* Null */)) { return false; } return (kind & 84 /* NumberLike */ && isTypeAssignableTo(source, numberType)) || (kind & 524322 /* StringLike */ && isTypeAssignableTo(source, stringType)) || (kind & 136 /* BooleanLike */ && isTypeAssignableTo(source, booleanType)) || (kind & 2048 /* Void */ && isTypeAssignableTo(source, voidType)) || (kind & 16384 /* Never */ && isTypeAssignableTo(source, neverType)) || (kind & 8192 /* Null */ && isTypeAssignableTo(source, nullType)) || (kind & 4096 /* Undefined */ && isTypeAssignableTo(source, undefinedType)) || (kind & 512 /* ESSymbol */ && isTypeAssignableTo(source, esSymbolType)) || (kind & 33554432 /* NonPrimitive */ && isTypeAssignableTo(source, nonPrimitiveType)); } function allTypesAssignableToKind(source, kind, strict) { return source.flags & 131072 /* Union */ ? ts.every(source.types, function (subType) { return allTypesAssignableToKind(subType, kind, strict); }) : isTypeAssignableToKind(source, kind, strict); } function isConstEnumObjectType(type) { return ts.getObjectFlags(type) & 16 /* Anonymous */ && type.symbol && isConstEnumSymbol(type.symbol); } function isConstEnumSymbol(symbol) { return (symbol.flags & 128 /* ConstEnum */) !== 0; } function checkInstanceOfExpression(left, right, leftType, rightType) { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } // TypeScript 1.0 spec (April 2014): 4.15.4 // The instanceof operator requires the left operand to be of type Any, an object type, or a type parameter type, // and the right operand to be of type Any, a subtype of the 'Function' interface type, or have a call or construct signature. // The result is always of the Boolean primitive type. // NOTE: do not raise error if leftType is unknown as related error was already reported if (!isTypeAny(leftType) && allTypesAssignableToKind(leftType, 16382 /* 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) || typeHasCallOrConstructSignatures(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) { if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); // TypeScript 1.0 spec (April 2014): 4.15.5 // The in operator requires the left operand to be of type Any, the String primitive type, or the Number primitive type, // and the right operand to be of type Any, an object type, or a type parameter type. // The result is always of the Boolean primitive type. if (!(isTypeComparableTo(leftType, stringType) || isTypeAssignableToKind(leftType, 84 /* NumberLike */ | 1536 /* ESSymbolLike */))) { error(left, ts.Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_type_any_string_number_or_symbol); } if (!isTypeAssignableToKind(rightType, 33554432 /* NonPrimitive */ | 1081344 /* TypeVariable */)) { error(right, ts.Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter); } return booleanType; } function checkObjectLiteralAssignment(node, sourceType) { var properties = node.properties; for (var _i = 0, properties_7 = properties; _i < properties_7.length; _i++) { var p = properties_7[_i]; checkObjectLiteralDestructuringPropertyAssignment(sourceType, p, properties); } return sourceType; } /** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */ function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType, property, allProperties) { if (property.kind === 265 /* PropertyAssignment */ || property.kind === 266 /* ShorthandPropertyAssignment */) { var name = property.name; if (name.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(name); } if (isComputedNonLiteralName(name)) { return undefined; } var text = ts.getTextOfPropertyName(name); var type = isTypeAny(objectLiteralType) ? objectLiteralType : getTypeOfPropertyOfType(objectLiteralType, text) || isNumericLiteralName(text) && getIndexTypeOfType(objectLiteralType, 1 /* Number */) || getIndexTypeOfType(objectLiteralType, 0 /* String */); if (type) { if (property.kind === 266 /* ShorthandPropertyAssignment */) { return checkDestructuringAssignment(property, type); } else { // non-shorthand property assignments should always have initializers return checkDestructuringAssignment(property.initializer, type); } } else { error(name, ts.Diagnostics.Type_0_has_no_property_1_and_no_string_index_signature, typeToString(objectLiteralType), ts.declarationNameToString(name)); } } else if (property.kind === 267 /* SpreadAssignment */) { if (languageVersion < 6 /* ESNext */) { checkExternalEmitHelpers(property, 4 /* Rest */); } var nonRestNames = []; if (allProperties) { for (var i = 0; i < allProperties.length - 1; i++) { nonRestNames.push(allProperties[i].name); } } var type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol); return checkDestructuringAssignment(property.expression, type); } else { error(property, ts.Diagnostics.Property_assignment_expected); } } function checkArrayLiteralAssignment(node, sourceType, checkMode) { if (languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, 512 /* Read */); } // This elementType will be used if the specific property corresponding to this index is not // present (aka the tuple element property). This call also checks that the parentType is in // fact an iterable or array (depending on target language). var elementType = checkIteratedTypeOrElementType(sourceType, node, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; var elements = node.elements; for (var i = 0; i < elements.length; i++) { checkArrayLiteralDestructuringElementAssignment(node, sourceType, i, elementType, checkMode); } return sourceType; } function checkArrayLiteralDestructuringElementAssignment(node, sourceType, elementIndex, elementType, checkMode) { var elements = node.elements; var element = elements[elementIndex]; if (element.kind !== 201 /* OmittedExpression */) { if (element.kind !== 199 /* SpreadElement */) { var propName = "" + elementIndex; var type = isTypeAny(sourceType) ? sourceType : isTupleLikeType(sourceType) ? getTypeOfPropertyOfType(sourceType, propName) : elementType; if (type) { return checkDestructuringAssignment(element, type, checkMode); } else { // We still need to check element expression here because we may need to set appropriate flag on the expression // such as NodeCheckFlags.LexicalThis on "this"expression. checkExpression(element); if (isTupleType(sourceType)) { error(element, ts.Diagnostics.Tuple_type_0_with_length_1_cannot_be_assigned_to_tuple_with_length_2, typeToString(sourceType), getTypeReferenceArity(sourceType), elements.length); } else { error(element, ts.Diagnostics.Type_0_has_no_property_1, typeToString(sourceType), propName); } } } else { if (elementIndex < elements.length - 1) { error(element, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } else { var restExpression = element.expression; if (restExpression.kind === 195 /* BinaryExpression */ && restExpression.operatorToken.kind === 58 /* EqualsToken */) { error(restExpression.operatorToken, ts.Diagnostics.A_rest_element_cannot_have_an_initializer); } else { return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode); } } } } return undefined; } function checkDestructuringAssignment(exprOrAssignment, sourceType, checkMode) { var target; if (exprOrAssignment.kind === 266 /* ShorthandPropertyAssignment */) { var prop = exprOrAssignment; if (prop.objectAssignmentInitializer) { // In strict null checking mode, if a default value of a non-undefined type is specified, remove // undefined from the final type. if (strictNullChecks && !(getFalsyFlags(checkExpression(prop.objectAssignmentInitializer)) & 4096 /* Undefined */)) { sourceType = getTypeWithFacts(sourceType, 131072 /* NEUndefined */); } checkBinaryLikeExpression(prop.name, prop.equalsToken, prop.objectAssignmentInitializer, checkMode); } target = exprOrAssignment.name; } else { target = exprOrAssignment; } if (target.kind === 195 /* BinaryExpression */ && target.operatorToken.kind === 58 /* EqualsToken */) { checkBinaryExpression(target, checkMode); target = target.left; } if (target.kind === 179 /* ObjectLiteralExpression */) { return checkObjectLiteralAssignment(target, sourceType); } if (target.kind === 178 /* ArrayLiteralExpression */) { return checkArrayLiteralAssignment(target, sourceType, checkMode); } return checkReferenceAssignment(target, sourceType, checkMode); } function checkReferenceAssignment(target, sourceType, checkMode) { var targetType = checkExpression(target, checkMode); var error = target.parent.kind === 267 /* SpreadAssignment */ ? ts.Diagnostics.The_target_of_an_object_rest_assignment_must_be_a_variable_or_a_property_access : ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access; if (checkReferenceExpression(target, error)) { checkTypeAssignableTo(sourceType, targetType, target, /*headMessage*/ undefined); } return sourceType; } /** * This is a *shallow* check: An expression is side-effect-free if the * evaluation of the expression *itself* cannot produce side effects. * For example, x++ / 3 is side-effect free because the / operator * does not have side effects. * The intent is to "smell test" an expression for correctness in positions where * its value is discarded (e.g. the left side of the comma operator). */ function isSideEffectFree(node) { node = ts.skipParentheses(node); switch (node.kind) { case 71 /* Identifier */: case 9 /* StringLiteral */: case 12 /* RegularExpressionLiteral */: case 184 /* TaggedTemplateExpression */: case 197 /* TemplateExpression */: case 13 /* NoSubstitutionTemplateLiteral */: case 8 /* NumericLiteral */: case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: case 95 /* NullKeyword */: case 139 /* UndefinedKeyword */: case 187 /* FunctionExpression */: case 200 /* ClassExpression */: case 188 /* ArrowFunction */: case 178 /* ArrayLiteralExpression */: case 179 /* ObjectLiteralExpression */: case 190 /* TypeOfExpression */: case 204 /* NonNullExpression */: case 251 /* JsxSelfClosingElement */: case 250 /* JsxElement */: return true; case 196 /* ConditionalExpression */: return isSideEffectFree(node.whenTrue) && isSideEffectFree(node.whenFalse); case 195 /* BinaryExpression */: if (ts.isAssignmentOperator(node.operatorToken.kind)) { return false; } return isSideEffectFree(node.left) && isSideEffectFree(node.right); case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: // Unary operators ~, !, +, and - have no side effects. // The rest do. switch (node.operator) { case 51 /* ExclamationToken */: case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: return true; } return false; // Some forms listed here for clarity case 191 /* VoidExpression */: // Explicit opt-out case 185 /* TypeAssertionExpression */: // Not SEF, but can produce useful type warnings case 203 /* AsExpression */: // Not SEF, but can produce useful type warnings default: return false; } } function isTypeEqualityComparableTo(source, target) { return (target.flags & 12288 /* Nullable */) !== 0 || isTypeComparableTo(source, target); } function checkBinaryExpression(node, checkMode) { return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, checkMode, node); } function checkBinaryLikeExpression(left, operatorToken, right, checkMode, errorNode) { var operator = operatorToken.kind; if (operator === 58 /* EqualsToken */ && (left.kind === 179 /* ObjectLiteralExpression */ || left.kind === 178 /* ArrayLiteralExpression */)) { return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode); } var leftType = checkExpression(left, checkMode); var rightType = checkExpression(right, checkMode); switch (operator) { case 39 /* AsteriskToken */: case 40 /* AsteriskAsteriskToken */: case 61 /* AsteriskEqualsToken */: case 62 /* AsteriskAsteriskEqualsToken */: case 41 /* SlashToken */: case 63 /* SlashEqualsToken */: case 42 /* PercentToken */: case 64 /* PercentEqualsToken */: case 38 /* MinusToken */: case 60 /* MinusEqualsToken */: case 45 /* LessThanLessThanToken */: case 65 /* LessThanLessThanEqualsToken */: case 46 /* GreaterThanGreaterThanToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 49 /* BarToken */: case 69 /* BarEqualsToken */: case 50 /* CaretToken */: case 70 /* CaretEqualsToken */: case 48 /* AmpersandToken */: case 68 /* AmpersandEqualsToken */: if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); var suggestedOperator = void 0; // if a user tries to apply a bitwise operator to 2 boolean operands // try and return them a helpful suggestion if ((leftType.flags & 136 /* BooleanLike */) && (rightType.flags & 136 /* BooleanLike */) && (suggestedOperator = getSuggestedBooleanOperator(operatorToken.kind)) !== undefined) { error(errorNode || operatorToken, ts.Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, ts.tokenToString(operatorToken.kind), ts.tokenToString(suggestedOperator)); } else { // otherwise just check each operand separately and report errors as normal var leftOk = checkArithmeticOperandType(left, leftType, ts.Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); var rightOk = checkArithmeticOperandType(right, rightType, ts.Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); if (leftOk && rightOk) { checkAssignmentOperator(numberType); } } return numberType; case 37 /* PlusToken */: case 59 /* PlusEqualsToken */: if (leftType === silentNeverType || rightType === silentNeverType) { return silentNeverType; } if (!isTypeAssignableToKind(leftType, 524322 /* StringLike */) && !isTypeAssignableToKind(rightType, 524322 /* StringLike */)) { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); } var resultType = void 0; if (isTypeAssignableToKind(leftType, 84 /* NumberLike */, /*strict*/ true) && isTypeAssignableToKind(rightType, 84 /* NumberLike */, /*strict*/ true)) { // Operands of an enum type are treated as having the primitive type Number. // If both operands are of the Number primitive type, the result is of the Number primitive type. resultType = numberType; } else if (isTypeAssignableToKind(leftType, 524322 /* StringLike */, /*strict*/ true) || isTypeAssignableToKind(rightType, 524322 /* StringLike */, /*strict*/ true)) { // If one or both operands are of the String primitive type, the result is of the String primitive type. resultType = stringType; } else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. // NOTE: unknown type here denotes error type. Old compiler treated this case as any type so do we. resultType = leftType === unknownType || rightType === unknownType ? unknownType : anyType; } // Symbols are not allowed at all in arithmetic expressions if (resultType && !checkForDisallowedESSymbolOperand(operator)) { return resultType; } if (!resultType) { reportOperatorError(); return anyType; } if (operator === 59 /* PlusEqualsToken */) { checkAssignmentOperator(resultType); } return resultType; case 27 /* LessThanToken */: case 29 /* GreaterThanToken */: case 30 /* LessThanEqualsToken */: case 31 /* GreaterThanEqualsToken */: if (checkForDisallowedESSymbolOperand(operator)) { leftType = getBaseTypeOfLiteralType(checkNonNullType(leftType, left)); rightType = getBaseTypeOfLiteralType(checkNonNullType(rightType, right)); if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) { reportOperatorError(); } } return booleanType; case 32 /* EqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: var leftIsLiteral = isLiteralType(leftType); var rightIsLiteral = isLiteralType(rightType); if (!leftIsLiteral || !rightIsLiteral) { leftType = leftIsLiteral ? getBaseTypeOfLiteralType(leftType) : leftType; rightType = rightIsLiteral ? getBaseTypeOfLiteralType(rightType) : rightType; } if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) { reportOperatorError(); } return booleanType; case 93 /* InstanceOfKeyword */: return checkInstanceOfExpression(left, right, leftType, rightType); case 92 /* InKeyword */: return checkInExpression(left, right, leftType, rightType); case 53 /* AmpersandAmpersandToken */: return getTypeFacts(leftType) & 1048576 /* Truthy */ ? getUnionType([extractDefinitelyFalsyTypes(strictNullChecks ? leftType : getBaseTypeOfLiteralType(rightType)), rightType]) : leftType; case 54 /* BarBarToken */: return getTypeFacts(leftType) & 2097152 /* Falsy */ ? getUnionType([removeDefinitelyFalsyTypes(leftType), rightType], /*subtypeReduction*/ true) : leftType; case 58 /* EqualsToken */: checkAssignmentOperator(rightType); return getRegularTypeOfObjectLiteral(rightType); case 26 /* CommaToken */: if (!compilerOptions.allowUnreachableCode && isSideEffectFree(left) && !isEvalNode(right)) { error(left, ts.Diagnostics.Left_side_of_comma_operator_is_unused_and_has_no_side_effects); } return rightType; } function isEvalNode(node) { return node.kind === 71 /* Identifier */ && node.escapedText === "eval"; } // Return true if there was no error, false if there was an error. function checkForDisallowedESSymbolOperand(operator) { var offendingSymbolOperand = maybeTypeOfKind(leftType, 1536 /* ESSymbolLike */) ? left : maybeTypeOfKind(rightType, 1536 /* ESSymbolLike */) ? right : undefined; if (offendingSymbolOperand) { error(offendingSymbolOperand, ts.Diagnostics.The_0_operator_cannot_be_applied_to_type_symbol, ts.tokenToString(operator)); return false; } return true; } function getSuggestedBooleanOperator(operator) { switch (operator) { case 49 /* BarToken */: case 69 /* BarEqualsToken */: return 54 /* BarBarToken */; case 50 /* CaretToken */: case 70 /* CaretEqualsToken */: return 35 /* ExclamationEqualsEqualsToken */; case 48 /* AmpersandToken */: case 68 /* AmpersandEqualsToken */: return 53 /* AmpersandAmpersandToken */; default: return undefined; } } function checkAssignmentOperator(valueType) { if (produceDiagnostics && ts.isAssignmentOperator(operator)) { // TypeScript 1.0 spec (April 2014): 4.17 // An assignment of the form // VarExpr = ValueExpr // requires VarExpr to be classified as a reference // A compound assignment furthermore requires VarExpr to be classified as a reference (section 4.1) // and the type of the non - compound operation to be assignable to the type of VarExpr. if (checkReferenceExpression(left, ts.Diagnostics.The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access)) { // to avoid cascading errors check assignability only if 'isReference' check succeeded and no errors were reported checkTypeAssignableTo(valueType, leftType, left, /*headMessage*/ undefined); } } } function reportOperatorError() { error(errorNode || operatorToken, ts.Diagnostics.Operator_0_cannot_be_applied_to_types_1_and_2, ts.tokenToString(operatorToken.kind), typeToString(leftType), typeToString(rightType)); } } function isYieldExpressionInClass(node) { var current = node; var parent = node.parent; while (parent) { if (ts.isFunctionLike(parent) && current === parent.body) { return false; } else if (ts.isClassLike(current)) { return true; } current = parent; parent = parent.parent; } return false; } function checkYieldExpression(node) { // Grammar checking if (produceDiagnostics) { if (!(node.flags & 4096 /* YieldContext */) || isYieldExpressionInClass(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body); } if (isInParameterInitializerBeforeContainingFunction(node)) { error(node, ts.Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer); } } if (node.expression) { var func = ts.getContainingFunction(node); // If the user's code is syntactically correct, the func should always have a star. After all, // we are in a yield context. var functionFlags = func && ts.getFunctionFlags(func); if (node.asteriskToken) { // Async generator functions prior to ESNext require the __await, __asyncDelegator, // and __asyncValues helpers if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 6 /* ESNext */) { checkExternalEmitHelpers(node, 26624 /* AsyncDelegatorIncludes */); } // Generator functions prior to ES2015 require the __values helper if ((functionFlags & 3 /* AsyncGenerator */) === 1 /* Generator */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, 256 /* Values */); } } if (functionFlags & 1 /* Generator */) { var expressionType = checkExpressionCached(node.expression); var expressionElementType = void 0; var nodeIsYieldStar = !!node.asteriskToken; if (nodeIsYieldStar) { expressionElementType = checkIteratedTypeOrElementType(expressionType, node.expression, /*allowStringInput*/ false, (functionFlags & 2 /* Async */) !== 0); } // There is no point in doing an assignability check if the function // has no explicit return type because the return type is directly computed // from the yield expressions. var returnType = ts.getEffectiveReturnTypeNode(func); if (returnType) { var signatureElementType = getIteratedTypeOfGenerator(getTypeFromTypeNode(returnType), (functionFlags & 2 /* Async */) !== 0) || anyType; if (nodeIsYieldStar) { checkTypeAssignableTo(functionFlags & 2 /* Async */ ? getAwaitedType(expressionElementType, node.expression, ts.Diagnostics.Type_of_iterated_elements_of_a_yield_Asterisk_operand_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) : expressionElementType, signatureElementType, node.expression, /*headMessage*/ undefined); } else { checkTypeAssignableTo(functionFlags & 2 /* Async */ ? getAwaitedType(expressionType, node.expression, ts.Diagnostics.Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member) : expressionType, signatureElementType, node.expression, /*headMessage*/ undefined); } } } } // Both yield and yield* expressions have type 'any' return anyType; } function checkConditionalExpression(node, checkMode) { checkExpression(node.condition); var type1 = checkExpression(node.whenTrue, checkMode); var type2 = checkExpression(node.whenFalse, checkMode); return getUnionType([type1, type2], /*subtypeReduction*/ true); } function checkTemplateExpression(node) { // We just want to check each expressions, but we are unconcerned with // the type of each expression, as any value may be coerced into a string. // It is worth asking whether this is what we really want though. // A place where we actually *are* concerned with the expressions' types are // in tagged templates. ts.forEach(node.templateSpans, function (templateSpan) { checkExpression(templateSpan.expression); }); return stringType; } function checkExpressionWithContextualType(node, contextualType, contextualMapper) { var saveContextualType = node.contextualType; var saveContextualMapper = node.contextualMapper; node.contextualType = contextualType; node.contextualMapper = contextualMapper; var checkMode = contextualMapper === identityMapper ? 1 /* SkipContextSensitive */ : contextualMapper ? 2 /* Inferential */ : 0 /* Normal */; var result = checkExpression(node, checkMode); node.contextualType = saveContextualType; node.contextualMapper = saveContextualMapper; return result; } function checkExpressionCached(node, checkMode) { var links = getNodeLinks(node); if (!links.resolvedType) { // When computing a type that we're going to cache, we need to ignore any ongoing control flow // analysis because variables may have transient types in indeterminable states. Moving flowLoopStart // to the top of the stack ensures all transient types are computed from a known point. var saveFlowLoopStart = flowLoopStart; flowLoopStart = flowLoopCount; links.resolvedType = checkExpression(node, checkMode); flowLoopStart = saveFlowLoopStart; } return links.resolvedType; } function isTypeAssertion(node) { node = ts.skipParentheses(node); return node.kind === 185 /* TypeAssertionExpression */ || node.kind === 203 /* AsExpression */; } function checkDeclarationInitializer(declaration) { var type = getTypeOfExpression(declaration.initializer, /*cache*/ true); return ts.getCombinedNodeFlags(declaration) & 2 /* Const */ || (ts.getCombinedModifierFlags(declaration) & 64 /* Readonly */ && !ts.isParameterPropertyDeclaration(declaration)) || isTypeAssertion(declaration.initializer) ? type : getWidenedLiteralType(type); } function isLiteralOfContextualType(candidateType, contextualType) { if (contextualType) { if (contextualType.flags & 131072 /* Union */ && !(contextualType.flags & 8 /* Boolean */)) { // If the contextual type is a union containing both of the 'true' and 'false' types we // don't consider it a literal context for boolean literals. var types_19 = contextualType.types; return ts.some(types_19, function (t) { return !(t.flags & 128 /* BooleanLiteral */ && containsType(types_19, trueType) && containsType(types_19, falseType)) && isLiteralOfContextualType(candidateType, t); }); } if (contextualType.flags & 1081344 /* TypeVariable */) { // If the contextual type is a type variable constrained to a primitive type, consider // this a literal context for literals of that primitive type. For example, given a // type parameter 'T extends string', infer string literal types for T. var constraint = getBaseConstraintOfType(contextualType) || emptyObjectType; return constraint.flags & 2 /* String */ && maybeTypeOfKind(candidateType, 32 /* StringLiteral */) || constraint.flags & 4 /* Number */ && maybeTypeOfKind(candidateType, 64 /* NumberLiteral */) || constraint.flags & 8 /* Boolean */ && maybeTypeOfKind(candidateType, 128 /* BooleanLiteral */) || constraint.flags & 512 /* ESSymbol */ && maybeTypeOfKind(candidateType, 1024 /* UniqueESSymbol */) || isLiteralOfContextualType(candidateType, constraint); } // If the contextual type is a literal of a particular primitive type, we consider this a // literal context for all literals of that primitive type. return contextualType.flags & (32 /* StringLiteral */ | 524288 /* Index */) && maybeTypeOfKind(candidateType, 32 /* StringLiteral */) || contextualType.flags & 64 /* NumberLiteral */ && maybeTypeOfKind(candidateType, 64 /* NumberLiteral */) || contextualType.flags & 128 /* BooleanLiteral */ && maybeTypeOfKind(candidateType, 128 /* BooleanLiteral */) || contextualType.flags & 1024 /* UniqueESSymbol */ && maybeTypeOfKind(candidateType, 1024 /* UniqueESSymbol */); } return false; } function checkExpressionForMutableLocation(node, checkMode, contextualType) { if (arguments.length === 2) { contextualType = getContextualType(node); } var type = checkExpression(node, checkMode); return isTypeAssertion(node) ? type : getWidenedLiteralLikeTypeForContextualType(type, contextualType); } function checkPropertyAssignment(node, checkMode) { // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(node.name); } return checkExpressionForMutableLocation(node.initializer, checkMode); } function checkObjectLiteralMethod(node, checkMode) { // Grammar checking checkGrammarMethod(node); // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(node.name); } var uninstantiatedType = checkFunctionExpressionOrObjectLiteralMethod(node, checkMode); return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } function instantiateTypeWithSingleGenericCallSignature(node, type, checkMode) { if (checkMode === 2 /* Inferential */) { var signature = getSingleCallSignature(type); if (signature && signature.typeParameters) { var contextualType = getApparentTypeOfContextualType(node); if (contextualType) { var contextualSignature = getSingleCallSignature(getNonNullableType(contextualType)); if (contextualSignature && !contextualSignature.typeParameters) { return getOrCreateTypeFromSignature(instantiateSignatureInContextOf(signature, contextualSignature, getContextualMapper(node))); } } } } return type; } /** * Returns the type of an expression. Unlike checkExpression, this function is simply concerned * with computing the type and may not fully check all contained sub-expressions for errors. * A cache argument of true indicates that if the function performs a full type check, it is ok * to cache the result. */ function getTypeOfExpression(node, cache) { // Optimize for the common case of a call to a function with a single non-generic call // signature where we can just fetch the return type without checking the arguments. if (node.kind === 182 /* CallExpression */ && node.expression.kind !== 97 /* SuperKeyword */ && !ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true) && !isSymbolOrSymbolForCall(node)) { var funcType = checkNonNullExpression(node.expression); var signature = getSingleCallSignature(funcType); if (signature && !signature.typeParameters) { return getReturnTypeOfSignature(signature); } } // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions // should have a parameter that indicates whether full error checking is required such that // we can perform the optimizations locally. return cache ? checkExpressionCached(node) : checkExpression(node); } /** * Returns the type of an expression. Unlike checkExpression, this function is simply concerned * with computing the type and may not fully check all contained sub-expressions for errors. * It is intended for uses where you know there is no contextual type, * and requesting the contextual type might cause a circularity or other bad behaviour. * It sets the contextual type of the node to any before calling getTypeOfExpression. */ function getContextFreeTypeOfExpression(node) { var saveContextualType = node.contextualType; node.contextualType = anyType; var type = getTypeOfExpression(node); node.contextualType = saveContextualType; return type; } // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the // expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in // conjunction with the generic contextual type. When contextualMapper is equal to the identityMapper function // object, it serves as an indicator that all contained function and arrow expressions should be considered to // have the wildcard function type; this form of type check is used during overload resolution to exclude // contextually typed function and arrow expressions in the initial phase. function checkExpression(node, checkMode) { var type; if (node.kind === 144 /* QualifiedName */) { type = checkQualifiedName(node); } else { var uninstantiatedType = checkExpressionWorker(node, checkMode); type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode); } if (isConstEnumObjectType(type)) { // enum object type for const enums are only permitted in: // - 'left' in property access // - 'object' in indexed access // - target in rhs of import statement var ok = (node.parent.kind === 180 /* PropertyAccessExpression */ && node.parent.expression === node) || (node.parent.kind === 181 /* ElementAccessExpression */ && node.parent.expression === node) || ((node.kind === 71 /* Identifier */ || node.kind === 144 /* QualifiedName */) && isInRightSideOfImportOrExportAssignment(node)); if (!ok) { error(node, ts.Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment); } } return type; } function checkParenthesizedExpression(node, checkMode) { var tag = ts.isInJavaScriptFile(node) ? ts.getJSDocTypeTag(node) : undefined; if (tag) { return checkAssertionWorker(tag, tag.typeExpression.type, node.expression, checkMode); } return checkExpression(node.expression, checkMode); } function checkExpressionWorker(node, checkMode) { switch (node.kind) { case 71 /* Identifier */: return checkIdentifier(node); case 99 /* ThisKeyword */: return checkThisExpression(node); case 97 /* SuperKeyword */: return checkSuperExpression(node); case 95 /* NullKeyword */: return nullWideningType; case 13 /* NoSubstitutionTemplateLiteral */: case 9 /* StringLiteral */: return getFreshTypeOfLiteralType(getLiteralType(node.text)); case 8 /* NumericLiteral */: checkGrammarNumericLiteral(node); return getFreshTypeOfLiteralType(getLiteralType(+node.text)); case 101 /* TrueKeyword */: return trueType; case 86 /* FalseKeyword */: return falseType; case 197 /* TemplateExpression */: return checkTemplateExpression(node); case 12 /* RegularExpressionLiteral */: return globalRegExpType; case 178 /* ArrayLiteralExpression */: return checkArrayLiteral(node, checkMode); case 179 /* ObjectLiteralExpression */: return checkObjectLiteral(node, checkMode); case 180 /* PropertyAccessExpression */: return checkPropertyAccessExpression(node); case 181 /* ElementAccessExpression */: return checkIndexedAccess(node); case 182 /* CallExpression */: if (node.expression.kind === 91 /* ImportKeyword */) { return checkImportCallExpression(node); } /* falls through */ case 183 /* NewExpression */: return checkCallExpression(node); case 184 /* TaggedTemplateExpression */: return checkTaggedTemplateExpression(node); case 186 /* ParenthesizedExpression */: return checkParenthesizedExpression(node, checkMode); case 200 /* ClassExpression */: return checkClassExpression(node); case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return checkFunctionExpressionOrObjectLiteralMethod(node, checkMode); case 190 /* TypeOfExpression */: return checkTypeOfExpression(node); case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: return checkAssertion(node); case 204 /* NonNullExpression */: return checkNonNullAssertion(node); case 205 /* MetaProperty */: return checkMetaProperty(node); case 189 /* DeleteExpression */: return checkDeleteExpression(node); case 191 /* VoidExpression */: return checkVoidExpression(node); case 192 /* AwaitExpression */: return checkAwaitExpression(node); case 193 /* PrefixUnaryExpression */: return checkPrefixUnaryExpression(node); case 194 /* PostfixUnaryExpression */: return checkPostfixUnaryExpression(node); case 195 /* BinaryExpression */: return checkBinaryExpression(node, checkMode); case 196 /* ConditionalExpression */: return checkConditionalExpression(node, checkMode); case 199 /* SpreadElement */: return checkSpreadExpression(node, checkMode); case 201 /* OmittedExpression */: return undefinedWideningType; case 198 /* YieldExpression */: return checkYieldExpression(node); case 260 /* JsxExpression */: return checkJsxExpression(node, checkMode); case 250 /* JsxElement */: return checkJsxElement(node); case 251 /* JsxSelfClosingElement */: return checkJsxSelfClosingElement(node); case 254 /* JsxFragment */: return checkJsxFragment(node); case 258 /* JsxAttributes */: return checkJsxAttributes(node, checkMode); case 252 /* JsxOpeningElement */: ts.Debug.fail("Shouldn't ever directly check a JsxOpeningElement"); } return unknownType; } // DECLARATION AND STATEMENT TYPE CHECKING function checkTypeParameter(node) { // Grammar Checking if (node.expression) { grammarErrorOnFirstToken(node.expression, ts.Diagnostics.Type_expected); } checkSourceElement(node.constraint); checkSourceElement(node.default); var typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); if (!hasNonCircularBaseConstraint(typeParameter)) { error(node.constraint, ts.Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter)); } if (!hasNonCircularTypeParameterDefault(typeParameter)) { error(node.default, ts.Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter)); } var constraintType = getConstraintOfTypeParameter(typeParameter); var defaultType = getDefaultFromTypeParameter(typeParameter); if (constraintType && defaultType) { checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } if (produceDiagnostics) { checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_parameter_name_cannot_be_0); } } function checkParameter(node) { // Grammar checking // It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the // Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code // or if its FunctionBody is strict code(11.1.5). checkGrammarDecoratorsAndModifiers(node); checkVariableLikeDeclaration(node); var func = ts.getContainingFunction(node); if (ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { if (!(func.kind === 153 /* Constructor */ && ts.nodeIsPresent(func.body))) { error(node, ts.Diagnostics.A_parameter_property_is_only_allowed_in_a_constructor_implementation); } } if (node.questionToken && ts.isBindingPattern(node.name) && func.body) { error(node, ts.Diagnostics.A_binding_pattern_parameter_cannot_be_optional_in_an_implementation_signature); } if (node.name && ts.isIdentifier(node.name) && (node.name.escapedText === "this" || node.name.escapedText === "new")) { if (ts.indexOf(func.parameters, node) !== 0) { error(node, ts.Diagnostics.A_0_parameter_must_be_the_first_parameter, node.name.escapedText); } if (func.kind === 153 /* Constructor */ || func.kind === 157 /* ConstructSignature */ || func.kind === 162 /* ConstructorType */) { error(node, ts.Diagnostics.A_constructor_cannot_have_a_this_parameter); } } // Only check rest parameter type if it's not a binding pattern. Since binding patterns are // not allowed in a rest parameter, we already have an error from checkGrammarParameterList. if (node.dotDotDotToken && !ts.isBindingPattern(node.name) && !isArrayType(getTypeOfSymbol(node.symbol))) { error(node, ts.Diagnostics.A_rest_parameter_must_be_of_an_array_type); } } function getTypePredicateParameterIndex(parameterList, parameter) { if (parameterList) { for (var i = 0; i < parameterList.length; i++) { var param = parameterList[i]; if (param.name.kind === 71 /* Identifier */ && param.name.escapedText === parameter.escapedText) { return i; } } } return -1; } function checkTypePredicate(node) { var parent = getTypePredicateParent(node); if (!parent) { // The parent must not be valid. error(node, ts.Diagnostics.A_type_predicate_is_only_allowed_in_return_type_position_for_functions_and_methods); return; } var typePredicate = getSignatureFromDeclaration(parent).typePredicate; if (!typePredicate) { return; } checkSourceElement(node.type); var parameterName = node.parameterName; if (ts.isThisTypePredicate(typePredicate)) { getTypeFromThisTypeNode(parameterName); } else { if (typePredicate.parameterIndex >= 0) { if (parent.parameters[typePredicate.parameterIndex].dotDotDotToken) { error(parameterName, ts.Diagnostics.A_type_predicate_cannot_reference_a_rest_parameter); } else { var leadingError = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.A_type_predicate_s_type_must_be_assignable_to_its_parameter_s_type); checkTypeAssignableTo(typePredicate.type, getTypeOfNode(parent.parameters[typePredicate.parameterIndex]), node.type, /*headMessage*/ undefined, leadingError); } } else if (parameterName) { var hasReportedError = false; for (var _i = 0, _a = parent.parameters; _i < _a.length; _i++) { var name = _a[_i].name; if (ts.isBindingPattern(name) && checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { hasReportedError = true; break; } } if (!hasReportedError) { error(node.parameterName, ts.Diagnostics.Cannot_find_parameter_0, typePredicate.parameterName); } } } } function getTypePredicateParent(node) { switch (node.parent.kind) { case 188 /* ArrowFunction */: case 156 /* CallSignature */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 161 /* FunctionType */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: var parent = node.parent; if (node === parent.type) { return parent; } } } function checkIfTypePredicateVariableIsDeclaredInBindingPattern(pattern, predicateVariableNode, predicateVariableName) { for (var _i = 0, _a = pattern.elements; _i < _a.length; _i++) { var element = _a[_i]; if (ts.isOmittedExpression(element)) { continue; } var name = element.name; if (name.kind === 71 /* Identifier */ && name.escapedText === predicateVariableName) { error(predicateVariableNode, ts.Diagnostics.A_type_predicate_cannot_reference_element_0_in_a_binding_pattern, predicateVariableName); return true; } else if (name.kind === 176 /* ArrayBindingPattern */ || name.kind === 175 /* ObjectBindingPattern */) { if (checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, predicateVariableNode, predicateVariableName)) { return true; } } } } function checkSignatureDeclaration(node) { // Grammar checking if (node.kind === 158 /* IndexSignature */) { checkGrammarIndexSignature(node); } else if (node.kind === 161 /* FunctionType */ || node.kind === 229 /* FunctionDeclaration */ || node.kind === 162 /* ConstructorType */ || node.kind === 156 /* CallSignature */ || node.kind === 153 /* Constructor */ || node.kind === 157 /* ConstructSignature */) { checkGrammarFunctionLikeDeclaration(node); } var functionFlags = ts.getFunctionFlags(node); if (!(functionFlags & 4 /* Invalid */)) { // Async generators prior to ESNext require the __await and __asyncGenerator helpers if ((functionFlags & 3 /* AsyncGenerator */) === 3 /* AsyncGenerator */ && languageVersion < 6 /* ESNext */) { checkExternalEmitHelpers(node, 6144 /* AsyncGeneratorIncludes */); } // Async functions prior to ES2017 require the __awaiter helper if ((functionFlags & 3 /* AsyncGenerator */) === 2 /* Async */ && languageVersion < 4 /* ES2017 */) { checkExternalEmitHelpers(node, 64 /* Awaiter */); } // Generator functions, Async functions, and Async Generator functions prior to // ES2015 require the __generator helper if ((functionFlags & 3 /* AsyncGenerator */) !== 0 /* Normal */ && languageVersion < 2 /* ES2015 */) { checkExternalEmitHelpers(node, 128 /* Generator */); } } checkTypeParameters(node.typeParameters); ts.forEach(node.parameters, checkParameter); // TODO(rbuckton): Should we start checking JSDoc types? if (node.type) { checkSourceElement(node.type); } if (produceDiagnostics) { checkCollisionWithArgumentsInGeneratedCode(node); var returnTypeNode = ts.getEffectiveReturnTypeNode(node); if (noImplicitAny && !returnTypeNode) { switch (node.kind) { case 157 /* ConstructSignature */: error(node, ts.Diagnostics.Construct_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); break; case 156 /* CallSignature */: error(node, ts.Diagnostics.Call_signature_which_lacks_return_type_annotation_implicitly_has_an_any_return_type); break; } } if (returnTypeNode) { var functionFlags_1 = ts.getFunctionFlags(node); if ((functionFlags_1 & (4 /* Invalid */ | 1 /* Generator */)) === 1 /* Generator */) { var returnType = getTypeFromTypeNode(returnTypeNode); if (returnType === voidType) { error(returnTypeNode, ts.Diagnostics.A_generator_cannot_have_a_void_type_annotation); } else { var generatorElementType = getIteratedTypeOfGenerator(returnType, (functionFlags_1 & 2 /* Async */) !== 0) || anyType; var iterableIteratorInstantiation = functionFlags_1 & 2 /* Async */ ? createAsyncIterableIteratorType(generatorElementType) // AsyncGenerator function : createIterableIteratorType(generatorElementType); // Generator function // Naively, one could check that IterableIterator is assignable to the return type annotation. // However, that would not catch the error in the following case. // // interface BadGenerator extends Iterable, Iterator { } // function* g(): BadGenerator { } // Iterable and Iterator have different types! // checkTypeAssignableTo(iterableIteratorInstantiation, returnType, returnTypeNode); } } else if ((functionFlags_1 & 3 /* AsyncGenerator */) === 2 /* Async */) { checkAsyncFunctionReturnType(node); } } if (noUnusedIdentifiers && !node.body) { checkUnusedTypeParameters(node); } } } function checkClassForDuplicateDeclarations(node) { var Declaration; (function (Declaration) { Declaration[Declaration["Getter"] = 1] = "Getter"; Declaration[Declaration["Setter"] = 2] = "Setter"; Declaration[Declaration["Method"] = 4] = "Method"; Declaration[Declaration["Property"] = 3] = "Property"; })(Declaration || (Declaration = {})); var instanceNames = ts.createUnderscoreEscapedMap(); var staticNames = ts.createUnderscoreEscapedMap(); for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 153 /* Constructor */) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var param = _c[_b]; if (ts.isParameterPropertyDeclaration(param) && !ts.isBindingPattern(param.name)) { addName(instanceNames, param.name, param.name.escapedText, 3 /* Property */); } } } else { var isStatic = ts.hasModifier(member, 32 /* Static */); var names = isStatic ? staticNames : instanceNames; var memberName = member.name && ts.getPropertyNameForPropertyNameNode(member.name); if (memberName) { switch (member.kind) { case 154 /* GetAccessor */: addName(names, member.name, memberName, 1 /* Getter */); break; case 155 /* SetAccessor */: addName(names, member.name, memberName, 2 /* Setter */); break; case 150 /* PropertyDeclaration */: addName(names, member.name, memberName, 3 /* Property */); break; case 152 /* MethodDeclaration */: addName(names, member.name, memberName, 4 /* Method */); break; } } } } function addName(names, location, name, meaning) { var prev = names.get(name); if (prev) { if (prev & 4 /* Method */) { if (meaning !== 4 /* Method */) { error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); } } else if (prev & meaning) { error(location, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(location)); } else { names.set(name, prev | meaning); } } else { names.set(name, meaning); } } } /** * Static members being set on a constructor function may conflict with built-in properties * of Function. Esp. in ECMAScript 5 there are non-configurable and non-writable * built-in properties. This check issues a transpile error when a class has a static * member with the same name as a non-writable built-in property. * * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.3 * @see http://www.ecma-international.org/ecma-262/5.1/#sec-15.3.5 * @see http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-function-constructor * @see http://www.ecma-international.org/ecma-262/6.0/#sec-function-instances */ function checkClassForStaticPropertyNameConflicts(node) { for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var memberNameNode = member.name; var isStatic = ts.hasModifier(member, 32 /* Static */); if (isStatic && memberNameNode) { var memberName = ts.getPropertyNameForPropertyNameNode(memberNameNode); switch (memberName) { case "name": case "length": case "caller": case "arguments": case "prototype": var message = ts.Diagnostics.Static_property_0_conflicts_with_built_in_property_Function_0_of_constructor_function_1; var className = getNameOfSymbolAsWritten(getSymbolOfNode(node)); error(memberNameNode, message, memberName, className); break; } } } } function checkObjectTypeForDuplicateDeclarations(node) { var names = ts.createMap(); for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 149 /* PropertySignature */) { var memberName = void 0; switch (member.name.kind) { case 9 /* StringLiteral */: case 8 /* NumericLiteral */: memberName = member.name.text; break; case 71 /* Identifier */: memberName = ts.idText(member.name); break; default: continue; } if (names.get(memberName)) { error(ts.getNameOfDeclaration(member.symbol.valueDeclaration), ts.Diagnostics.Duplicate_identifier_0, memberName); error(member.name, ts.Diagnostics.Duplicate_identifier_0, memberName); } else { names.set(memberName, true); } } } } function checkTypeForDuplicateIndexSignatures(node) { if (node.kind === 231 /* InterfaceDeclaration */) { var nodeSymbol = getSymbolOfNode(node); // in case of merging interface declaration it is possible that we'll enter this check procedure several times for every declaration // to prevent this run check only for the first declaration of a given kind if (nodeSymbol.declarations.length > 0 && nodeSymbol.declarations[0] !== node) { return; } } // TypeScript 1.0 spec (April 2014) // 3.7.4: An object type can contain at most one string index signature and one numeric index signature. // 8.5: A class declaration can have at most one string index member declaration and one numeric index member declaration var indexSymbol = getIndexSymbol(getSymbolOfNode(node)); if (indexSymbol) { var seenNumericIndexer = false; var seenStringIndexer = false; for (var _i = 0, _a = indexSymbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; var declaration = decl; if (declaration.parameters.length === 1 && declaration.parameters[0].type) { switch (declaration.parameters[0].type.kind) { case 136 /* StringKeyword */: if (!seenStringIndexer) { seenStringIndexer = true; } else { error(declaration, ts.Diagnostics.Duplicate_string_index_signature); } break; case 133 /* NumberKeyword */: if (!seenNumericIndexer) { seenNumericIndexer = true; } else { error(declaration, ts.Diagnostics.Duplicate_number_index_signature); } break; } } } } } function checkPropertyDeclaration(node) { // Grammar checking if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) checkGrammarComputedPropertyName(node.name); checkVariableLikeDeclaration(node); } function checkMethodDeclaration(node) { // Grammar checking if (!checkGrammarMethod(node)) checkGrammarComputedPropertyName(node.name); // Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration checkFunctionOrMethodDeclaration(node); // Abstract methods cannot have an implementation. // Extra checks are to avoid reporting multiple errors relating to the "abstractness" of the node. if (ts.hasModifier(node, 128 /* Abstract */) && node.body) { error(node, ts.Diagnostics.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract, ts.declarationNameToString(node.name)); } } function checkConstructorDeclaration(node) { // Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function. checkSignatureDeclaration(node); // Grammar check for checking only related to constructorDeclaration if (!checkGrammarConstructorTypeParameters(node)) checkGrammarConstructorTypeAnnotation(node); checkSourceElement(node.body); registerForUnusedIdentifiersCheck(node); var symbol = getSymbolOfNode(node); var firstDeclaration = ts.getDeclarationOfKind(symbol, node.kind); // Only type check the symbol once if (node === firstDeclaration) { checkFunctionOrConstructorSymbol(symbol); } // exit early in the case of signature - super checks are not relevant to them if (ts.nodeIsMissing(node.body)) { return; } if (!produceDiagnostics) { return; } function containsSuperCallAsComputedPropertyName(n) { var name = ts.getNameOfDeclaration(n); return name && containsSuperCall(name); } function containsSuperCall(n) { if (ts.isSuperCall(n)) { return true; } else if (ts.isFunctionLike(n)) { return false; } else if (ts.isClassLike(n)) { return ts.forEach(n.members, containsSuperCallAsComputedPropertyName); } return ts.forEachChild(n, containsSuperCall); } function isInstancePropertyWithInitializer(n) { return n.kind === 150 /* PropertyDeclaration */ && !ts.hasModifier(n, 32 /* Static */) && !!n.initializer; } // TS 1.0 spec (April 2014): 8.3.2 // Constructors of classes with no extends clause may not contain super calls, whereas // constructors of derived classes must contain at least one super call somewhere in their function body. var containingClassDecl = node.parent; if (ts.getClassExtendsHeritageClauseElement(containingClassDecl)) { captureLexicalThis(node.parent, containingClassDecl); var classExtendsNull = classDeclarationExtendsNull(containingClassDecl); var superCall = getSuperCallInConstructor(node); if (superCall) { if (classExtendsNull) { error(superCall, ts.Diagnostics.A_constructor_cannot_contain_a_super_call_when_its_class_extends_null); } // The first statement in the body of a constructor (excluding prologue directives) must be a super call // if both of the following are true: // - The containing class is a derived class. // - The constructor declares parameter properties // or the containing class declares instance member variables with initializers. var superCallShouldBeFirst = ts.some(node.parent.members, isInstancePropertyWithInitializer) || ts.some(node.parameters, function (p) { return ts.hasModifier(p, 92 /* ParameterPropertyModifier */); }); // Skip past any prologue directives to find the first statement // to ensure that it was a super call. if (superCallShouldBeFirst) { var statements = node.body.statements; var superCallStatement = void 0; for (var _i = 0, statements_2 = statements; _i < statements_2.length; _i++) { var statement = statements_2[_i]; if (statement.kind === 211 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) { superCallStatement = statement; break; } if (!ts.isPrologueDirective(statement)) { break; } } if (!superCallStatement) { error(node, ts.Diagnostics.A_super_call_must_be_the_first_statement_in_the_constructor_when_a_class_contains_initialized_properties_or_has_parameter_properties); } } } else if (!classExtendsNull) { error(node, ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call); } } } function checkAccessorDeclaration(node) { if (produceDiagnostics) { // Grammar checking accessors if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node)) checkGrammarComputedPropertyName(node.name); checkDecorators(node); checkSignatureDeclaration(node); if (node.kind === 154 /* GetAccessor */) { if (!(node.flags & 2097152 /* Ambient */) && ts.nodeIsPresent(node.body) && (node.flags & 128 /* HasImplicitReturn */)) { if (!(node.flags & 256 /* HasExplicitReturn */)) { error(node.name, ts.Diagnostics.A_get_accessor_must_return_a_value); } } } // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(node.name); } if (!hasNonBindableDynamicName(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 === 154 /* GetAccessor */ ? 155 /* SetAccessor */ : 154 /* GetAccessor */; var otherAccessor = ts.getDeclarationOfKind(getSymbolOfNode(node), otherKind); if (otherAccessor) { var nodeFlags = ts.getModifierFlags(node); var otherFlags = ts.getModifierFlags(otherAccessor); if ((nodeFlags & 28 /* AccessibilityModifier */) !== (otherFlags & 28 /* AccessibilityModifier */)) { error(node.name, ts.Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility); } if ((nodeFlags & 128 /* Abstract */) !== (otherFlags & 128 /* Abstract */)) { error(node.name, ts.Diagnostics.Accessors_must_both_be_abstract_or_non_abstract); } // TypeScript 1.0 spec (April 2014): 4.5 // If both accessors include type annotations, the specified types must be identical. checkAccessorDeclarationTypesIdentical(node, otherAccessor, getAnnotatedAccessorType, ts.Diagnostics.get_and_set_accessor_must_have_the_same_type); checkAccessorDeclarationTypesIdentical(node, otherAccessor, getThisTypeOfDeclaration, ts.Diagnostics.get_and_set_accessor_must_have_the_same_this_type); } } var returnType = getTypeOfAccessors(getSymbolOfNode(node)); if (node.kind === 154 /* GetAccessor */) { checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnType); } } checkSourceElement(node.body); registerForUnusedIdentifiersCheck(node); } function checkAccessorDeclarationTypesIdentical(first, second, getAnnotatedType, message) { var firstType = getAnnotatedType(first); var secondType = getAnnotatedType(second); if (firstType && secondType && !isTypeIdenticalTo(firstType, secondType)) { error(first, message); } } function checkMissingDeclaration(node) { checkDecorators(node); } function checkTypeArgumentConstraints(typeParameters, typeArgumentNodes) { var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); var typeArguments; var mapper; var result = true; for (var i = 0; i < typeParameters.length; i++) { var constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { if (!typeArguments) { typeArguments = fillMissingTypeArguments(ts.map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount, ts.isInJavaScriptFile(typeArgumentNodes[i])); mapper = createTypeMapper(typeParameters, typeArguments); } var typeArgument = typeArguments[i]; result = result && checkTypeAssignableTo(typeArgument, instantiateType(constraint, mapper), typeArgumentNodes[i], ts.Diagnostics.Type_0_does_not_satisfy_the_constraint_1); } } return result; } function checkTypeReferenceNode(node) { checkGrammarTypeArguments(node, node.typeArguments); if (node.kind === 160 /* TypeReference */ && node.typeName.jsdocDotPos !== undefined && !ts.isInJavaScriptFile(node) && !ts.isInJSDoc(node)) { grammarErrorAtPos(node, node.typeName.jsdocDotPos, 1, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); } var type = getTypeFromTypeReference(node); if (type !== unknownType) { if (node.typeArguments) { // Do type argument local checks only if referenced type is successfully resolved ts.forEach(node.typeArguments, checkSourceElement); if (produceDiagnostics) { var symbol = getNodeLinks(node).resolvedSymbol; if (!symbol) { // There is no resolved symbol cached if the type resolved to a builtin // via JSDoc type reference resolution (eg, Boolean became boolean), none // of which are generic when they have no associated symbol // (additionally, JSDoc's index signature syntax, Object actually uses generic syntax without being generic) if (!ts.isJSDocIndexSignature(node)) { error(node, ts.Diagnostics.Type_0_is_not_generic, typeToString(type)); } return; } var typeParameters = symbol.flags & 524288 /* TypeAlias */ && getSymbolLinks(symbol).typeParameters; if (!typeParameters && ts.getObjectFlags(type) & 4 /* Reference */) { typeParameters = type.target.localTypeParameters; } checkTypeArgumentConstraints(typeParameters, node.typeArguments); } } if (type.flags & 16 /* Enum */ && getNodeLinks(node).resolvedSymbol.flags & 8 /* EnumMember */) { error(node, ts.Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type)); } } } function checkTypeQuery(node) { getTypeFromTypeQueryNode(node); } function checkTypeLiteral(node) { ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { var type = getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node); checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); checkObjectTypeForDuplicateDeclarations(node); } } function checkArrayType(node) { checkSourceElement(node.elementType); } function checkTupleType(node) { // Grammar checking var hasErrorFromDisallowedTrailingComma = checkGrammarForDisallowedTrailingComma(node.elementTypes); if (!hasErrorFromDisallowedTrailingComma && node.elementTypes.length === 0) { grammarErrorOnNode(node, ts.Diagnostics.A_tuple_type_element_list_cannot_be_empty); } ts.forEach(node.elementTypes, checkSourceElement); } function checkUnionOrIntersectionType(node) { ts.forEach(node.types, checkSourceElement); } function checkIndexedAccessIndexType(type, accessNode) { if (!(type.flags & 1048576 /* IndexedAccess */)) { return type; } // Check if the index type is assignable to 'keyof T' for the object type. var objectType = type.objectType; var indexType = type.indexType; if (isTypeAssignableTo(indexType, getIndexType(objectType))) { if (accessNode.kind === 181 /* ElementAccessExpression */ && ts.isAssignmentTarget(accessNode) && ts.getObjectFlags(objectType) & 32 /* Mapped */ && objectType.declaration.readonlyToken) { error(accessNode, ts.Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } return type; } // Check if we're indexing with a numeric type and if either object or index types // is a generic type with a constraint that has a numeric index signature. if (getIndexInfoOfType(getApparentType(objectType), 1 /* Number */) && isTypeAssignableToKind(indexType, 84 /* NumberLike */)) { return type; } error(accessNode, ts.Diagnostics.Type_0_cannot_be_used_to_index_type_1, typeToString(indexType), typeToString(objectType)); return type; } function checkIndexedAccessType(node) { checkSourceElement(node.objectType); checkSourceElement(node.indexType); checkIndexedAccessIndexType(getTypeFromIndexedAccessTypeNode(node), node); } function checkMappedType(node) { checkSourceElement(node.typeParameter); checkSourceElement(node.type); var type = getTypeFromMappedTypeNode(node); var constraintType = getConstraintTypeFromMappedType(type); checkTypeAssignableTo(constraintType, stringType, node.typeParameter.constraint); } function checkTypeOperator(node) { checkGrammarTypeOperatorNode(node); checkSourceElement(node.type); } function isPrivateWithinAmbient(node) { return ts.hasModifier(node, 8 /* Private */) && !!(node.flags & 2097152 /* Ambient */); } function getEffectiveDeclarationFlags(n, flagsToCheck) { var flags = ts.getCombinedModifierFlags(n); // children of classes (even ambient classes) should not be marked as ambient or export // because those flags have no useful semantics there. if (n.parent.kind !== 231 /* InterfaceDeclaration */ && n.parent.kind !== 230 /* ClassDeclaration */ && n.parent.kind !== 200 /* ClassExpression */ && n.flags & 2097152 /* Ambient */) { if (!(flags & 2 /* Ambient */)) { // It is nested in an ambient context, which means it is automatically exported flags |= 1 /* Export */; } flags |= 2 /* Ambient */; } return flags & flagsToCheck; } function checkFunctionOrConstructorSymbol(symbol) { if (!produceDiagnostics) { return; } function getCanonicalOverload(overloads, implementation) { // Consider the canonical set of flags to be the flags of the bodyDeclaration or the first declaration // Error on all deviations from this canonical set of flags // The caveat is that if some overloads are defined in lib.d.ts, we don't want to // report the errors on those. To achieve this, we will say that the implementation is // the canonical signature only if it is in the same container as the first overload var implementationSharesContainerWithFirstOverload = implementation !== undefined && implementation.parent === overloads[0].parent; return implementationSharesContainerWithFirstOverload ? implementation : overloads[0]; } function checkFlagAgreementBetweenOverloads(overloads, implementation, flagsToCheck, someOverloadFlags, allOverloadFlags) { // Error if some overloads have a flag that is not shared by all overloads. To find the // deviations, we XOR someOverloadFlags with allOverloadFlags var someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags; if (someButNotAllOverloadFlags !== 0) { var canonicalFlags_1 = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck); ts.forEach(overloads, function (o) { var deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags_1; if (deviation & 1 /* Export */) { error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_exported_or_non_exported); } else if (deviation & 2 /* Ambient */) { error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_ambient_or_non_ambient); } else if (deviation & (8 /* Private */ | 16 /* Protected */)) { error(ts.getNameOfDeclaration(o) || o, ts.Diagnostics.Overload_signatures_must_all_be_public_private_or_protected); } else if (deviation & 128 /* Abstract */) { error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_abstract_or_non_abstract); } }); } } function checkQuestionTokenAgreementBetweenOverloads(overloads, implementation, someHaveQuestionToken, allHaveQuestionToken) { if (someHaveQuestionToken !== allHaveQuestionToken) { var canonicalHasQuestionToken_1 = ts.hasQuestionToken(getCanonicalOverload(overloads, implementation)); ts.forEach(overloads, function (o) { var deviation = ts.hasQuestionToken(o) !== canonicalHasQuestionToken_1; if (deviation) { error(ts.getNameOfDeclaration(o), ts.Diagnostics.Overload_signatures_must_all_be_optional_or_required); } }); } } var flagsToCheck = 1 /* Export */ | 2 /* Ambient */ | 8 /* Private */ | 16 /* Protected */ | 128 /* Abstract */; var someNodeFlags = 0 /* None */; var allNodeFlags = flagsToCheck; var someHaveQuestionToken = false; var allHaveQuestionToken = true; var hasOverloads = false; var bodyDeclaration; var lastSeenNonAmbientDeclaration; var previousDeclaration; var declarations = symbol.declarations; var isConstructor = (symbol.flags & 16384 /* Constructor */) !== 0; function reportImplementationExpectedError(node) { if (node.name && ts.nodeIsMissing(node.name)) { return; } var seen = false; var subsequentNode = ts.forEachChild(node.parent, function (c) { if (seen) { return c; } else { seen = c === node; } }); // We may be here because of some extra nodes between overloads that could not be parsed into a valid node. // In this case the subsequent node is not really consecutive (.pos !== node.end), and we must ignore it here. if (subsequentNode && subsequentNode.pos === node.end) { if (subsequentNode.kind === node.kind) { var errorNode_1 = subsequentNode.name || subsequentNode; // TODO: GH#17345: These are methods, so handle computed name case. (`Always allowing computed property names is *not* the correct behavior!) var subsequentName = subsequentNode.name; if (node.name && subsequentName && (ts.isComputedPropertyName(node.name) && ts.isComputedPropertyName(subsequentName) || !ts.isComputedPropertyName(node.name) && !ts.isComputedPropertyName(subsequentName) && ts.getEscapedTextOfIdentifierOrLiteral(node.name) === ts.getEscapedTextOfIdentifierOrLiteral(subsequentName))) { var reportError = (node.kind === 152 /* MethodDeclaration */ || node.kind === 151 /* MethodSignature */) && ts.hasModifier(node, 32 /* Static */) !== ts.hasModifier(subsequentNode, 32 /* Static */); // we can get here in two cases // 1. mixed static and instance class members // 2. something with the same name was defined before the set of overloads that prevents them from merging // here we'll report error only for the first case since for second we should already report error in binder if (reportError) { var diagnostic = ts.hasModifier(node, 32 /* Static */) ? ts.Diagnostics.Function_overload_must_be_static : ts.Diagnostics.Function_overload_must_not_be_static; error(errorNode_1, diagnostic); } return; } else if (ts.nodeIsPresent(subsequentNode.body)) { error(errorNode_1, ts.Diagnostics.Function_implementation_name_must_be_0, ts.declarationNameToString(node.name)); return; } } } var errorNode = node.name || node; if (isConstructor) { error(errorNode, ts.Diagnostics.Constructor_implementation_is_missing); } else { // Report different errors regarding non-consecutive blocks of declarations depending on whether // the node in question is abstract. if (ts.hasModifier(node, 128 /* Abstract */)) { error(errorNode, ts.Diagnostics.All_declarations_of_an_abstract_method_must_be_consecutive); } else { error(errorNode, ts.Diagnostics.Function_implementation_is_missing_or_not_immediately_following_the_declaration); } } } var duplicateFunctionDeclaration = false; var multipleConstructorImplementation = false; for (var _i = 0, declarations_4 = declarations; _i < declarations_4.length; _i++) { var current = declarations_4[_i]; var node = current; var inAmbientContext = node.flags & 2097152 /* Ambient */; var inAmbientContextOrInterface = node.parent.kind === 231 /* InterfaceDeclaration */ || node.parent.kind === 164 /* 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 === 229 /* FunctionDeclaration */ || node.kind === 152 /* MethodDeclaration */ || node.kind === 151 /* MethodSignature */ || node.kind === 153 /* Constructor */) { var currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck); someNodeFlags |= currentNodeFlags; allNodeFlags &= currentNodeFlags; someHaveQuestionToken = someHaveQuestionToken || ts.hasQuestionToken(node); allHaveQuestionToken = allHaveQuestionToken && ts.hasQuestionToken(node); if (ts.nodeIsPresent(node.body) && bodyDeclaration) { if (isConstructor) { multipleConstructorImplementation = true; } else { duplicateFunctionDeclaration = true; } } else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) { reportImplementationExpectedError(previousDeclaration); } if (ts.nodeIsPresent(node.body)) { if (!bodyDeclaration) { bodyDeclaration = node; } } else { hasOverloads = true; } previousDeclaration = node; if (!inAmbientContextOrInterface) { lastSeenNonAmbientDeclaration = node; } } } if (multipleConstructorImplementation) { ts.forEach(declarations, function (declaration) { error(declaration, ts.Diagnostics.Multiple_constructor_implementations_are_not_allowed); }); } if (duplicateFunctionDeclaration) { ts.forEach(declarations, function (declaration) { error(ts.getNameOfDeclaration(declaration), ts.Diagnostics.Duplicate_function_implementation); }); } // Abstract methods can't have an implementation -- in particular, they don't need one. if (lastSeenNonAmbientDeclaration && !lastSeenNonAmbientDeclaration.body && !ts.hasModifier(lastSeenNonAmbientDeclaration, 128 /* Abstract */) && !lastSeenNonAmbientDeclaration.questionToken) { reportImplementationExpectedError(lastSeenNonAmbientDeclaration); } if (hasOverloads) { checkFlagAgreementBetweenOverloads(declarations, bodyDeclaration, flagsToCheck, someNodeFlags, allNodeFlags); checkQuestionTokenAgreementBetweenOverloads(declarations, bodyDeclaration, someHaveQuestionToken, allHaveQuestionToken); if (bodyDeclaration) { var signatures = getSignaturesOfSymbol(symbol); var bodySignature = getSignatureFromDeclaration(bodyDeclaration); for (var _a = 0, signatures_7 = signatures; _a < signatures_7.length; _a++) { var signature = signatures_7[_a]; if (!isImplementationCompatibleWithOverload(bodySignature, signature)) { error(signature.declaration, ts.Diagnostics.Overload_signature_is_not_compatible_with_function_implementation); break; } } } } } function checkExportsOnMergedDeclarations(node) { if (!produceDiagnostics) { return; } // if localSymbol is defined on node then node itself is exported - check is required var symbol = node.localSymbol; if (!symbol) { // local symbol is undefined => this declaration is non-exported. // however symbol might contain other declarations that are exported symbol = getSymbolOfNode(node); if (!symbol.exportSymbol) { // this is a pure local symbol (all declarations are non-exported) - no need to check anything return; } } // run the check only for the first declaration in the list if (ts.getDeclarationOfKind(symbol, node.kind) !== node) { return; } var exportedDeclarationSpaces = 0 /* None */; var nonExportedDeclarationSpaces = 0 /* None */; var defaultExportedDeclarationSpaces = 0 /* None */; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var d = _a[_i]; var declarationSpaces = getDeclarationSpaces(d); var effectiveDeclarationFlags = getEffectiveDeclarationFlags(d, 1 /* Export */ | 512 /* Default */); if (effectiveDeclarationFlags & 1 /* Export */) { if (effectiveDeclarationFlags & 512 /* Default */) { defaultExportedDeclarationSpaces |= declarationSpaces; } else { exportedDeclarationSpaces |= declarationSpaces; } } else { nonExportedDeclarationSpaces |= declarationSpaces; } } // Spaces for anything not declared a 'default export'. var nonDefaultExportedDeclarationSpaces = exportedDeclarationSpaces | nonExportedDeclarationSpaces; var commonDeclarationSpacesForExportsAndLocals = exportedDeclarationSpaces & nonExportedDeclarationSpaces; var commonDeclarationSpacesForDefaultAndNonDefault = defaultExportedDeclarationSpaces & nonDefaultExportedDeclarationSpaces; if (commonDeclarationSpacesForExportsAndLocals || commonDeclarationSpacesForDefaultAndNonDefault) { // declaration spaces for exported and non-exported declarations intersect for (var _b = 0, _c = symbol.declarations; _b < _c.length; _b++) { var d = _c[_b]; var declarationSpaces = getDeclarationSpaces(d); var name = ts.getNameOfDeclaration(d); // Only error on the declarations that contributed to the intersecting spaces. if (declarationSpaces & commonDeclarationSpacesForDefaultAndNonDefault) { error(name, ts.Diagnostics.Merged_declaration_0_cannot_include_a_default_export_declaration_Consider_adding_a_separate_export_default_0_declaration_instead, ts.declarationNameToString(name)); } else if (declarationSpaces & commonDeclarationSpacesForExportsAndLocals) { error(name, ts.Diagnostics.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local, ts.declarationNameToString(name)); } } } var DeclarationSpaces; (function (DeclarationSpaces) { DeclarationSpaces[DeclarationSpaces["None"] = 0] = "None"; DeclarationSpaces[DeclarationSpaces["ExportValue"] = 1] = "ExportValue"; DeclarationSpaces[DeclarationSpaces["ExportType"] = 2] = "ExportType"; DeclarationSpaces[DeclarationSpaces["ExportNamespace"] = 4] = "ExportNamespace"; })(DeclarationSpaces || (DeclarationSpaces = {})); function getDeclarationSpaces(d) { switch (d.kind) { case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: // A jsdoc typedef is, by definition, a type alias case 288 /* JSDocTypedefTag */: return 2 /* ExportType */; case 234 /* ModuleDeclaration */: return ts.isAmbientModule(d) || ts.getModuleInstanceState(d) !== 0 /* NonInstantiated */ ? 4 /* ExportNamespace */ | 1 /* ExportValue */ : 4 /* ExportNamespace */; case 230 /* ClassDeclaration */: case 233 /* EnumDeclaration */: return 2 /* ExportType */ | 1 /* ExportValue */; // The below options all declare an Alias, which is allowed to merge with other values within the importing module case 238 /* ImportEqualsDeclaration */: case 241 /* NamespaceImport */: case 240 /* ImportClause */: var result_2 = 0 /* None */; var target = resolveAlias(getSymbolOfNode(d)); ts.forEach(target.declarations, function (d) { result_2 |= getDeclarationSpaces(d); }); return result_2; case 227 /* VariableDeclaration */: case 177 /* BindingElement */: case 229 /* FunctionDeclaration */: case 243 /* ImportSpecifier */:// https://github.com/Microsoft/TypeScript/pull/7591 return 1 /* ExportValue */; default: ts.Debug.fail(ts.SyntaxKind[d.kind]); } } } function getAwaitedTypeOfPromise(type, errorNode, diagnosticMessage) { var promisedType = getPromisedTypeOfPromise(type, errorNode); return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage); } /** * Gets the "promised type" of a promise. * @param type The type of the promise. * @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback. */ function getPromisedTypeOfPromise(promise, errorNode) { // // { // promise // then( // thenFunction // onfulfilled: ( // onfulfilledParameterType // value: T // valueParameterType // ) => any // ): any; // } // if (isTypeAny(promise)) { return undefined; } var typeAsPromise = promise; if (typeAsPromise.promisedTypeOfPromise) { return typeAsPromise.promisedTypeOfPromise; } if (isReferenceToType(promise, getGlobalPromiseType(/*reportErrors*/ false))) { return typeAsPromise.promisedTypeOfPromise = promise.typeArguments[0]; } var thenFunction = getTypeOfPropertyOfType(promise, "then"); if (isTypeAny(thenFunction)) { return undefined; } var thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, 0 /* Call */) : ts.emptyArray; if (thenSignatures.length === 0) { if (errorNode) { error(errorNode, ts.Diagnostics.A_promise_must_have_a_then_method); } return undefined; } var onfulfilledParameterType = getTypeWithFacts(getUnionType(ts.map(thenSignatures, getTypeOfFirstParameterOfSignature)), 524288 /* NEUndefinedOrNull */); if (isTypeAny(onfulfilledParameterType)) { return undefined; } var onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, 0 /* Call */); if (onfulfilledParameterSignatures.length === 0) { if (errorNode) { error(errorNode, ts.Diagnostics.The_first_parameter_of_the_then_method_of_a_promise_must_be_a_callback); } return undefined; } return typeAsPromise.promisedTypeOfPromise = getUnionType(ts.map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature), /*subtypeReduction*/ true); } /** * Gets the "awaited type" of a type. * @param type The type to await. * @remarks The "awaited type" of an expression is its "promised type" if the expression is a * Promise-like type; otherwise, it is the type of the expression. This is used to reflect * The runtime behavior of the `await` keyword. */ function checkAwaitedType(type, errorNode, diagnosticMessage) { return getAwaitedType(type, errorNode, diagnosticMessage) || unknownType; } function getAwaitedType(type, errorNode, diagnosticMessage) { var typeAsAwaitable = type; if (typeAsAwaitable.awaitedTypeOfType) { return typeAsAwaitable.awaitedTypeOfType; } if (isTypeAny(type)) { return typeAsAwaitable.awaitedTypeOfType = type; } if (type.flags & 131072 /* Union */) { var types = void 0; for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var constituentType = _a[_i]; types = ts.append(types, getAwaitedType(constituentType, errorNode, diagnosticMessage)); } if (!types) { return undefined; } return typeAsAwaitable.awaitedTypeOfType = getUnionType(types); } var promisedType = getPromisedTypeOfPromise(type); if (promisedType) { if (type.id === promisedType.id || ts.indexOf(awaitedTypeStack, promisedType.id) >= 0) { // Verify that we don't have a bad actor in the form of a promise whose // promised type is the same as the promise type, or a mutually recursive // promise. If so, we return undefined as we cannot guess the shape. If this // were the actual case in the JavaScript, this Promise would never resolve. // // An example of a bad actor with a singly-recursive promise type might // be: // // interface BadPromise { // then( // onfulfilled: (value: BadPromise) => any, // onrejected: (error: any) => any): BadPromise; // } // The above interface will pass the PromiseLike check, and return a // promised type of `BadPromise`. Since this is a self reference, we // don't want to keep recursing ad infinitum. // // An example of a bad actor in the form of a mutually-recursive // promise type might be: // // interface BadPromiseA { // then( // onfulfilled: (value: BadPromiseB) => any, // onrejected: (error: any) => any): BadPromiseB; // } // // interface BadPromiseB { // then( // onfulfilled: (value: BadPromiseA) => any, // onrejected: (error: any) => any): BadPromiseA; // } // if (errorNode) { error(errorNode, ts.Diagnostics.Type_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method); } return undefined; } // Keep track of the type we're about to unwrap to avoid bad recursive promise types. // See the comments above for more information. awaitedTypeStack.push(type.id); var awaitedType = getAwaitedType(promisedType, errorNode, diagnosticMessage); awaitedTypeStack.pop(); if (!awaitedType) { return undefined; } return typeAsAwaitable.awaitedTypeOfType = awaitedType; } // The type was not a promise, so it could not be unwrapped any further. // As long as the type does not have a callable "then" property, it is // safe to return the type; otherwise, an error will be reported in // the call to getNonThenableType and we will return undefined. // // An example of a non-promise "thenable" might be: // // await { then(): void {} } // // The "thenable" does not match the minimal definition for a promise. When // a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise // will never settle. We treat this as an error to help flag an early indicator // of a runtime problem. If the user wants to return this value from an async // function, they would need to wrap it in some other value. If they want it to // be treated as a promise, they can cast to . var thenFunction = getTypeOfPropertyOfType(type, "then"); if (thenFunction && getSignaturesOfType(thenFunction, 0 /* Call */).length > 0) { if (errorNode) { ts.Debug.assert(!!diagnosticMessage); error(errorNode, diagnosticMessage); } return undefined; } return typeAsAwaitable.awaitedTypeOfType = type; } /** * Checks the return type of an async function to ensure it is a compatible * Promise implementation. * * This checks that an async function has a valid Promise-compatible return type, * and returns the *awaited type* of the promise. An async function has a valid * Promise-compatible return type if the resolved value of the return type has a * construct signature that takes in an `initializer` function that in turn supplies * a `resolve` function as one of its arguments and results in an object with a * callable `then` signature. * * @param node The signature to check */ function checkAsyncFunctionReturnType(node) { // As part of our emit for an async function, we will need to emit the entity name of // the return type annotation as an expression. To meet the necessary runtime semantics // for __awaiter, we must also check that the type of the declaration (e.g. the static // side or "constructor" of the promise type) is compatible `PromiseConstructorLike`. // // An example might be (from lib.es6.d.ts): // // interface Promise { ... } // interface PromiseConstructor { // new (...): Promise; // } // declare var Promise: PromiseConstructor; // // When an async function declares a return type annotation of `Promise`, 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 { // constructor(...); // then(...): Promise; // } // var returnTypeNode = ts.getEffectiveReturnTypeNode(node); var returnType = getTypeFromTypeNode(returnTypeNode); if (languageVersion >= 2 /* ES2015 */) { if (returnType === unknownType) { return unknownType; } var globalPromiseType = getGlobalPromiseType(/*reportErrors*/ true); if (globalPromiseType !== emptyGenericType && !isReferenceToType(returnType, globalPromiseType)) { // The promise type was not a valid type reference to the global promise type, so we // report an error and return the unknown type. error(returnTypeNode, ts.Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type); return unknownType; } } else { // Always mark the type node as referenced if it points to a value markTypeNodeAsReferenced(returnTypeNode); if (returnType === unknownType) { return unknownType; } var promiseConstructorName = ts.getEntityNameFromTypeNode(returnTypeNode); if (promiseConstructorName === undefined) { error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, typeToString(returnType)); return unknownType; } var promiseConstructorSymbol = resolveEntityName(promiseConstructorName, 107455 /* Value */, /*ignoreErrors*/ true); var promiseConstructorType = promiseConstructorSymbol ? getTypeOfSymbol(promiseConstructorSymbol) : unknownType; if (promiseConstructorType === unknownType) { if (promiseConstructorName.kind === 71 /* Identifier */ && promiseConstructorName.escapedText === "Promise" && getTargetType(returnType) === getGlobalPromiseType(/*reportErrors*/ false)) { error(returnTypeNode, ts.Diagnostics.An_async_function_or_method_in_ES5_SlashES3_requires_the_Promise_constructor_Make_sure_you_have_a_declaration_for_the_Promise_constructor_or_include_ES2015_in_your_lib_option); } else { error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName)); } return unknownType; } var globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(/*reportErrors*/ true); if (globalPromiseConstructorLikeType === emptyObjectType) { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify // compatibility with __awaiter. error(returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value, ts.entityNameToString(promiseConstructorName)); return unknownType; } if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, returnTypeNode, ts.Diagnostics.Type_0_is_not_a_valid_async_function_return_type_in_ES5_SlashES3_because_it_does_not_refer_to_a_Promise_compatible_constructor_value)) { return unknownType; } // Verify there is no local declaration that could collide with the promise constructor. var rootName = promiseConstructorName && getFirstIdentifier(promiseConstructorName); var collidingSymbol = getSymbol(node.locals, rootName.escapedText, 107455 /* Value */); if (collidingSymbol) { error(collidingSymbol.valueDeclaration, ts.Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, ts.idText(rootName), ts.entityNameToString(promiseConstructorName)); return unknownType; } } // Get and return the awaited type of the return type. return checkAwaitedType(returnType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); } /** Check a decorator */ function checkDecorator(node) { var signature = getResolvedSignature(node); var returnType = getReturnTypeOfSignature(signature); if (returnType.flags & 1 /* Any */) { return; } var expectedReturnType; var headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); var errorInfo; switch (node.parent.kind) { case 230 /* ClassDeclaration */: var classSymbol = getSymbolOfNode(node.parent); var classConstructorType = getTypeOfSymbol(classSymbol); expectedReturnType = getUnionType([classConstructorType, voidType]); break; case 147 /* 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 150 /* 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 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: var methodType = getTypeOfNode(node.parent); var descriptorType = createTypedPropertyDescriptorType(methodType); expectedReturnType = getUnionType([descriptorType, voidType]); break; } checkTypeAssignableTo(returnType, expectedReturnType, node, headMessage, errorInfo); } /** * If a TypeNode can be resolved to a value symbol imported from an external module, it is * marked as referenced to prevent import elision. */ function markTypeNodeAsReferenced(node) { markEntityNameOrEntityExpressionAsReference(node && ts.getEntityNameFromTypeNode(node)); } function markEntityNameOrEntityExpressionAsReference(typeName) { if (!typeName) return; var rootName = getFirstIdentifier(typeName); var meaning = (typeName.kind === 71 /* Identifier */ ? 793064 /* Type */ : 1920 /* Namespace */) | 2097152 /* Alias */; var rootSymbol = resolveName(rootName, rootName.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isRefernce*/ true); if (rootSymbol && rootSymbol.flags & 2097152 /* Alias */ && symbolIsValue(rootSymbol) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(rootSymbol))) { markAliasSymbolAsReferenced(rootSymbol); } } /** * This function marks the type used for metadata decorator as referenced if it is import * from external module. * This is different from markTypeNodeAsReferenced because it tries to simplify type nodes in * union and intersection type * @param node */ function markDecoratorMedataDataTypeNodeAsReferenced(node) { var entityName = getEntityNameForDecoratorMetadata(node); if (entityName && ts.isEntityName(entityName)) { markEntityNameOrEntityExpressionAsReference(entityName); } } function getEntityNameForDecoratorMetadata(node) { if (node) { switch (node.kind) { case 168 /* IntersectionType */: case 167 /* UnionType */: var commonEntityName = void 0; for (var _i = 0, _a = node.types; _i < _a.length; _i++) { var typeNode = _a[_i]; while (typeNode.kind === 169 /* ParenthesizedType */) { typeNode = typeNode.type; // Skip parens if need be } if (typeNode.kind === 130 /* NeverKeyword */) { continue; // Always elide `never` from the union/intersection if possible } if (!strictNullChecks && (typeNode.kind === 95 /* NullKeyword */ || typeNode.kind === 139 /* UndefinedKeyword */)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } var individualEntityName = getEntityNameForDecoratorMetadata(typeNode); if (!individualEntityName) { // Individual is something like string number // So it would be serialized to either that type or object // Safe to return here return undefined; } if (commonEntityName) { // Note this is in sync with the transformation that happens for type node. // Keep this in sync with serializeUnionOrIntersectionType // Verify if they refer to same entity and is identifier // return undefined if they dont match because we would emit object if (!ts.isIdentifier(commonEntityName) || !ts.isIdentifier(individualEntityName) || commonEntityName.escapedText !== individualEntityName.escapedText) { return undefined; } } else { commonEntityName = individualEntityName; } } return commonEntityName; case 169 /* ParenthesizedType */: return getEntityNameForDecoratorMetadata(node.type); case 160 /* TypeReference */: return node.typeName; } } } function getParameterTypeNodeForDecoratorCheck(node) { var typeNode = ts.getEffectiveTypeAnnotationNode(node); return ts.isRestParameter(node) ? ts.getRestParameterElementType(typeNode) : typeNode; } /** Check the decorators of a node */ function checkDecorators(node) { if (!node.decorators) { return; } // skip this check for nodes that cannot have decorators. These should have already had an error reported by // checkGrammarDecorators. if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) { return; } if (!compilerOptions.experimentalDecorators) { error(node, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning); } var firstDecorator = node.decorators[0]; checkExternalEmitHelpers(firstDecorator, 8 /* Decorate */); if (node.kind === 147 /* Parameter */) { checkExternalEmitHelpers(firstDecorator, 32 /* Param */); } if (compilerOptions.emitDecoratorMetadata) { checkExternalEmitHelpers(firstDecorator, 16 /* Metadata */); // we only need to perform these checks if we are emitting serialized type metadata for the target of a decorator. switch (node.kind) { case 230 /* ClassDeclaration */: var constructor = ts.getFirstConstructorWithBody(node); if (constructor) { for (var _i = 0, _a = constructor.parameters; _i < _a.length; _i++) { var parameter = _a[_i]; markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } } break; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: for (var _b = 0, _c = node.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveReturnTypeNode(node)); break; case 150 /* PropertyDeclaration */: markDecoratorMedataDataTypeNodeAsReferenced(ts.getEffectiveTypeAnnotationNode(node)); break; case 147 /* Parameter */: markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(node)); var containingSignature = node.parent; for (var _d = 0, _e = containingSignature.parameters; _d < _e.length; _d++) { var parameter = _e[_d]; markDecoratorMedataDataTypeNodeAsReferenced(getParameterTypeNodeForDecoratorCheck(parameter)); } break; } } ts.forEach(node.decorators, checkDecorator); } function checkFunctionDeclaration(node) { if (produceDiagnostics) { checkFunctionOrMethodDeclaration(node); checkGrammarForGenerator(node); checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } function checkJSDocTypedefTag(node) { if (!node.typeExpression) { // If the node had `@property` tags, `typeExpression` would have been set to the first property tag. error(node.name, ts.Diagnostics.JSDoc_typedef_tag_should_either_have_a_type_annotation_or_be_followed_by_property_or_member_tags); } } function checkJSDocParameterTag(node) { checkSourceElement(node.typeExpression); if (!ts.getParameterSymbolFromJSDoc(node)) { error(node.name, ts.Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name, ts.idText(node.name.kind === 144 /* QualifiedName */ ? node.name.right : node.name)); } } function checkJSDocAugmentsTag(node) { var classLike = ts.getJSDocHost(node); if (!ts.isClassDeclaration(classLike) && !ts.isClassExpression(classLike)) { error(classLike, ts.Diagnostics.JSDoc_0_is_not_attached_to_a_class, ts.idText(node.tagName)); return; } var augmentsTags = ts.getAllJSDocTagsOfKind(classLike, 282 /* JSDocAugmentsTag */); ts.Debug.assert(augmentsTags.length > 0); if (augmentsTags.length > 1) { error(augmentsTags[1], ts.Diagnostics.Class_declarations_cannot_have_more_than_one_augments_or_extends_tag); } var name = getIdentifierFromEntityNameExpression(node.class.expression); var extend = ts.getClassExtendsHeritageClauseElement(classLike); if (extend) { var className = getIdentifierFromEntityNameExpression(extend.expression); if (className && name.escapedText !== className.escapedText) { error(name, ts.Diagnostics.JSDoc_0_1_does_not_match_the_extends_2_clause, ts.idText(node.tagName), ts.idText(name), ts.idText(className)); } } } function getIdentifierFromEntityNameExpression(node) { switch (node.kind) { case 71 /* Identifier */: return node; case 180 /* PropertyAccessExpression */: return node.name; default: return undefined; } } function checkFunctionOrMethodDeclaration(node) { checkDecorators(node); checkSignatureDeclaration(node); var functionFlags = ts.getFunctionFlags(node); // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name && node.name.kind === 145 /* ComputedPropertyName */) { // This check will account for methods in class/interface declarations, // as well as accessors in classes/object literals checkComputedPropertyName(node.name); } if (!hasNonBindableDynamicName(node)) { // first we want to check the local symbol that contain this declaration // - if node.localSymbol !== undefined - this is current declaration is exported and localSymbol points to the local symbol // - if node.localSymbol === undefined - this node is non-exported so we can just pick the result of getSymbolOfNode var symbol = getSymbolOfNode(node); var localSymbol = node.localSymbol || symbol; // Since the javascript won't do semantic analysis like typescript, // if the javascript file comes before the typescript file and both contain same name functions, // checkFunctionOrConstructorSymbol wouldn't be called if we didnt ignore javascript function. var firstDeclaration = ts.find(localSymbol.declarations, // Get first non javascript function declaration function (declaration) { return declaration.kind === node.kind && !(declaration.flags & 65536 /* JavaScriptFile */); }); // Only type check the symbol once if (node === firstDeclaration) { checkFunctionOrConstructorSymbol(localSymbol); } if (symbol.parent) { // run check once for the first declaration if (ts.getDeclarationOfKind(symbol, node.kind) === node) { // run check on export symbol to check that modifiers agree across all exported declarations checkFunctionOrConstructorSymbol(symbol); } } } checkSourceElement(node.body); var returnTypeNode = ts.getEffectiveReturnTypeNode(node); if ((functionFlags & 1 /* Generator */) === 0) { var returnOrPromisedType = returnTypeNode && (functionFlags & 2 /* Async */ ? checkAsyncFunctionReturnType(node) // Async function : getTypeFromTypeNode(returnTypeNode)); // normal function checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType); } if (produceDiagnostics && !returnTypeNode) { // Report an implicit any error if there is no body, no explicit return type, and node is not a private method // in an ambient context if (noImplicitAny && ts.nodeIsMissing(node.body) && !isPrivateWithinAmbient(node)) { reportImplicitAnyError(node, anyType); } if (functionFlags & 1 /* Generator */ && ts.nodeIsPresent(node.body)) { // A generator with a body and no type annotation can still cause errors. It can error if the // yielded values have no common supertype, or it can give an implicit any error if it has no // yielded values. The only way to trigger these errors is to try checking its return type. getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } } registerForUnusedIdentifiersCheck(node); } function registerForUnusedIdentifiersCheck(node) { if (deferredUnusedIdentifierNodes) { deferredUnusedIdentifierNodes.push(node); } } function checkUnusedIdentifiers() { if (deferredUnusedIdentifierNodes) { for (var _i = 0, deferredUnusedIdentifierNodes_1 = deferredUnusedIdentifierNodes; _i < deferredUnusedIdentifierNodes_1.length; _i++) { var node = deferredUnusedIdentifierNodes_1[_i]; switch (node.kind) { case 269 /* SourceFile */: case 234 /* ModuleDeclaration */: checkUnusedModuleMembers(node); break; case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: checkUnusedClassMembers(node); checkUnusedTypeParameters(node); break; case 231 /* InterfaceDeclaration */: checkUnusedTypeParameters(node); break; case 208 /* Block */: case 236 /* CaseBlock */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: checkUnusedLocalsAndParameters(node); break; case 153 /* Constructor */: case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: if (node.body) { checkUnusedLocalsAndParameters(node); } checkUnusedTypeParameters(node); break; case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 232 /* TypeAliasDeclaration */: checkUnusedTypeParameters(node); break; default: ts.Debug.fail("Node should not have been registered for unused identifiers check"); } } } } function checkUnusedLocalsAndParameters(node) { if (noUnusedIdentifiers && !(node.flags & 2097152 /* Ambient */)) { node.locals.forEach(function (local) { if (!local.isReferenced) { if (local.valueDeclaration && ts.getRootDeclaration(local.valueDeclaration).kind === 147 /* Parameter */) { var parameter = ts.getRootDeclaration(local.valueDeclaration); var name = ts.getNameOfDeclaration(local.valueDeclaration); if (compilerOptions.noUnusedParameters && !ts.isParameterPropertyDeclaration(parameter) && !ts.parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) { error(name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(local)); } } else if (compilerOptions.noUnusedLocals) { ts.forEach(local.declarations, function (d) { return errorUnusedLocal(d, ts.symbolName(local)); }); } } }); } } function isRemovedPropertyFromObjectSpread(node) { if (ts.isBindingElement(node) && ts.isObjectBindingPattern(node.parent)) { var lastElement = ts.lastOrUndefined(node.parent.elements); return lastElement !== node && !!lastElement.dotDotDotToken; } return false; } function errorUnusedLocal(declaration, name) { var node = ts.getNameOfDeclaration(declaration) || declaration; if (isIdentifierThatStartsWithUnderScore(node)) { var declaration_2 = ts.getRootDeclaration(node.parent); if ((declaration_2.kind === 227 /* VariableDeclaration */ && ts.isForInOrOfStatement(declaration_2.parent.parent)) || declaration_2.kind === 146 /* TypeParameter */) { return; } } if (!isRemovedPropertyFromObjectSpread(node.kind === 71 /* Identifier */ ? node.parent : node)) { error(node, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, name); } } function parameterNameStartsWithUnderscore(parameterName) { return parameterName && isIdentifierThatStartsWithUnderScore(parameterName); } function isIdentifierThatStartsWithUnderScore(node) { return node.kind === 71 /* Identifier */ && ts.idText(node).charCodeAt(0) === 95 /* _ */; } function checkUnusedClassMembers(node) { if (compilerOptions.noUnusedLocals && !(node.flags & 2097152 /* Ambient */)) { if (node.members) { for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 152 /* MethodDeclaration */ || member.kind === 150 /* PropertyDeclaration */) { if (!member.symbol.isReferenced && ts.hasModifier(member, 8 /* Private */)) { error(member.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(member.symbol)); } } else if (member.kind === 153 /* Constructor */) { for (var _b = 0, _c = member.parameters; _b < _c.length; _b++) { var parameter = _c[_b]; if (!parameter.symbol.isReferenced && ts.hasModifier(parameter, 8 /* Private */)) { error(parameter.name, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read, ts.symbolName(parameter.symbol)); } } } } } } } function checkUnusedTypeParameters(node) { if (compilerOptions.noUnusedLocals && !(node.flags & 2097152 /* Ambient */)) { if (node.typeParameters) { // Only report errors on the last declaration for the type parameter container; // this ensures that all uses have been accounted for. var symbol = getSymbolOfNode(node); var lastDeclaration = symbol && symbol.declarations && ts.lastOrUndefined(symbol.declarations); if (lastDeclaration !== node) { return; } for (var _i = 0, _a = node.typeParameters; _i < _a.length; _i++) { var typeParameter = _a[_i]; if (!getMergedSymbol(typeParameter.symbol).isReferenced && !isIdentifierThatStartsWithUnderScore(typeParameter.name)) { error(typeParameter.name, ts.Diagnostics._0_is_declared_but_its_value_is_never_read, ts.symbolName(typeParameter.symbol)); } } } } } function checkUnusedModuleMembers(node) { if (compilerOptions.noUnusedLocals && !(node.flags & 2097152 /* Ambient */)) { node.locals.forEach(function (local) { if (!local.isReferenced && !local.exportSymbol) { for (var _i = 0, _a = local.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (!ts.isAmbientModule(declaration)) { errorUnusedLocal(declaration, ts.symbolName(local)); } } } }); } } function checkBlock(node) { // Grammar checking for SyntaxKind.Block if (node.kind === 208 /* Block */) { checkGrammarStatementInAmbientContext(node); } if (ts.isFunctionOrModuleBlock(node)) { var saveFlowAnalysisDisabled = flowAnalysisDisabled; ts.forEach(node.statements, checkSourceElement); flowAnalysisDisabled = saveFlowAnalysisDisabled; } else { ts.forEach(node.statements, checkSourceElement); } if (node.locals) { registerForUnusedIdentifiersCheck(node); } } function checkCollisionWithArgumentsInGeneratedCode(node) { // no rest parameters \ declaration context \ overload - no codegen impact if (!ts.hasRestParameter(node) || node.flags & 2097152 /* Ambient */ || ts.nodeIsMissing(node.body)) { return; } ts.forEach(node.parameters, function (p) { if (p.name && !ts.isBindingPattern(p.name) && p.name.escapedText === argumentsSymbol.escapedName) { error(p, ts.Diagnostics.Duplicate_identifier_arguments_Compiler_uses_arguments_to_initialize_rest_parameters); } }); } function needCollisionCheckForIdentifier(node, identifier, name) { if (!(identifier && identifier.escapedText === name)) { return false; } if (node.kind === 150 /* PropertyDeclaration */ || node.kind === 149 /* PropertySignature */ || node.kind === 152 /* MethodDeclaration */ || node.kind === 151 /* MethodSignature */ || node.kind === 154 /* GetAccessor */ || node.kind === 155 /* SetAccessor */) { // it is ok to have member named '_super' or '_this' - member access is always qualified return false; } if (node.flags & 2097152 /* Ambient */) { // ambient context - no codegen impact return false; } var root = ts.getRootDeclaration(node); if (root.kind === 147 /* Parameter */ && ts.nodeIsMissing(root.parent.body)) { // just an overload - no codegen impact return false; } return true; } function checkCollisionWithCapturedThisVariable(node, name) { if (needCollisionCheckForIdentifier(node, name, "_this")) { potentialThisCollisions.push(node); } } function checkCollisionWithCapturedNewTargetVariable(node, name) { if (needCollisionCheckForIdentifier(node, name, "_newTarget")) { potentialNewTargetCollisions.push(node); } } // this function will run after checking the source file so 'CaptureThis' is correct for all nodes function checkIfThisIsCapturedInEnclosingScope(node) { ts.findAncestor(node, function (current) { if (getNodeCheckFlags(current) & 4 /* CaptureThis */) { var isDeclaration_1 = node.kind !== 71 /* Identifier */; if (isDeclaration_1) { error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_this_Compiler_uses_variable_declaration_this_to_capture_this_reference); } else { error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_this_that_compiler_uses_to_capture_this_reference); } return true; } }); } function checkIfNewTargetIsCapturedInEnclosingScope(node) { ts.findAncestor(node, function (current) { if (getNodeCheckFlags(current) & 8 /* CaptureNewTarget */) { var isDeclaration_2 = node.kind !== 71 /* Identifier */; if (isDeclaration_2) { error(ts.getNameOfDeclaration(node), ts.Diagnostics.Duplicate_identifier_newTarget_Compiler_uses_variable_declaration_newTarget_to_capture_new_target_meta_property_reference); } else { error(node, ts.Diagnostics.Expression_resolves_to_variable_declaration_newTarget_that_compiler_uses_to_capture_new_target_meta_property_reference); } return true; } }); } function checkCollisionWithCapturedSuperVariable(node, name) { if (!needCollisionCheckForIdentifier(node, name, "_super")) { return; } // bubble up and find containing type var enclosingClass = ts.getContainingClass(node); // if containing type was not found or it is ambient - exit (no codegen) if (!enclosingClass || enclosingClass.flags & 2097152 /* Ambient */) { return; } if (ts.getClassExtendsHeritageClauseElement(enclosingClass)) { var isDeclaration_3 = node.kind !== 71 /* Identifier */; if (isDeclaration_3) { error(node, ts.Diagnostics.Duplicate_identifier_super_Compiler_uses_super_to_capture_base_class_reference); } else { error(node, ts.Diagnostics.Expression_resolves_to_super_that_compiler_uses_to_capture_base_class_reference); } } } function checkCollisionWithRequireExportsInGeneratedCode(node, name) { // No need to check for require or exports for ES6 modules and later if (modulekind >= ts.ModuleKind.ES2015) { return; } if (!needCollisionCheckForIdentifier(node, name, "require") && !needCollisionCheckForIdentifier(node, name, "exports")) { return; } // Uninstantiated modules shouldnt do this check if (ts.isModuleDeclaration(node) && 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 === 269 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent)) { // If the declaration happens to be in external module, report error that require and exports are reserved keywords error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module, ts.declarationNameToString(name), ts.declarationNameToString(name)); } } function checkCollisionWithGlobalPromiseInGeneratedCode(node, name) { if (languageVersion >= 4 /* ES2017 */ || !needCollisionCheckForIdentifier(node, name, "Promise")) { return; } // Uninstantiated modules shouldnt do this check if (ts.isModuleDeclaration(node) && 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 === 269 /* SourceFile */ && ts.isExternalOrCommonJsModule(parent) && parent.flags & 1024 /* HasAsyncFunctions */) { // If the declaration happens to be in external module, report error that Promise is a reserved identifier. error(name, ts.Diagnostics.Duplicate_identifier_0_Compiler_reserves_name_1_in_top_level_scope_of_a_module_containing_async_functions, ts.declarationNameToString(name), ts.declarationNameToString(name)); } } function checkVarDeclaredNamesNotShadowed(node) { // - ScriptBody : StatementList // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList // also occurs in the VarDeclaredNames of StatementList. // - Block : { StatementList } // It is a Syntax Error if any element of the LexicallyDeclaredNames of StatementList // also occurs in the VarDeclaredNames of StatementList. // Variable declarations are hoisted to the top of their function scope. They can shadow // block scoped declarations, which bind tighter. this will not be flagged as duplicate definition // by the binder as the declaration scope is different. // A non-initialized declaration is a no-op as the block declaration will resolve before the var // declaration. the problem is if the declaration has an initializer. this will act as a write to the // block declared value. this is fine for let, but not const. // Only consider declarations with initializers, uninitialized const declarations will not // step on a let/const variable. // Do not consider const and const declarations, as duplicate block-scoped declarations // are handled by the binder. // We are only looking for const declarations that step on let\const declarations from a // different scope. e.g.: // { // const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration // const x = 0; // symbol for this declaration will be 'symbol' // } // skip block-scoped variables and parameters if ((ts.getCombinedNodeFlags(node) & 3 /* BlockScoped */) !== 0 || ts.isParameterDeclaration(node)) { return; } // skip variable declarations that don't have initializers // NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern // so we'll always treat binding elements as initialized if (node.kind === 227 /* VariableDeclaration */ && !node.initializer) { return; } var symbol = getSymbolOfNode(node); if (symbol.flags & 1 /* FunctionScopedVariable */) { if (!ts.isIdentifier(node.name)) throw ts.Debug.fail(); var localDeclarationSymbol = resolveName(node, node.name.escapedText, 3 /* Variable */, /*nodeNotFoundErrorMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); if (localDeclarationSymbol && localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & 2 /* BlockScopedVariable */) { if (getDeclarationNodeFlagsFromSymbol(localDeclarationSymbol) & 3 /* BlockScoped */) { var varDeclList = ts.getAncestor(localDeclarationSymbol.valueDeclaration, 228 /* VariableDeclarationList */); var container = varDeclList.parent.kind === 209 /* 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 === 208 /* Block */ && ts.isFunctionLike(container.parent) || container.kind === 235 /* ModuleBlock */ || container.kind === 234 /* ModuleDeclaration */ || container.kind === 269 /* SourceFile */); // here we know that function scoped variable is shadowed by block scoped one // if they are defined in the same scope - binder has already reported redeclaration error // otherwise if variable has an initializer - show error that initialization will fail // since LHS will be block scoped name instead of function scoped if (!namesShareScope) { var name = symbolToString(localDeclarationSymbol); error(node, ts.Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name); } } } } } // Check that a parameter initializer contains no references to parameters declared to the right of itself function checkParameterInitializer(node) { if (ts.getRootDeclaration(node).kind !== 147 /* 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 === 180 /* PropertyAccessExpression */) { // skip property names in property access expression return visit(n.expression); } else if (n.kind === 71 /* Identifier */) { // check FunctionLikeDeclaration.locals (stores parameters\function local variable) // if it contains entry with a specified name var symbol = resolveName(n, n.escapedText, 107455 /* Value */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false); if (!symbol || symbol === unknownSymbol || !symbol.valueDeclaration) { return; } if (symbol.valueDeclaration === node) { error(n, ts.Diagnostics.Parameter_0_cannot_be_referenced_in_its_initializer, ts.declarationNameToString(node.name)); return; } // locals map for function contain both parameters and function locals // so we need to do a bit of extra work to check if reference is legal var enclosingContainer = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration); if (enclosingContainer === func) { if (symbol.valueDeclaration.kind === 147 /* Parameter */ || symbol.valueDeclaration.kind === 177 /* BindingElement */) { // it is ok to reference parameter in initializer if either // - parameter is located strictly on the left of current parameter declaration if (symbol.valueDeclaration.pos < node.pos) { return; } // - parameter is wrapped in function-like entity if (ts.findAncestor(n, function (current) { if (current === node.initializer) { return "quit"; } return ts.isFunctionLike(current.parent) || // computed property names/initializers in instance property declaration of class like entities // are executed in constructor and thus deferred (current.parent.kind === 150 /* PropertyDeclaration */ && !(ts.hasModifier(current.parent, 32 /* Static */)) && ts.isClassLike(current.parent.parent)); })) { return; } // fall through to report error } error(n, ts.Diagnostics.Initializer_of_parameter_0_cannot_reference_identifier_1_declared_after_it, ts.declarationNameToString(node.name), ts.declarationNameToString(n)); } } else { return ts.forEachChild(n, visit); } } } function convertAutoToAny(type) { return type === autoType ? anyType : type === autoArrayType ? anyArrayType : type; } // Check variable, parameter, or property declaration function checkVariableLikeDeclaration(node) { checkDecorators(node); checkSourceElement(node.type); // JSDoc `function(string, string): string` syntax results in parameters with no name if (!node.name) { return; } // For a computed property, just check the initializer and exit // Do not use hasDynamicName here, because that returns false for well known symbols. // We want to perform checkComputedPropertyName for all computed properties, including // well known symbols. if (node.name.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(node.name); if (node.initializer) { checkExpressionCached(node.initializer); } } if (node.kind === 177 /* BindingElement */) { if (node.parent.kind === 175 /* ObjectBindingPattern */ && languageVersion < 6 /* ESNext */) { checkExternalEmitHelpers(node, 4 /* Rest */); } // check computed properties inside property names of binding elements if (node.propertyName && node.propertyName.kind === 145 /* ComputedPropertyName */) { checkComputedPropertyName(node.propertyName); } // check private/protected variable access var parent = node.parent.parent; var parentType = getTypeForBindingElementParent(parent); var name = node.propertyName || node.name; var property = getPropertyOfType(parentType, ts.getTextOfPropertyName(name)); markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference. if (parent.initializer && property) { checkPropertyAccessibility(parent, parent.initializer, parentType, property); } } // For a binding pattern, check contained binding elements if (ts.isBindingPattern(node.name)) { if (node.name.kind === 176 /* ArrayBindingPattern */ && languageVersion < 2 /* ES2015 */ && compilerOptions.downlevelIteration) { checkExternalEmitHelpers(node, 512 /* Read */); } ts.forEach(node.name.elements, checkSourceElement); } // For a parameter declaration with an initializer, error and exit if the containing function doesn't have a body if (node.initializer && ts.getRootDeclaration(node).kind === 147 /* 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 !== 216 /* ForInStatement */) { checkTypeAssignableTo(checkExpressionCached(node.initializer), getWidenedTypeForVariableLikeDeclaration(node), node, /*headMessage*/ undefined); checkParameterInitializer(node); } return; } var symbol = getSymbolOfNode(node); var type = convertAutoToAny(getTypeOfVariableOrParameterOrProperty(symbol)); if (node === symbol.valueDeclaration) { // Node is the primary declaration of the symbol, just validate the initializer // Don't validate for-in initializer as it is already an error if (node.initializer && node.parent.parent.kind !== 216 /* ForInStatement */) { checkTypeAssignableTo(checkExpressionCached(node.initializer), type, node, /*headMessage*/ undefined); checkParameterInitializer(node); } } else { // Node is a secondary declaration, check that type is identical to primary declaration and check that // initializer is consistent with type associated with the node var declarationType = convertAutoToAny(getWidenedTypeForVariableLikeDeclaration(node)); if (type !== unknownType && declarationType !== unknownType && !isTypeIdenticalTo(type, declarationType) && !(symbol.flags & 67108864 /* JSContainer */)) { errorNextVariableOrPropertyDeclarationMustHaveSameType(type, node, declarationType); } if (node.initializer) { checkTypeAssignableTo(checkExpressionCached(node.initializer), declarationType, node, /*headMessage*/ undefined); } if (!areDeclarationFlagsIdentical(node, symbol.valueDeclaration)) { error(ts.getNameOfDeclaration(symbol.valueDeclaration), ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); error(node.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_modifiers, ts.declarationNameToString(node.name)); } } if (node.kind !== 150 /* PropertyDeclaration */ && node.kind !== 149 /* PropertySignature */) { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations(node); if (node.kind === 227 /* VariableDeclaration */ || node.kind === 177 /* BindingElement */) { checkVarDeclaredNamesNotShadowed(node); } checkCollisionWithCapturedSuperVariable(node, node.name); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } } function errorNextVariableOrPropertyDeclarationMustHaveSameType(firstType, nextDeclaration, nextType) { var nextDeclarationName = ts.getNameOfDeclaration(nextDeclaration); var message = nextDeclaration.kind === 150 /* PropertyDeclaration */ || nextDeclaration.kind === 149 /* PropertySignature */ ? ts.Diagnostics.Subsequent_property_declarations_must_have_the_same_type_Property_0_must_be_of_type_1_but_here_has_type_2 : ts.Diagnostics.Subsequent_variable_declarations_must_have_the_same_type_Variable_0_must_be_of_type_1_but_here_has_type_2; error(nextDeclarationName, message, ts.declarationNameToString(nextDeclarationName), typeToString(firstType), typeToString(nextType)); } function areDeclarationFlagsIdentical(left, right) { if ((left.kind === 147 /* Parameter */ && right.kind === 227 /* VariableDeclaration */) || (left.kind === 227 /* VariableDeclaration */ && right.kind === 147 /* Parameter */)) { // Differences in optionality between parameters and variables are allowed. return true; } if (ts.hasQuestionToken(left) !== ts.hasQuestionToken(right)) { return false; } var interestingFlags = 8 /* Private */ | 16 /* Protected */ | 256 /* Async */ | 128 /* Abstract */ | 64 /* Readonly */ | 32 /* Static */; return ts.getSelectedModifierFlags(left, interestingFlags) === ts.getSelectedModifierFlags(right, interestingFlags); } function checkVariableDeclaration(node) { checkGrammarVariableDeclaration(node); return checkVariableLikeDeclaration(node); } function checkBindingElement(node) { checkGrammarBindingElement(node); return checkVariableLikeDeclaration(node); } function checkVariableStatement(node) { // Grammar checking if (!checkGrammarDecoratorsAndModifiers(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 === 179 /* ObjectLiteralExpression */) { if (ts.getFunctionFlags(node) & 2 /* Async */) { if (node.modifiers.length > 1) { return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); } } else { return grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here); } } } function checkExpressionStatement(node) { // Grammar checking checkGrammarStatementInAmbientContext(node); checkExpression(node.expression); } function checkIfStatement(node) { // Grammar checking checkGrammarStatementInAmbientContext(node); checkExpression(node.expression); checkSourceElement(node.thenStatement); if (node.thenStatement.kind === 210 /* 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 === 228 /* VariableDeclarationList */) { checkGrammarVariableDeclarationList(node.initializer); } } if (node.initializer) { if (node.initializer.kind === 228 /* VariableDeclarationList */) { ts.forEach(node.initializer.declarations, checkVariableDeclaration); } else { checkExpression(node.initializer); } } if (node.condition) checkExpression(node.condition); if (node.incrementor) checkExpression(node.incrementor); checkSourceElement(node.statement); if (node.locals) { registerForUnusedIdentifiersCheck(node); } } function checkForOfStatement(node) { checkGrammarForInOrForOfStatement(node); if (node.kind === 217 /* ForOfStatement */) { if (node.awaitModifier) { var functionFlags = ts.getFunctionFlags(ts.getContainingFunction(node)); if ((functionFlags & (4 /* Invalid */ | 2 /* Async */)) === 2 /* Async */ && languageVersion < 6 /* ESNext */) { // for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper checkExternalEmitHelpers(node, 16384 /* ForAwaitOfIncludes */); } } else if (compilerOptions.downlevelIteration && languageVersion < 2 /* ES2015 */) { // for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled checkExternalEmitHelpers(node, 256 /* ForOfIncludes */); } } // Check the LHS and RHS // If the LHS is a declaration, just check it as a variable declaration, which will in turn check the RHS // via checkRightHandSideOfForOf. // If the LHS is an expression, check the LHS, as a destructuring assignment or as a reference. // Then check that the RHS is assignable to it. if (node.initializer.kind === 228 /* VariableDeclarationList */) { checkForInOrForOfVariableDeclaration(node); } else { var varExpr = node.initializer; var iteratedType = checkRightHandSideOfForOf(node.expression, node.awaitModifier); // There may be a destructuring assignment on the left side if (varExpr.kind === 178 /* ArrayLiteralExpression */ || varExpr.kind === 179 /* ObjectLiteralExpression */) { // iteratedType may be undefined. In this case, we still want to check the structure of // varExpr, in particular making sure it's a valid LeftHandSideExpression. But we'd like // to short circuit the type relation checking as much as possible, so we pass the unknownType. checkDestructuringAssignment(varExpr, iteratedType || unknownType); } else { var leftType = checkExpression(varExpr); checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_of_statement_must_be_a_variable_or_a_property_access); // iteratedType will be undefined if the rightType was missing properties/signatures // required to get its iteratedType (like [Symbol.iterator] or next). This may be // because we accessed properties from anyType, or it may have led to an error inside // getElementTypeOfIterable. if (iteratedType) { checkTypeAssignableTo(iteratedType, leftType, varExpr, /*headMessage*/ undefined); } } } checkSourceElement(node.statement); if (node.locals) { registerForUnusedIdentifiersCheck(node); } } function checkForInStatement(node) { // Grammar checking checkGrammarForInOrForOfStatement(node); var rightType = checkNonNullExpression(node.expression); // TypeScript 1.0 spec (April 2014): 5.4 // In a 'for-in' statement of the form // for (let VarDecl in Expr) Statement // VarDecl must be a variable declaration without a type annotation that declares a variable of type Any, // and Expr must be an expression of type Any, an object type, or a type parameter type. if (node.initializer.kind === 228 /* 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 === 178 /* ArrayLiteralExpression */ || varExpr.kind === 179 /* ObjectLiteralExpression */) { error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_cannot_be_a_destructuring_pattern); } else if (!isTypeAssignableTo(getIndexTypeOrString(rightType), leftType)) { error(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_of_type_string_or_any); } else { // run check only former check succeeded to avoid cascading errors checkReferenceExpression(varExpr, ts.Diagnostics.The_left_hand_side_of_a_for_in_statement_must_be_a_variable_or_a_property_access); } } // unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved // in this case error about missing name is already reported - do not report extra one if (!isTypeAssignableToKind(rightType, 33554432 /* NonPrimitive */ | 1081344 /* TypeVariable */)) { error(node.expression, ts.Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter); } checkSourceElement(node.statement); if (node.locals) { registerForUnusedIdentifiersCheck(node); } } function checkForInOrForOfVariableDeclaration(iterationStatement) { var variableDeclarationList = iterationStatement.initializer; // checkGrammarForInOrForOfStatement will check that there is exactly one declaration. if (variableDeclarationList.declarations.length >= 1) { var decl = variableDeclarationList.declarations[0]; checkVariableDeclaration(decl); } } function checkRightHandSideOfForOf(rhsExpression, awaitModifier) { var expressionType = checkNonNullExpression(rhsExpression); return checkIteratedTypeOrElementType(expressionType, rhsExpression, /*allowStringInput*/ true, awaitModifier !== undefined); } function checkIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables) { if (isTypeAny(inputType)) { return inputType; } return getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, /*checkAssignability*/ true) || anyType; } /** * When consuming an iterable type in a for..of, spread, or iterator destructuring assignment * we want to get the iterated type of an iterable for ES2015 or later, or the iterated type * of a iterable (if defined globally) or element type of an array like for ES2015 or earlier. */ function getIteratedTypeOrElementType(inputType, errorNode, allowStringInput, allowAsyncIterables, checkAssignability) { var uplevelIteration = languageVersion >= 2 /* ES2015 */; var downlevelIteration = !uplevelIteration && compilerOptions.downlevelIteration; // Get the iterated type of an `Iterable` or `IterableIterator` only in ES2015 // or higher, when inside of an async generator or for-await-if, or when // downlevelIteration is requested. if (uplevelIteration || downlevelIteration || allowAsyncIterables) { // We only report errors for an invalid iterable type in ES2015 or higher. var iteratedType = getIteratedTypeOfIterable(inputType, uplevelIteration ? errorNode : undefined, allowAsyncIterables, /*allowSyncIterables*/ true, checkAssignability); if (iteratedType || uplevelIteration) { return iteratedType; } } var arrayType = inputType; var reportedError = false; var hasStringConstituent = false; // If strings are permitted, remove any string-like constituents from the array type. // This allows us to find other non-string element types from an array unioned with // a string. if (allowStringInput) { if (arrayType.flags & 131072 /* Union */) { // After we remove all types that are StringLike, we will know if there was a string constituent // based on whether the result of filter is a new array. var arrayTypes = inputType.types; var filteredTypes = ts.filter(arrayTypes, function (t) { return !(t.flags & 524322 /* StringLike */); }); if (filteredTypes !== arrayTypes) { arrayType = getUnionType(filteredTypes, /*subtypeReduction*/ true); } } else if (arrayType.flags & 524322 /* StringLike */) { arrayType = neverType; } hasStringConstituent = arrayType !== inputType; if (hasStringConstituent) { if (languageVersion < 1 /* ES5 */) { if (errorNode) { error(errorNode, ts.Diagnostics.Using_a_string_in_a_for_of_statement_is_only_supported_in_ECMAScript_5_and_higher); reportedError = true; } } // Now that we've removed all the StringLike types, if no constituents remain, then the entire // arrayOrStringType was a string. if (arrayType.flags & 16384 /* Never */) { return stringType; } } } if (!isArrayLikeType(arrayType)) { if (errorNode && !reportedError) { // Which error we report depends on whether we allow strings or if there was a // string constituent. For example, if the input type is number | string, we // want to say that number is not an array type. But if the input was just // number and string input is allowed, we want to say that number is not an // array type or a string type. var diagnostic = !allowStringInput || hasStringConstituent ? downlevelIteration ? ts.Diagnostics.Type_0_is_not_an_array_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator : ts.Diagnostics.Type_0_is_not_an_array_type : downlevelIteration ? ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type_or_does_not_have_a_Symbol_iterator_method_that_returns_an_iterator : ts.Diagnostics.Type_0_is_not_an_array_type_or_a_string_type; error(errorNode, diagnostic, typeToString(arrayType)); } return hasStringConstituent ? stringType : undefined; } var arrayElementType = getIndexTypeOfType(arrayType, 1 /* Number */); if (hasStringConstituent && arrayElementType) { // This is just an optimization for the case where arrayOrStringType is string | string[] if (arrayElementType.flags & 524322 /* StringLike */) { return stringType; } return getUnionType([arrayElementType, stringType], /*subtypeReduction*/ true); } return arrayElementType; } /** * We want to treat type as an iterable, and get the type it is an iterable of. The iterable * must have the following structure (annotated with the names of the variables below): * * { // iterable * [Symbol.iterator]: { // iteratorMethod * (): Iterator * } * } * * For an async iterable, we expect the following structure: * * { // iterable * [Symbol.asyncIterator]: { // iteratorMethod * (): AsyncIterator * } * } * * T is the type we are after. At every level that involves analyzing return types * of signatures, we union the return types of all the signatures. * * Another thing to note is that at any step of this process, we could run into a dead end, * meaning either the property is missing, or we run into the anyType. If either of these things * happens, we return undefined to signal that we could not find the iterated type. If a property * is missing, and the previous step did not result in 'any', then we also give an error if the * caller requested it. Then the caller can decide what to do in the case where there is no iterated * type. This is different from returning anyType, because that would signify that we have matched the * whole pattern and that T (above) is 'any'. * * For a **for-of** statement, `yield*` (in a normal generator), spread, array * destructuring, or normal generator we will only ever look for a `[Symbol.iterator]()` * method. * * For an async generator we will only ever look at the `[Symbol.asyncIterator]()` method. * * For a **for-await-of** statement or a `yield*` in an async generator we will look for * the `[Symbol.asyncIterator]()` method first, and then the `[Symbol.iterator]()` method. */ function getIteratedTypeOfIterable(type, errorNode, allowAsyncIterables, allowSyncIterables, checkAssignability) { if (isTypeAny(type)) { return undefined; } return mapType(type, getIteratedType); function getIteratedType(type) { var typeAsIterable = type; if (allowAsyncIterables) { if (typeAsIterable.iteratedTypeOfAsyncIterable) { return typeAsIterable.iteratedTypeOfAsyncIterable; } // As an optimization, if the type is an instantiation of the global `AsyncIterable` // or the global `AsyncIterableIterator` then just grab its type argument. if (isReferenceToType(type, getGlobalAsyncIterableType(/*reportErrors*/ false)) || isReferenceToType(type, getGlobalAsyncIterableIteratorType(/*reportErrors*/ false))) { return typeAsIterable.iteratedTypeOfAsyncIterable = type.typeArguments[0]; } } if (allowSyncIterables) { if (typeAsIterable.iteratedTypeOfIterable) { return typeAsIterable.iteratedTypeOfIterable; } // As an optimization, if the type is an instantiation of the global `Iterable` or // `IterableIterator` then just grab its type argument. if (isReferenceToType(type, getGlobalIterableType(/*reportErrors*/ false)) || isReferenceToType(type, getGlobalIterableIteratorType(/*reportErrors*/ false))) { return typeAsIterable.iteratedTypeOfIterable = type.typeArguments[0]; } } var asyncMethodType = allowAsyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("asyncIterator")); var methodType = asyncMethodType || (allowSyncIterables && getTypeOfPropertyOfType(type, ts.getPropertyNameForKnownSymbolName("iterator"))); if (isTypeAny(methodType)) { return undefined; } var signatures = methodType && getSignaturesOfType(methodType, 0 /* Call */); if (!ts.some(signatures)) { if (errorNode) { error(errorNode, allowAsyncIterables ? ts.Diagnostics.Type_must_have_a_Symbol_asyncIterator_method_that_returns_an_async_iterator : ts.Diagnostics.Type_must_have_a_Symbol_iterator_method_that_returns_an_iterator); // only report on the first error errorNode = undefined; } return undefined; } var returnType = getUnionType(ts.map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); var iteratedType = getIteratedTypeOfIterator(returnType, errorNode, /*isAsyncIterator*/ !!asyncMethodType); if (checkAssignability && errorNode && iteratedType) { // If `checkAssignability` was specified, we were called from // `checkIteratedTypeOrElementType`. As such, we need to validate that // the type passed in is actually an Iterable. checkTypeAssignableTo(type, asyncMethodType ? createAsyncIterableType(iteratedType) : createIterableType(iteratedType), errorNode); } return asyncMethodType ? typeAsIterable.iteratedTypeOfAsyncIterable = iteratedType : typeAsIterable.iteratedTypeOfIterable = iteratedType; } } /** * This function has very similar logic as getIteratedTypeOfIterable, except that it operates on * Iterators instead of Iterables. Here is the structure: * * { // iterator * next: { // nextMethod * (): { // nextResult * value: T // nextValue * } * } * } * * For an async iterator, we expect the following structure: * * { // iterator * next: { // nextMethod * (): PromiseLike<{ // nextResult * value: T // nextValue * }> * } * } */ function getIteratedTypeOfIterator(type, errorNode, isAsyncIterator) { if (isTypeAny(type)) { return undefined; } var typeAsIterator = type; if (isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator) { return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator : typeAsIterator.iteratedTypeOfIterator; } // As an optimization, if the type is an instantiation of the global `Iterator` (for // a non-async iterator) or the global `AsyncIterator` (for an async-iterator) then // just grab its type argument. var getIteratorType = isAsyncIterator ? getGlobalAsyncIteratorType : getGlobalIteratorType; if (isReferenceToType(type, getIteratorType(/*reportErrors*/ false))) { return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator = type.typeArguments[0] : typeAsIterator.iteratedTypeOfIterator = type.typeArguments[0]; } // Both async and non-async iterators must have a `next` method. var nextMethod = getTypeOfPropertyOfType(type, "next"); if (isTypeAny(nextMethod)) { return undefined; } var nextMethodSignatures = nextMethod ? getSignaturesOfType(nextMethod, 0 /* Call */) : ts.emptyArray; if (nextMethodSignatures.length === 0) { if (errorNode) { error(errorNode, isAsyncIterator ? ts.Diagnostics.An_async_iterator_must_have_a_next_method : ts.Diagnostics.An_iterator_must_have_a_next_method); } return undefined; } var nextResult = getUnionType(ts.map(nextMethodSignatures, getReturnTypeOfSignature), /*subtypeReduction*/ true); if (isTypeAny(nextResult)) { return undefined; } // For an async iterator, we must get the awaited type of the return type. if (isAsyncIterator) { nextResult = getAwaitedTypeOfPromise(nextResult, errorNode, ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property); if (isTypeAny(nextResult)) { return undefined; } } var nextValue = nextResult && getTypeOfPropertyOfType(nextResult, "value"); if (!nextValue) { if (errorNode) { error(errorNode, isAsyncIterator ? ts.Diagnostics.The_type_returned_by_the_next_method_of_an_async_iterator_must_be_a_promise_for_a_type_with_a_value_property : ts.Diagnostics.The_type_returned_by_the_next_method_of_an_iterator_must_have_a_value_property); } return undefined; } return isAsyncIterator ? typeAsIterator.iteratedTypeOfAsyncIterator = nextValue : typeAsIterator.iteratedTypeOfIterator = nextValue; } /** * A generator may have a return type of `Iterator`, `Iterable`, or * `IterableIterator`. An async generator may have a return type of `AsyncIterator`, * `AsyncIterable`, or `AsyncIterableIterator`. This function can be used to extract * the iterated type from this return type for contextual typing and verifying signatures. */ function getIteratedTypeOfGenerator(returnType, isAsyncGenerator) { if (isTypeAny(returnType)) { return undefined; } return getIteratedTypeOfIterable(returnType, /*errorNode*/ undefined, /*allowAsyncIterables*/ isAsyncGenerator, /*allowSyncIterables*/ !isAsyncGenerator, /*checkAssignability*/ false) || getIteratedTypeOfIterator(returnType, /*errorNode*/ undefined, isAsyncGenerator); } function checkBreakOrContinueStatement(node) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) checkGrammarBreakOrContinueStatement(node); // TODO: Check that target label is valid } function isGetAccessorWithAnnotatedSetAccessor(node) { return node.kind === 154 /* GetAccessor */ && ts.getEffectiveSetAccessorTypeAnnotationNode(ts.getDeclarationOfKind(node.symbol, 155 /* SetAccessor */)) !== undefined; } function isUnwrappedReturnTypeVoidOrAny(func, returnType) { var unwrappedReturnType = (ts.getFunctionFlags(func) & 3 /* AsyncGenerator */) === 2 /* Async */ ? getPromisedTypeOfPromise(returnType) // Async function : returnType; // AsyncGenerator function, Generator function, or normal function return unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, 2048 /* 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); var functionFlags = ts.getFunctionFlags(func); if (functionFlags & 1 /* Generator */) { // A generator does not need its return expressions checked against its return type. // Instead, the yield expressions are checked against the element type. // TODO: Check return expressions of generators when return type tracking is added // for generators. return; } if (strictNullChecks || node.expression || returnType.flags & 16384 /* Never */) { var exprType = node.expression ? checkExpressionCached(node.expression) : undefinedType; if (func.kind === 155 /* SetAccessor */) { if (node.expression) { error(node, ts.Diagnostics.Setters_cannot_return_a_value); } } else if (func.kind === 153 /* Constructor */) { if (node.expression && !checkTypeAssignableTo(exprType, returnType, node)) { error(node, ts.Diagnostics.Return_type_of_constructor_signature_must_be_assignable_to_the_instance_type_of_the_class); } } else if (ts.getEffectiveReturnTypeNode(func) || isGetAccessorWithAnnotatedSetAccessor(func)) { if (functionFlags & 2 /* Async */) { var promisedType = getPromisedTypeOfPromise(returnType); var awaitedType = checkAwaitedType(exprType, node, ts.Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member); if (promisedType) { // If the function has a return type, but promisedType is // undefined, an error will be reported in checkAsyncFunctionReturnType // so we don't need to report one here. checkTypeAssignableTo(awaitedType, promisedType, node); } } else { checkTypeAssignableTo(exprType, returnType, node); } } } else if (func.kind !== 153 /* Constructor */ && compilerOptions.noImplicitReturns && !isUnwrappedReturnTypeVoidOrAny(func, returnType)) { // The function has a return type, but the return statement doesn't have an expression. error(node, ts.Diagnostics.Not_all_code_paths_return_a_value); } } } function checkWithStatement(node) { // Grammar checking for withStatement if (!checkGrammarStatementInAmbientContext(node)) { if (node.flags & 16384 /* AwaitContext */) { grammarErrorOnFirstToken(node, ts.Diagnostics.with_statements_are_not_allowed_in_an_async_function_block); } } checkExpression(node.expression); var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var start = ts.getSpanOfTokenAtPosition(sourceFile, node.pos).start; var end = node.statement.pos; grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.The_with_statement_is_not_supported_All_symbols_in_a_with_block_will_have_type_any); } } function checkSwitchStatement(node) { // Grammar checking checkGrammarStatementInAmbientContext(node); var firstDefaultClause; var hasDuplicateDefaultClause = false; var expressionType = checkExpression(node.expression); var expressionIsLiteral = isLiteralType(expressionType); ts.forEach(node.caseBlock.clauses, function (clause) { // Grammar check for duplicate default clauses, skip if we already report duplicate default clause if (clause.kind === 262 /* 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 === 261 /* CaseClause */) { var caseClause = clause; // TypeScript 1.0 spec (April 2014): 5.9 // In a 'switch' statement, each 'case' expression must be of a type that is comparable // to or from the type of the 'switch' expression. var caseType = checkExpression(caseClause.expression); var caseIsLiteral = isLiteralType(caseType); var comparedExpressionType = expressionType; if (!caseIsLiteral || !expressionIsLiteral) { caseType = caseIsLiteral ? getBaseTypeOfLiteralType(caseType) : caseType; comparedExpressionType = getBaseTypeOfLiteralType(expressionType); } if (!isTypeEqualityComparableTo(comparedExpressionType, caseType)) { // expressionType is not comparable to caseType, try the reversed check and report errors if it fails checkTypeComparableTo(caseType, comparedExpressionType, caseClause.expression, /*headMessage*/ undefined); } } ts.forEach(clause.statements, checkSourceElement); }); if (node.caseBlock.locals) { registerForUnusedIdentifiersCheck(node.caseBlock); } } function checkLabeledStatement(node) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { ts.findAncestor(node.parent, function (current) { if (ts.isFunctionLike(current)) { return "quit"; } if (current.kind === 223 /* LabeledStatement */ && current.label.escapedText === node.label.escapedText) { var sourceFile = ts.getSourceFileOfNode(node); grammarErrorOnNode(node.label, ts.Diagnostics.Duplicate_label_0, ts.getTextOfNodeFromSourceText(sourceFile.text, node.label)); return true; } }); } // ensure that label is unique checkSourceElement(node.statement); } function checkThrowStatement(node) { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { if (node.expression === undefined) { grammarErrorAfterFirstToken(node, ts.Diagnostics.Line_break_not_permitted_here); } } if (node.expression) { checkExpression(node.expression); } } function checkTryStatement(node) { // Grammar checking checkGrammarStatementInAmbientContext(node); checkBlock(node.tryBlock); var catchClause = node.catchClause; if (catchClause) { // Grammar checking if (catchClause.variableDeclaration) { if (catchClause.variableDeclaration.type) { grammarErrorOnFirstToken(catchClause.variableDeclaration.type, ts.Diagnostics.Catch_clause_variable_cannot_have_a_type_annotation); } else if (catchClause.variableDeclaration.initializer) { grammarErrorOnFirstToken(catchClause.variableDeclaration.initializer, ts.Diagnostics.Catch_clause_variable_cannot_have_an_initializer); } else { var blockLocals_1 = catchClause.block.locals; if (blockLocals_1) { ts.forEachKey(catchClause.locals, function (caughtName) { var blockLocal = blockLocals_1.get(caughtName); if (blockLocal && (blockLocal.flags & 2 /* BlockScopedVariable */) !== 0) { grammarErrorOnNode(blockLocal.valueDeclaration, ts.Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName); } }); } } } checkBlock(catchClause.block); } if (node.finallyBlock) { checkBlock(node.finallyBlock); } } function checkIndexConstraints(type) { var declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, 1 /* Number */); var declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, 0 /* String */); var stringIndexType = getIndexTypeOfType(type, 0 /* String */); var numberIndexType = getIndexTypeOfType(type, 1 /* Number */); if (stringIndexType || numberIndexType) { ts.forEach(getPropertiesOfObjectType(type), function (prop) { var propType = getTypeOfSymbol(prop); checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */); checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, 1 /* Number */); }); if (ts.getObjectFlags(type) & 1 /* Class */ && ts.isClassLike(type.symbol.valueDeclaration)) { var classDeclaration = type.symbol.valueDeclaration; for (var _i = 0, _a = classDeclaration.members; _i < _a.length; _i++) { var member = _a[_i]; // Only process instance properties with computed names here. // Static properties cannot be in conflict with indexers, // and properties with literal names were already checked. if (!ts.hasModifier(member, 32 /* Static */) && hasNonBindableDynamicName(member)) { var symbol = getSymbolOfNode(member); var propType = getTypeOfSymbol(symbol); checkIndexConstraintForProperty(symbol, propType, type, declaredStringIndexer, stringIndexType, 0 /* String */); checkIndexConstraintForProperty(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 && (ts.getObjectFlags(type) & 2 /* Interface */)) { var someBaseTypeHasBothIndexers = ts.forEach(getBaseTypes(type), function (base) { return getIndexTypeOfType(base, 0 /* String */) && getIndexTypeOfType(base, 1 /* Number */); }); errorNode = someBaseTypeHasBothIndexers ? undefined : type.symbol.declarations[0]; } } if (errorNode && !isTypeAssignableTo(numberIndexType, stringIndexType)) { error(errorNode, ts.Diagnostics.Numeric_index_type_0_is_not_assignable_to_string_index_type_1, typeToString(numberIndexType), typeToString(stringIndexType)); } function checkIndexConstraintForProperty(prop, propertyType, containingType, indexDeclaration, indexType, indexKind) { if (!indexType) { return; } var propDeclaration = prop.valueDeclaration; // index is numeric and property name is not valid numeric literal if (indexKind === 1 /* Number */ && !(propDeclaration ? isNumericName(ts.getNameOfDeclaration(propDeclaration)) : isNumericLiteralName(prop.escapedName))) { return; } // perform property check if property or indexer is declared in 'type' // this allows us to rule out cases when both property and indexer are inherited from the base class var errorNode; if (propDeclaration && (propDeclaration.kind === 195 /* BinaryExpression */ || ts.getNameOfDeclaration(propDeclaration).kind === 145 /* ComputedPropertyName */ || prop.parent === containingType.symbol)) { errorNode = propDeclaration; } else if (indexDeclaration) { errorNode = indexDeclaration; } else if (ts.getObjectFlags(containingType) & 2 /* Interface */) { // for interfaces property and indexer might be inherited from different bases // check if any base class already has both property and indexer. // check should be performed only if 'type' is the first type that brings property\indexer together var someBaseClassHasBothPropertyAndIndexer = ts.forEach(getBaseTypes(containingType), function (base) { return getPropertyOfObjectType(base, prop.escapedName) && getIndexTypeOfType(base, indexKind); }); errorNode = someBaseClassHasBothPropertyAndIndexer ? undefined : containingType.symbol.declarations[0]; } if (errorNode && !isTypeAssignableTo(propertyType, indexType)) { var errorMessage = indexKind === 0 /* String */ ? ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_string_index_type_2 : ts.Diagnostics.Property_0_of_type_1_is_not_assignable_to_numeric_index_type_2; error(errorNode, errorMessage, symbolToString(prop), typeToString(propertyType), typeToString(indexType)); } } } function checkTypeNameIsReserved(name, message) { // TS 1.0 spec (April 2014): 3.6.1 // The predefined type keywords are reserved and cannot be used as names of user defined types. switch (name.escapedText) { case "any": case "number": case "boolean": case "string": case "symbol": case "void": case "object": error(name, message, name.escapedText); } } /** * Check each type parameter and check that type parameters have no duplicate type parameter declarations */ function checkTypeParameters(typeParameterDeclarations) { if (typeParameterDeclarations) { var seenDefault = false; for (var i = 0; i < typeParameterDeclarations.length; i++) { var node = typeParameterDeclarations[i]; checkTypeParameter(node); if (produceDiagnostics) { if (node.default) { seenDefault = true; } else if (seenDefault) { error(node, ts.Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters); } for (var j = 0; j < i; j++) { if (typeParameterDeclarations[j].symbol === node.symbol) { error(node.name, ts.Diagnostics.Duplicate_identifier_0, ts.declarationNameToString(node.name)); } } } } } } /** Check that type parameter lists are identical across multiple declarations */ function checkTypeParameterListsIdentical(symbol) { if (symbol.declarations.length === 1) { return; } var links = getSymbolLinks(symbol); if (!links.typeParametersChecked) { links.typeParametersChecked = true; var declarations = getClassOrInterfaceDeclarationsOfSymbol(symbol); if (declarations.length <= 1) { return; } var type = getDeclaredTypeOfSymbol(symbol); if (!areTypeParametersIdentical(declarations, type.localTypeParameters)) { // Report an error on every conflicting declaration. var name = symbolToString(symbol); for (var _i = 0, declarations_5 = declarations; _i < declarations_5.length; _i++) { var declaration = declarations_5[_i]; error(declaration.name, ts.Diagnostics.All_declarations_of_0_must_have_identical_type_parameters, name); } } } } function areTypeParametersIdentical(declarations, typeParameters) { var maxTypeArgumentCount = ts.length(typeParameters); var minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); for (var _i = 0, declarations_6 = declarations; _i < declarations_6.length; _i++) { var declaration = declarations_6[_i]; // If this declaration has too few or too many type parameters, we report an error var numTypeParameters = ts.length(declaration.typeParameters); if (numTypeParameters < minTypeArgumentCount || numTypeParameters > maxTypeArgumentCount) { return false; } for (var i = 0; i < numTypeParameters; i++) { var source = declaration.typeParameters[i]; var target = typeParameters[i]; // If the type parameter node does not have the same as the resolved type // parameter at this position, we report an error. if (source.name.escapedText !== target.symbol.escapedName) { return false; } // If the type parameter node does not have an identical constraint as the resolved // type parameter at this position, we report an error. var sourceConstraint = source.constraint && getTypeFromTypeNode(source.constraint); var targetConstraint = getConstraintFromTypeParameter(target); if ((sourceConstraint || targetConstraint) && (!sourceConstraint || !targetConstraint || !isTypeIdenticalTo(sourceConstraint, targetConstraint))) { return false; } // If the type parameter node has a default and it is not identical to the default // for the type parameter at this position, we report an error. var sourceDefault = source.default && getTypeFromTypeNode(source.default); var targetDefault = getDefaultFromTypeParameter(target); if (sourceDefault && targetDefault && !isTypeIdenticalTo(sourceDefault, targetDefault)) { return false; } } } return true; } function checkClassExpression(node) { checkClassLikeDeclaration(node); checkNodeDeferred(node); return getTypeOfSymbol(getSymbolOfNode(node)); } function checkClassExpressionDeferred(node) { ts.forEach(node.members, checkSourceElement); registerForUnusedIdentifiersCheck(node); } function checkClassDeclaration(node) { if (!node.name && !ts.hasModifier(node, 512 /* Default */)) { grammarErrorOnFirstToken(node, ts.Diagnostics.A_class_declaration_without_the_default_modifier_must_have_a_name); } checkClassLikeDeclaration(node); ts.forEach(node.members, checkSourceElement); registerForUnusedIdentifiersCheck(node); } function checkClassLikeDeclaration(node) { checkGrammarClassLikeDeclaration(node); checkDecorators(node); if (node.name) { checkTypeNameIsReserved(node.name, ts.Diagnostics.Class_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } checkTypeParameters(node.typeParameters); checkExportsOnMergedDeclarations(node); var symbol = getSymbolOfNode(node); var type = getDeclaredTypeOfSymbol(symbol); var typeWithThis = getTypeWithThisArgument(type); var staticType = getTypeOfSymbol(symbol); checkTypeParameterListsIdentical(symbol); checkClassForDuplicateDeclarations(node); // Only check for reserved static identifiers on non-ambient context. if (!(node.flags & 2097152 /* Ambient */)) { checkClassForStaticPropertyNameConflicts(node); } var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); if (baseTypeNode) { if (languageVersion < 2 /* ES2015 */) { checkExternalEmitHelpers(baseTypeNode.parent, 1 /* Extends */); } var baseTypes = getBaseTypes(type); if (baseTypes.length && produceDiagnostics) { var baseType_1 = baseTypes[0]; var baseConstructorType = getBaseConstructorTypeOfClass(type); var staticBaseType = getApparentType(baseConstructorType); checkBaseTypeAccessibility(staticBaseType, baseTypeNode); checkSourceElement(baseTypeNode.expression); if (ts.some(baseTypeNode.typeArguments)) { ts.forEach(baseTypeNode.typeArguments, checkSourceElement); for (var _i = 0, _a = getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); _i < _a.length; _i++) { var constructor = _a[_i]; if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) { break; } } } checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType_1, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_extends_base_class_1); checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, ts.Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); if (baseConstructorType.flags & 1081344 /* TypeVariable */ && !isMixinConstructorType(staticType)) { error(node.name || node, ts.Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); } if (!(staticBaseType.symbol && staticBaseType.symbol.flags & 32 /* Class */) && !(baseConstructorType.flags & 1081344 /* TypeVariable */)) { // When the static base type is a "class-like" constructor function (but not actually a class), we verify // that all instantiated base constructor signatures return the same type. We can simply compare the type // references (as opposed to checking the structure of the types) because elsewhere we have already checked // that the base type is a class or interface type (and not, for example, an anonymous object type). var constructors = getInstantiatedConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments, baseTypeNode); if (ts.forEach(constructors, function (sig) { return getReturnTypeOfSignature(sig) !== baseType_1; })) { error(baseTypeNode.expression, ts.Diagnostics.Base_constructors_must_all_have_the_same_return_type); } } checkKindsOfPropertyMemberOverrides(type, baseType_1); } } var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(node); if (implementedTypeNodes) { for (var _b = 0, implementedTypeNodes_1 = implementedTypeNodes; _b < implementedTypeNodes_1.length; _b++) { var typeRefNode = implementedTypeNodes_1[_b]; if (!ts.isEntityNameExpression(typeRefNode.expression)) { error(typeRefNode.expression, ts.Diagnostics.A_class_can_only_implement_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(typeRefNode); if (produceDiagnostics) { var t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { if (isValidBaseType(t)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, ts.Diagnostics.Class_0_incorrectly_implements_interface_1); } else { error(typeRefNode, ts.Diagnostics.A_class_may_only_implement_another_class_or_interface); } } } } } if (produceDiagnostics) { checkIndexConstraints(type); checkTypeForDuplicateIndexSignatures(node); checkPropertyInitialization(node); } } function checkBaseTypeAccessibility(type, node) { var signatures = getSignaturesOfType(type, 1 /* Construct */); if (signatures.length) { var declaration = signatures[0].declaration; if (declaration && ts.hasModifier(declaration, 8 /* Private */)) { var typeClassDeclaration = ts.getClassLikeDeclarationOfSymbol(type.symbol); if (!isNodeWithinClass(node, typeClassDeclaration)) { error(node, ts.Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol)); } } } } function getTargetSymbol(s) { // if symbol is instantiated its flags are not copied from the 'target' // so we'll need to get back original 'target' symbol to work with correct set of flags return ts.getCheckFlags(s) & 1 /* Instantiated */ ? s.target : s; } function getClassOrInterfaceDeclarationsOfSymbol(symbol) { return ts.filter(symbol.declarations, function (d) { return d.kind === 230 /* ClassDeclaration */ || d.kind === 231 /* InterfaceDeclaration */; }); } function checkKindsOfPropertyMemberOverrides(type, baseType) { // TypeScript 1.0 spec (April 2014): 8.2.3 // A derived class inherits all members from its base class it doesn't override. // Inheritance means that a derived class implicitly contains all non - overridden members of the base class. // Both public and private property members are inherited, but only public property members can be overridden. // A property member in a derived class is said to override a property member in a base class // when the derived class property member has the same name and kind(instance or static) // as the base class property member. // The type of an overriding property member must be assignable(section 3.8.4) // to the type of the overridden property member, or otherwise a compile - time error occurs. // Base class instance member functions can be overridden by derived class instance member functions, // but not by other kinds of members. // Base class instance member variables and accessors can be overridden by // derived class instance member variables and accessors, but not by other kinds of members. // NOTE: assignability is checked in checkClassDeclaration var baseProperties = getPropertiesOfType(baseType); for (var _i = 0, baseProperties_1 = baseProperties; _i < baseProperties_1.length; _i++) { var baseProperty = baseProperties_1[_i]; var base = getTargetSymbol(baseProperty); if (base.flags & 4194304 /* Prototype */) { continue; } var derived = getTargetSymbol(getPropertyOfObjectType(type, base.escapedName)); var baseDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(base); ts.Debug.assert(!!derived, "derived should point to something, even if it is the base class' declaration."); if (derived) { // In order to resolve whether the inherited method was overridden in the base class or not, // we compare the Symbols obtained. Since getTargetSymbol returns the symbol on the *uninstantiated* // type declaration, derived and base resolve to the same symbol even in the case of generic classes. if (derived === base) { // derived class inherits base without override/redeclaration var derivedClassDecl = ts.getClassLikeDeclarationOfSymbol(type.symbol); // It is an error to inherit an abstract member without implementing it or being declared abstract. // If there is no declaration for the derived class (as in the case of class expressions), // then the class cannot be declared abstract. if (baseDeclarationFlags & 128 /* Abstract */ && (!derivedClassDecl || !ts.hasModifier(derivedClassDecl, 128 /* Abstract */))) { if (derivedClassDecl.kind === 200 /* ClassExpression */) { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1, symbolToString(baseProperty), typeToString(baseType)); } else { error(derivedClassDecl, ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2, typeToString(type), symbolToString(baseProperty), typeToString(baseType)); } } } else { // derived overrides base. var derivedDeclarationFlags = ts.getDeclarationModifierFlagsFromSymbol(derived); if (baseDeclarationFlags & 8 /* Private */ || derivedDeclarationFlags & 8 /* Private */) { // either base or derived property is private - not override, skip it continue; } if (isMethodLike(base) && isMethodLike(derived) || base.flags & 98308 /* PropertyOrAccessor */ && derived.flags & 98308 /* PropertyOrAccessor */) { // method is overridden with method or property/accessor is overridden with property/accessor - correct case continue; } var errorMessage = void 0; if (isMethodLike(base)) { if (derived.flags & 98304 /* Accessor */) { errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_accessor; } else { errorMessage = ts.Diagnostics.Class_0_defines_instance_member_function_1_but_extended_class_2_defines_it_as_instance_member_property; } } else if (base.flags & 4 /* Property */) { errorMessage = ts.Diagnostics.Class_0_defines_instance_member_property_1_but_extended_class_2_defines_it_as_instance_member_function; } else { errorMessage = ts.Diagnostics.Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function; } error(ts.getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, typeToString(baseType), symbolToString(base), typeToString(type)); } } } } function checkInheritedPropertiesAreIdentical(type, typeNode) { var baseTypes = getBaseTypes(type); if (baseTypes.length < 2) { return true; } var seen = ts.createUnderscoreEscapedMap(); ts.forEach(resolveDeclaredMembers(type).declaredProperties, function (p) { seen.set(p.escapedName, { prop: p, containingType: type }); }); var ok = true; for (var _i = 0, baseTypes_2 = baseTypes; _i < baseTypes_2.length; _i++) { var base = baseTypes_2[_i]; var properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); for (var _a = 0, properties_8 = properties; _a < properties_8.length; _a++) { var prop = properties_8[_a]; var existing = seen.get(prop.escapedName); if (!existing) { seen.set(prop.escapedName, { prop: prop, containingType: base }); } else { var isInheritedProperty = existing.containingType !== type; if (isInheritedProperty && !isPropertyIdenticalTo(existing.prop, prop)) { ok = false; var typeName1 = typeToString(existing.containingType); var typeName2 = typeToString(base); var errorInfo = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Named_property_0_of_types_1_and_2_are_not_identical, symbolToString(prop), typeName1, typeName2); errorInfo = ts.chainDiagnosticMessages(errorInfo, ts.Diagnostics.Interface_0_cannot_simultaneously_extend_types_1_and_2, typeToString(type), typeName1, typeName2); diagnostics.add(ts.createDiagnosticForNodeFromMessageChain(typeNode, errorInfo)); } } } } return ok; } function checkPropertyInitialization(node) { if (!strictNullChecks || !strictPropertyInitialization || node.flags & 2097152 /* Ambient */) { return; } var constructor = findConstructorDeclaration(node); for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; if (isInstancePropertyWithoutInitializer(member)) { var propName = member.name; if (ts.isIdentifier(propName)) { var type = getTypeOfSymbol(getSymbolOfNode(member)); if (!(type.flags & 1 /* Any */ || getFalsyFlags(type) & 4096 /* Undefined */)) { if (!constructor || !isPropertyInitializedInConstructor(propName, type, constructor)) { error(member.name, ts.Diagnostics.Property_0_has_no_initializer_and_is_not_definitely_assigned_in_the_constructor, ts.declarationNameToString(propName)); } } } } } } function isInstancePropertyWithoutInitializer(node) { return node.kind === 150 /* PropertyDeclaration */ && !ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */) && !node.exclamationToken && !node.initializer; } function isPropertyInitializedInConstructor(propName, propType, constructor) { var reference = ts.createPropertyAccess(ts.createThis(), propName); reference.flowNode = constructor.returnFlowNode; var flowType = getFlowTypeOfReference(reference, propType, getOptionalType(propType)); return !(getFalsyFlags(flowType) & 4096 /* Undefined */); } function checkInterfaceDeclaration(node) { // Grammar checking if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node); checkTypeParameters(node.typeParameters); if (produceDiagnostics) { checkTypeNameIsReserved(node.name, ts.Diagnostics.Interface_name_cannot_be_0); checkExportsOnMergedDeclarations(node); var symbol = getSymbolOfNode(node); checkTypeParameterListsIdentical(symbol); // Only check this symbol once var firstInterfaceDecl = ts.getDeclarationOfKind(symbol, 231 /* InterfaceDeclaration */); if (node === firstInterfaceDecl) { var type = getDeclaredTypeOfSymbol(symbol); var typeWithThis = getTypeWithThisArgument(type); // run subsequent checks only if first set succeeded if (checkInheritedPropertiesAreIdentical(type, node.name)) { for (var _i = 0, _a = getBaseTypes(type); _i < _a.length; _i++) { var baseType = _a[_i]; checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(baseType, type.thisType), node.name, ts.Diagnostics.Interface_0_incorrectly_extends_interface_1); } checkIndexConstraints(type); } } checkObjectTypeForDuplicateDeclarations(node); } ts.forEach(ts.getInterfaceBaseTypeNodes(node), function (heritageElement) { if (!ts.isEntityNameExpression(heritageElement.expression)) { error(heritageElement.expression, ts.Diagnostics.An_interface_can_only_extend_an_identifier_Slashqualified_name_with_optional_type_arguments); } checkTypeReferenceNode(heritageElement); }); ts.forEach(node.members, checkSourceElement); if (produceDiagnostics) { checkTypeForDuplicateIndexSignatures(node); registerForUnusedIdentifiersCheck(node); } } function checkTypeAliasDeclaration(node) { // Grammar checking checkGrammarDecoratorsAndModifiers(node); checkTypeNameIsReserved(node.name, ts.Diagnostics.Type_alias_name_cannot_be_0); checkTypeParameters(node.typeParameters); checkSourceElement(node.type); registerForUnusedIdentifiersCheck(node); } function computeEnumMemberValues(node) { var nodeLinks = getNodeLinks(node); if (!(nodeLinks.flags & 16384 /* EnumValuesComputed */)) { nodeLinks.flags |= 16384 /* EnumValuesComputed */; var autoValue = 0; for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; var value = computeMemberValue(member, autoValue); getNodeLinks(member).enumMemberValue = value; autoValue = typeof value === "number" ? value + 1 : undefined; } } } function computeMemberValue(member, autoValue) { if (isComputedNonLiteralName(member.name)) { error(member.name, ts.Diagnostics.Computed_property_names_are_not_allowed_in_enums); } else { var text = ts.getTextOfPropertyName(member.name); if (isNumericLiteralName(text) && !isInfinityOrNaNString(text)) { error(member.name, ts.Diagnostics.An_enum_member_cannot_have_a_numeric_name); } } if (member.initializer) { return computeConstantValue(member); } // In ambient enum declarations that specify no const modifier, enum member declarations that omit // a value are considered computed members (as opposed to having auto-incremented values). if (member.parent.flags & 2097152 /* Ambient */ && !ts.isConst(member.parent)) { return undefined; } // If the member declaration specifies no value, the member is considered a constant enum member. // If the member is the first member in the enum declaration, it is assigned the value zero. // Otherwise, it is assigned the value of the immediately preceding member plus one, and an error // occurs if the immediately preceding member is not a constant enum member. if (autoValue !== undefined) { return autoValue; } error(member.name, ts.Diagnostics.Enum_member_must_have_initializer); return undefined; } function computeConstantValue(member) { var enumKind = getEnumKind(getSymbolOfNode(member.parent)); var isConstEnum = ts.isConst(member.parent); var initializer = member.initializer; var value = enumKind === 1 /* Literal */ && !isLiteralEnumMember(member) ? undefined : evaluate(initializer); if (value !== undefined) { if (isConstEnum && typeof value === "number" && !isFinite(value)) { error(initializer, isNaN(value) ? ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN : ts.Diagnostics.const_enum_member_initializer_was_evaluated_to_a_non_finite_value); } } else if (enumKind === 1 /* Literal */) { error(initializer, ts.Diagnostics.Computed_values_are_not_permitted_in_an_enum_with_string_valued_members); return 0; } else if (isConstEnum) { error(initializer, ts.Diagnostics.In_const_enum_declarations_member_initializer_must_be_constant_expression); } else if (member.parent.flags & 2097152 /* 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), getDeclaredTypeOfSymbol(getSymbolOfNode(member.parent)), initializer, /*headMessage*/ undefined); } return value; function evaluate(expr) { switch (expr.kind) { case 193 /* PrefixUnaryExpression */: var value_1 = evaluate(expr.operand); if (typeof value_1 === "number") { switch (expr.operator) { case 37 /* PlusToken */: return value_1; case 38 /* MinusToken */: return -value_1; case 52 /* TildeToken */: return ~value_1; } } break; case 195 /* BinaryExpression */: var left = evaluate(expr.left); var right = evaluate(expr.right); if (typeof left === "number" && typeof right === "number") { switch (expr.operatorToken.kind) { case 49 /* BarToken */: return left | right; case 48 /* AmpersandToken */: return left & right; case 46 /* GreaterThanGreaterThanToken */: return left >> right; case 47 /* GreaterThanGreaterThanGreaterThanToken */: return left >>> right; case 45 /* LessThanLessThanToken */: return left << right; case 50 /* CaretToken */: return left ^ right; case 39 /* AsteriskToken */: return left * right; case 41 /* SlashToken */: return left / right; case 37 /* PlusToken */: return left + right; case 38 /* MinusToken */: return left - right; case 42 /* PercentToken */: return left % right; } } break; case 9 /* StringLiteral */: return expr.text; case 8 /* NumericLiteral */: checkGrammarNumericLiteral(expr); return +expr.text; case 186 /* ParenthesizedExpression */: return evaluate(expr.expression); case 71 /* Identifier */: return ts.nodeIsMissing(expr) ? 0 : evaluateEnumMember(expr, getSymbolOfNode(member.parent), expr.escapedText); case 181 /* ElementAccessExpression */: case 180 /* PropertyAccessExpression */: var ex = expr; if (isConstantMemberAccess(ex)) { var type = getTypeOfExpression(ex.expression); if (type.symbol && type.symbol.flags & 384 /* Enum */) { var name = void 0; if (ex.kind === 180 /* PropertyAccessExpression */) { name = ex.name.escapedText; } else { var argument = ex.argumentExpression; ts.Debug.assert(ts.isLiteralExpression(argument)); name = ts.escapeLeadingUnderscores(argument.text); } return evaluateEnumMember(expr, type.symbol, name); } } break; } return undefined; } function evaluateEnumMember(expr, enumSymbol, name) { var memberSymbol = enumSymbol.exports.get(name); if (memberSymbol) { var declaration = memberSymbol.valueDeclaration; if (declaration !== member) { if (isBlockScopedNameDeclaredBeforeUse(declaration, member)) { return getEnumMemberValue(declaration); } error(expr, ts.Diagnostics.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums); return 0; } } return undefined; } } function isConstantMemberAccess(node) { return node.kind === 71 /* Identifier */ || node.kind === 180 /* PropertyAccessExpression */ && isConstantMemberAccess(node.expression) || node.kind === 181 /* ElementAccessExpression */ && isConstantMemberAccess(node.expression) && node.argumentExpression.kind === 9 /* StringLiteral */; } function checkEnumDeclaration(node) { if (!produceDiagnostics) { return; } // Grammar checking checkGrammarDecoratorsAndModifiers(node); checkTypeNameIsReserved(node.name, ts.Diagnostics.Enum_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithCapturedNewTargetVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); var enumIsConst = ts.isConst(node); if (compilerOptions.isolatedModules && enumIsConst && node.flags & 2097152 /* Ambient */) { error(node.name, ts.Diagnostics.Ambient_const_enums_are_not_allowed_when_the_isolatedModules_flag_is_provided); } // Spec 2014 - Section 9.3: // It isn't possible for one enum declaration to continue the automatic numbering sequence of another, // and when an enum type has multiple declarations, only one declaration is permitted to omit a value // for the first member. // // Only perform this check once per symbol var enumSymbol = getSymbolOfNode(node); var firstDeclaration = ts.getDeclarationOfKind(enumSymbol, node.kind); if (node === firstDeclaration) { if (enumSymbol.declarations.length > 1) { // check that const is placed\omitted on all enum declarations ts.forEach(enumSymbol.declarations, function (decl) { if (ts.isConstEnumDeclaration(decl) !== enumIsConst) { error(ts.getNameOfDeclaration(decl), ts.Diagnostics.Enum_declarations_must_all_be_const_or_non_const); } }); } var seenEnumMissingInitialInitializer_1 = false; ts.forEach(enumSymbol.declarations, function (declaration) { // return true if we hit a violation of the rule, false otherwise if (declaration.kind !== 233 /* EnumDeclaration */) { return false; } var enumDeclaration = declaration; if (!enumDeclaration.members.length) { return false; } var firstEnumMember = enumDeclaration.members[0]; if (!firstEnumMember.initializer) { if (seenEnumMissingInitialInitializer_1) { error(firstEnumMember.name, ts.Diagnostics.In_an_enum_with_multiple_declarations_only_one_declaration_can_omit_an_initializer_for_its_first_enum_element); } else { seenEnumMissingInitialInitializer_1 = true; } } }); } } function getFirstNonAmbientClassOrFunctionDeclaration(symbol) { var declarations = symbol.declarations; for (var _i = 0, declarations_7 = declarations; _i < declarations_7.length; _i++) { var declaration = declarations_7[_i]; if ((declaration.kind === 230 /* ClassDeclaration */ || (declaration.kind === 229 /* FunctionDeclaration */ && ts.nodeIsPresent(declaration.body))) && !(declaration.flags & 2097152 /* Ambient */)) { 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 = node.flags & 2097152 /* Ambient */; 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 (!checkGrammarDecoratorsAndModifiers(node)) { if (!inAmbientContext && node.name.kind === 9 /* StringLiteral */) { grammarErrorOnNode(node.name, ts.Diagnostics.Only_ambient_modules_can_use_quoted_names); } } if (ts.isIdentifier(node.name)) { checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); } checkExportsOnMergedDeclarations(node); var symbol = getSymbolOfNode(node); // The following checks only apply on a non-ambient instantiated module declaration. if (symbol.flags & 512 /* ValueModule */ && symbol.declarations.length > 1 && !inAmbientContext && isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules)) { var firstNonAmbientClassOrFunc = getFirstNonAmbientClassOrFunctionDeclaration(symbol); if (firstNonAmbientClassOrFunc) { if (ts.getSourceFileOfNode(node) !== ts.getSourceFileOfNode(firstNonAmbientClassOrFunc)) { error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_in_a_different_file_from_a_class_or_function_with_which_it_is_merged); } else if (node.pos < firstNonAmbientClassOrFunc.pos) { error(node.name, ts.Diagnostics.A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged); } } // if the module merges with a class declaration in the same lexical scope, // we need to track this to ensure the correct emit. var mergedClass = ts.getDeclarationOfKind(symbol, 230 /* ClassDeclaration */); if (mergedClass && inSameLexicalScope(node, mergedClass)) { getNodeLinks(node).flags |= 32768 /* LexicalModuleMergesWithClass */; } } if (isAmbientExternalModule) { if (ts.isExternalModuleAugmentation(node)) { // body of the augmentation should be checked for consistency only if augmentation was applied to its target (either global scope or module) // otherwise we'll be swamped in cascading errors. // We can detect if augmentation was applied using following rules: // - augmentation for a global scope is always applied // - augmentation for some external module is applied if symbol for augmentation is merged (it was combined with target module). var checkBody = isGlobalAugmentation || (getSymbolOfNode(node).flags & 33554432 /* Transient */); if (checkBody && node.body) { // body of ambient external module is always a module block for (var _i = 0, _a = node.body.statements; _i < _a.length; _i++) { var statement = _a[_i]; checkModuleAugmentationElement(statement, isGlobalAugmentation); } } } else if (isGlobalSourceFile(node.parent)) { if (isGlobalAugmentation) { error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); } else if (ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(node.name))) { error(node.name, ts.Diagnostics.Ambient_module_declaration_cannot_specify_relative_module_name); } } else { if (isGlobalAugmentation) { error(node.name, ts.Diagnostics.Augmentations_for_the_global_scope_can_only_be_directly_nested_in_external_modules_or_ambient_module_declarations); } else { // Node is not an augmentation and is not located on the script level. // This means that this is declaration of ambient module that is located in other module or namespace which is prohibited. error(node.name, ts.Diagnostics.Ambient_modules_cannot_be_nested_in_other_modules_or_namespaces); } } } } if (node.body) { checkSourceElement(node.body); if (!ts.isGlobalScopeAugmentation(node)) { registerForUnusedIdentifiersCheck(node); } } } function checkModuleAugmentationElement(node, isGlobalAugmentation) { switch (node.kind) { case 209 /* 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 244 /* ExportAssignment */: case 245 /* ExportDeclaration */: grammarErrorOnFirstToken(node, ts.Diagnostics.Exports_and_export_assignments_are_not_permitted_in_module_augmentations); break; case 238 /* ImportEqualsDeclaration */: case 239 /* ImportDeclaration */: grammarErrorOnFirstToken(node, ts.Diagnostics.Imports_are_not_permitted_in_module_augmentations_Consider_moving_them_to_the_enclosing_external_module); break; case 177 /* BindingElement */: case 227 /* VariableDeclaration */: var name = node.name; if (ts.isBindingPattern(name)) { for (var _b = 0, _c = name.elements; _b < _c.length; _b++) { var el = _c[_b]; // mark individual names in binding pattern checkModuleAugmentationElement(el, isGlobalAugmentation); } break; } // falls through case 230 /* ClassDeclaration */: case 233 /* EnumDeclaration */: case 229 /* FunctionDeclaration */: case 231 /* InterfaceDeclaration */: case 234 /* ModuleDeclaration */: case 232 /* TypeAliasDeclaration */: if (isGlobalAugmentation) { return; } var symbol = getSymbolOfNode(node); if (symbol) { // module augmentations cannot introduce new names on the top level scope of the module // this is done it two steps // 1. quick check - if symbol for node is not merged - this is local symbol to this augmentation - report error // 2. main check - report error if value declaration of the parent symbol is module augmentation) var reportError = !(symbol.flags & 33554432 /* Transient */); if (!reportError) { // symbol should not originate in augmentation reportError = ts.isExternalModuleAugmentation(symbol.parent.declarations[0]); } } break; } } function getFirstIdentifier(node) { switch (node.kind) { case 71 /* Identifier */: return node; case 144 /* QualifiedName */: do { node = node.left; } while (node.kind !== 71 /* Identifier */); return node; case 180 /* PropertyAccessExpression */: do { node = node.expression; } while (node.kind !== 71 /* Identifier */); return node; } } function checkExternalImportOrExportDeclaration(node) { var moduleName = ts.getExternalModuleName(node); if (!ts.nodeIsMissing(moduleName) && moduleName.kind !== 9 /* StringLiteral */) { error(moduleName, ts.Diagnostics.String_literal_expected); return false; } var inAmbientExternalModule = node.parent.kind === 235 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent); if (node.parent.kind !== 269 /* SourceFile */ && !inAmbientExternalModule) { error(moduleName, node.kind === 245 /* ExportDeclaration */ ? ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace : ts.Diagnostics.Import_declarations_in_a_namespace_cannot_reference_a_module); return false; } if (inAmbientExternalModule && ts.isExternalModuleNameRelative(ts.getTextOfIdentifierOrLiteral(moduleName))) { // we have already reported errors on top level imports\exports in external module augmentations in checkModuleDeclaration // no need to do this again. if (!isTopLevelInExternalModuleAugmentation(node)) { // TypeScript 1.0 spec (April 2013): 12.1.6 // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference // other external modules only through top - level external module names. // Relative external module names are not permitted. error(node, ts.Diagnostics.Import_or_export_declaration_in_an_ambient_module_declaration_cannot_reference_module_through_relative_module_name); return false; } } return true; } function checkAliasSymbol(node) { var symbol = getSymbolOfNode(node); var target = resolveAlias(symbol); if (target !== unknownSymbol) { // For external modules symbol represent local symbol for an alias. // This local symbol will merge any other local declarations (excluding other aliases) // and symbol.flags will contains combined representation for all merged declaration. // Based on symbol.flags we can compute a set of excluded meanings (meaning that resolved alias should not have, // otherwise it will conflict with some local declaration). Note that in addition to normal flags we include matching SymbolFlags.Export* // in order to prevent collisions with declarations that were exported from the current module (they still contribute to local names). var excludedMeanings = (symbol.flags & (107455 /* Value */ | 1048576 /* ExportValue */) ? 107455 /* Value */ : 0) | (symbol.flags & 793064 /* Type */ ? 793064 /* Type */ : 0) | (symbol.flags & 1920 /* Namespace */ ? 1920 /* Namespace */ : 0); if (target.flags & excludedMeanings) { var message = node.kind === 247 /* ExportSpecifier */ ? ts.Diagnostics.Export_declaration_conflicts_with_exported_declaration_of_0 : ts.Diagnostics.Import_declaration_conflicts_with_local_declaration_of_0; error(node, message, symbolToString(symbol)); } // Don't allow to re-export something with no value side when `--isolatedModules` is set. if (compilerOptions.isolatedModules && node.kind === 247 /* ExportSpecifier */ && !(target.flags & 107455 /* Value */) && !(node.flags & 2097152 /* Ambient */)) { error(node, ts.Diagnostics.Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided); } } } function checkImportBinding(node) { checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); checkCollisionWithGlobalPromiseInGeneratedCode(node, node.name); checkAliasSymbol(node); } function checkImportDeclaration(node) { if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_import_declaration_can_only_be_used_in_a_namespace_or_module)) { // If we hit an import declaration in an illegal context, just bail out to avoid cascading errors. return; } if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_import_declaration_cannot_have_modifiers); } if (checkExternalImportOrExportDeclaration(node)) { var importClause = node.importClause; if (importClause) { if (importClause.name) { checkImportBinding(importClause); } if (importClause.namedBindings) { if (importClause.namedBindings.kind === 241 /* 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; } checkGrammarDecoratorsAndModifiers(node); if (ts.isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) { checkImportBinding(node); if (ts.hasModifier(node, 1 /* Export */)) { markExportAsReferenced(node); } if (node.moduleReference.kind !== 249 /* ExternalModuleReference */) { var target = resolveAlias(getSymbolOfNode(node)); if (target !== unknownSymbol) { if (target.flags & 107455 /* Value */) { // Target is a value symbol, check that it is not hidden by a local declaration with the same name var moduleName = getFirstIdentifier(node.moduleReference); if (!(resolveEntityName(moduleName, 107455 /* Value */ | 1920 /* Namespace */).flags & 1920 /* Namespace */)) { error(moduleName, ts.Diagnostics.Module_0_is_hidden_by_a_local_declaration_with_the_same_name, ts.declarationNameToString(moduleName)); } } if (target.flags & 793064 /* Type */) { checkTypeNameIsReserved(node.name, ts.Diagnostics.Import_name_cannot_be_0); } } } else { if (modulekind >= ts.ModuleKind.ES2015 && !(node.flags & 2097152 /* Ambient */)) { // Import equals declaration is deprecated in es6 or above grammarErrorOnNode(node, ts.Diagnostics.Import_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_import_Asterisk_as_ns_from_mod_import_a_from_mod_import_d_from_mod_or_another_module_format_instead); } } } } function checkExportDeclaration(node) { if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_declaration_can_only_be_used_in_a_module)) { // If we hit an export in an illegal context, just bail out to avoid cascading errors. return; } if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_declaration_cannot_have_modifiers); } if (!node.moduleSpecifier || checkExternalImportOrExportDeclaration(node)) { if (node.exportClause) { // export { x, y } // export { x, y } from "foo" ts.forEach(node.exportClause.elements, checkExportSpecifier); var inAmbientExternalModule = node.parent.kind === 235 /* ModuleBlock */ && ts.isAmbientModule(node.parent.parent); var inAmbientNamespaceDeclaration = !inAmbientExternalModule && node.parent.kind === 235 /* ModuleBlock */ && !node.moduleSpecifier && node.flags & 2097152 /* Ambient */; if (node.parent.kind !== 269 /* SourceFile */ && !inAmbientExternalModule && !inAmbientNamespaceDeclaration) { error(node, ts.Diagnostics.Export_declarations_are_not_permitted_in_a_namespace); } } else { // export * from "foo" var moduleSymbol = resolveExternalModuleName(node, node.moduleSpecifier); if (moduleSymbol && hasExportAssignmentSymbol(moduleSymbol)) { error(node.moduleSpecifier, ts.Diagnostics.Module_0_uses_export_and_cannot_be_used_with_export_Asterisk, symbolToString(moduleSymbol)); } if (modulekind !== ts.ModuleKind.System && modulekind !== ts.ModuleKind.ES2015 && modulekind !== ts.ModuleKind.ESNext) { checkExternalEmitHelpers(node, 32768 /* ExportStar */); } } } } function checkGrammarModuleElementContext(node, errorMessage) { var isInAppropriateContext = node.parent.kind === 269 /* SourceFile */ || node.parent.kind === 235 /* ModuleBlock */ || node.parent.kind === 234 /* ModuleDeclaration */; if (!isInAppropriateContext) { grammarErrorOnFirstToken(node, errorMessage); } return !isInAppropriateContext; } function checkExportSpecifier(node) { checkAliasSymbol(node); if (compilerOptions.declaration) { collectLinkedAliases(node.propertyName || node.name, /*setVisibility*/ true); } if (!node.parent.parent.moduleSpecifier) { var exportedName = node.propertyName || node.name; // find immediate value referenced by exported name (SymbolFlags.Alias is set so we don't chase down aliases) var symbol = resolveName(exportedName, exportedName.escapedText, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); if (symbol && (symbol === undefinedSymbol || isGlobalSourceFile(getDeclarationContainer(symbol.declarations[0])))) { error(exportedName, ts.Diagnostics.Cannot_export_0_Only_local_declarations_can_be_exported_from_a_module, ts.idText(exportedName)); } else { markExportAsReferenced(node); } } } function checkExportAssignment(node) { if (checkGrammarModuleElementContext(node, ts.Diagnostics.An_export_assignment_can_only_be_used_in_a_module)) { // If we hit an export assignment in an illegal context, just bail out to avoid cascading errors. return; } var container = node.parent.kind === 269 /* SourceFile */ ? node.parent : node.parent.parent; if (container.kind === 234 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) { if (node.isExportEquals) { error(node, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_namespace); } else { error(node, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); } return; } // Grammar checking if (!checkGrammarDecoratorsAndModifiers(node) && ts.hasModifiers(node)) { grammarErrorOnFirstToken(node, ts.Diagnostics.An_export_assignment_cannot_have_modifiers); } if (node.expression.kind === 71 /* Identifier */) { markExportAsReferenced(node); if (compilerOptions.declaration) { collectLinkedAliases(node.expression, /*setVisibility*/ true); } } else { checkExpressionCached(node.expression); } checkExternalModuleExports(container); if ((node.flags & 2097152 /* Ambient */) && !ts.isEntityNameExpression(node.expression)) { grammarErrorOnNode(node.expression, ts.Diagnostics.The_expression_of_an_export_assignment_must_be_an_identifier_or_qualified_name_in_an_ambient_context); } if (node.isExportEquals && !(node.flags & 2097152 /* Ambient */)) { if (modulekind >= ts.ModuleKind.ES2015) { // export assignment is not supported in es6 modules grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_cannot_be_used_when_targeting_ECMAScript_modules_Consider_using_export_default_or_another_module_format_instead); } else if (modulekind === ts.ModuleKind.System) { // system modules does not support export assignment grammarErrorOnNode(node, ts.Diagnostics.Export_assignment_is_not_supported_when_module_flag_is_system); } } } function hasExportedMembers(moduleSymbol) { return ts.forEachEntry(moduleSymbol.exports, function (_, id) { return id !== "export="; }); } function checkExternalModuleExports(node) { var moduleSymbol = getSymbolOfNode(node); var links = getSymbolLinks(moduleSymbol); if (!links.exportsChecked) { var exportEqualsSymbol = moduleSymbol.exports.get("export="); if (exportEqualsSymbol && hasExportedMembers(moduleSymbol)) { var declaration = getDeclarationOfAliasSymbol(exportEqualsSymbol) || exportEqualsSymbol.valueDeclaration; if (!isTopLevelInExternalModuleAugmentation(declaration)) { error(declaration, ts.Diagnostics.An_export_assignment_cannot_be_used_in_a_module_with_other_exported_elements); } } // Checks for export * conflicts var exports = getExportsOfModule(moduleSymbol); if (exports) { exports.forEach(function (_a, id) { var declarations = _a.declarations, flags = _a.flags; if (id === "__export") { return; } // ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries. // (TS Exceptions: namespaces, function overloads, enums, and interfaces) if (flags & (1920 /* Namespace */ | 64 /* Interface */ | 384 /* Enum */)) { return; } var exportedDeclarationsCount = ts.countWhere(declarations, isNotOverloadAndNotAccessor); if (flags & 524288 /* TypeAlias */ && exportedDeclarationsCount <= 2) { // it is legal to merge type alias with other values // so count should be either 1 (just type alias) or 2 (type alias + merged value) return; } if (exportedDeclarationsCount > 1) { for (var _i = 0, declarations_8 = declarations; _i < declarations_8.length; _i++) { var declaration = declarations_8[_i]; if (isNotOverload(declaration)) { diagnostics.add(ts.createDiagnosticForNode(declaration, ts.Diagnostics.Cannot_redeclare_exported_variable_0, ts.unescapeLeadingUnderscores(id))); } } } }); } links.exportsChecked = true; } } function isNotAccessor(declaration) { // Accessors check for their own matching duplicates, and in contexts where they are valid, there are already duplicate identifier checks return !ts.isAccessor(declaration); } function isNotOverload(declaration) { return (declaration.kind !== 229 /* FunctionDeclaration */ && declaration.kind !== 152 /* MethodDeclaration */) || !!declaration.body; } function checkSourceElement(node) { if (!node) { return; } if (ts.isInJavaScriptFile(node) && node.jsDoc) { for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) { var tags = _a[_i].tags; ts.forEach(tags, checkSourceElement); } } var kind = node.kind; if (cancellationToken) { // Only bother checking on a few construct kinds. We don't want to be excessively // hitting the cancellation token on every node we check. switch (kind) { case 234 /* ModuleDeclaration */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 229 /* FunctionDeclaration */: cancellationToken.throwIfCancellationRequested(); } } switch (kind) { case 146 /* TypeParameter */: return checkTypeParameter(node); case 147 /* Parameter */: return checkParameter(node); case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return checkPropertyDeclaration(node); case 161 /* FunctionType */: case 162 /* ConstructorType */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: return checkSignatureDeclaration(node); case 158 /* IndexSignature */: return checkSignatureDeclaration(node); case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: return checkMethodDeclaration(node); case 153 /* Constructor */: return checkConstructorDeclaration(node); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return checkAccessorDeclaration(node); case 160 /* TypeReference */: return checkTypeReferenceNode(node); case 159 /* TypePredicate */: return checkTypePredicate(node); case 163 /* TypeQuery */: return checkTypeQuery(node); case 164 /* TypeLiteral */: return checkTypeLiteral(node); case 165 /* ArrayType */: return checkArrayType(node); case 166 /* TupleType */: return checkTupleType(node); case 167 /* UnionType */: case 168 /* IntersectionType */: return checkUnionOrIntersectionType(node); case 169 /* ParenthesizedType */: return checkSourceElement(node.type); case 171 /* TypeOperator */: return checkTypeOperator(node); case 282 /* JSDocAugmentsTag */: return checkJSDocAugmentsTag(node); case 288 /* JSDocTypedefTag */: return checkJSDocTypedefTag(node); case 284 /* JSDocParameterTag */: return checkJSDocParameterTag(node); case 277 /* JSDocFunctionType */: checkSignatureDeclaration(node); // falls through case 275 /* JSDocNonNullableType */: case 274 /* JSDocNullableType */: case 272 /* JSDocAllType */: case 273 /* JSDocUnknownType */: checkJSDocTypeIsInJsFile(node); ts.forEachChild(node, checkSourceElement); return; case 278 /* JSDocVariadicType */: checkJSDocVariadicType(node); return; case 271 /* JSDocTypeExpression */: return checkSourceElement(node.type); case 172 /* IndexedAccessType */: return checkIndexedAccessType(node); case 173 /* MappedType */: return checkMappedType(node); case 229 /* FunctionDeclaration */: return checkFunctionDeclaration(node); case 208 /* Block */: case 235 /* ModuleBlock */: return checkBlock(node); case 209 /* VariableStatement */: return checkVariableStatement(node); case 211 /* ExpressionStatement */: return checkExpressionStatement(node); case 212 /* IfStatement */: return checkIfStatement(node); case 213 /* DoStatement */: return checkDoStatement(node); case 214 /* WhileStatement */: return checkWhileStatement(node); case 215 /* ForStatement */: return checkForStatement(node); case 216 /* ForInStatement */: return checkForInStatement(node); case 217 /* ForOfStatement */: return checkForOfStatement(node); case 218 /* ContinueStatement */: case 219 /* BreakStatement */: return checkBreakOrContinueStatement(node); case 220 /* ReturnStatement */: return checkReturnStatement(node); case 221 /* WithStatement */: return checkWithStatement(node); case 222 /* SwitchStatement */: return checkSwitchStatement(node); case 223 /* LabeledStatement */: return checkLabeledStatement(node); case 224 /* ThrowStatement */: return checkThrowStatement(node); case 225 /* TryStatement */: return checkTryStatement(node); case 227 /* VariableDeclaration */: return checkVariableDeclaration(node); case 177 /* BindingElement */: return checkBindingElement(node); case 230 /* ClassDeclaration */: return checkClassDeclaration(node); case 231 /* InterfaceDeclaration */: return checkInterfaceDeclaration(node); case 232 /* TypeAliasDeclaration */: return checkTypeAliasDeclaration(node); case 233 /* EnumDeclaration */: return checkEnumDeclaration(node); case 234 /* ModuleDeclaration */: return checkModuleDeclaration(node); case 239 /* ImportDeclaration */: return checkImportDeclaration(node); case 238 /* ImportEqualsDeclaration */: return checkImportEqualsDeclaration(node); case 245 /* ExportDeclaration */: return checkExportDeclaration(node); case 244 /* ExportAssignment */: return checkExportAssignment(node); case 210 /* EmptyStatement */: checkGrammarStatementInAmbientContext(node); return; case 226 /* DebuggerStatement */: checkGrammarStatementInAmbientContext(node); return; case 248 /* MissingDeclaration */: return checkMissingDeclaration(node); } } function checkJSDocTypeIsInJsFile(node) { if (!ts.isInJavaScriptFile(node)) { grammarErrorOnNode(node, ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments); } } function checkJSDocVariadicType(node) { checkJSDocTypeIsInJsFile(node); checkSourceElement(node.type); // Only legal location is in the *last* parameter tag. var parent = node.parent; if (!ts.isJSDocTypeExpression(parent)) { error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); } var paramTag = parent.parent; if (!ts.isJSDocParameterTag(paramTag)) { error(node, ts.Diagnostics.JSDoc_may_only_appear_in_the_last_parameter_of_a_signature); return; } var param = ts.getParameterSymbolFromJSDoc(paramTag); if (!param) { // We will error in `checkJSDocParameterTag`. return; } var host = ts.getHostSignatureFromJSDoc(paramTag); if (!host || ts.last(host.parameters).symbol !== param) { error(node, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } } function getTypeFromJSDocVariadicType(node) { var type = getTypeFromTypeNode(node.type); var parent = node.parent; var paramTag = parent.parent; if (ts.isJSDocTypeExpression(parent) && ts.isJSDocParameterTag(paramTag)) { // Else we will add a diagnostic, see `checkJSDocVariadicType`. var param = ts.getParameterSymbolFromJSDoc(paramTag); if (param) { var host_1 = ts.getHostSignatureFromJSDoc(paramTag); /* Only return an array type if the corresponding parameter is marked as a rest parameter. So in the following situation we will not create an array type: /** @param {...number} a * / function f(a) {} Because `a` will just be of type `number | undefined`. A synthetic `...args` will also be added, which *will* get an array type. */ var lastParamDeclaration = host_1 && ts.last(host_1.parameters); if (lastParamDeclaration.symbol === param && ts.isRestParameter(lastParamDeclaration)) { return createArrayType(type); } } } return addOptionality(type); } // 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 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: checkFunctionExpressionOrObjectLiteralMethodDeferred(node); break; case 154 /* GetAccessor */: case 155 /* SetAccessor */: checkAccessorDeclaration(node); break; case 200 /* ClassExpression */: checkClassExpressionDeferred(node); break; } } } function checkSourceFile(node) { ts.performance.mark("beforeCheck"); checkSourceFileWorker(node); ts.performance.mark("afterCheck"); ts.performance.measure("Check", "beforeCheck", "afterCheck"); } // Fully type check a source file and collect the relevant diagnostics. function checkSourceFileWorker(node) { var links = getNodeLinks(node); if (!(links.flags & 1 /* TypeChecked */)) { // If skipLibCheck is enabled, skip type checking if file is a declaration file. // If skipDefaultLibCheck is enabled, skip type checking if file contains a // '/// ' directive. if (compilerOptions.skipLibCheck && node.isDeclarationFile || compilerOptions.skipDefaultLibCheck && node.hasNoDefaultLib) { return; } // Grammar checking checkGrammarSourceFile(node); ts.clear(potentialThisCollisions); ts.clear(potentialNewTargetCollisions); deferredNodes = []; deferredUnusedIdentifierNodes = produceDiagnostics && noUnusedIdentifiers ? [] : undefined; flowAnalysisDisabled = false; ts.forEach(node.statements, checkSourceElement); checkDeferredNodes(); if (ts.isExternalOrCommonJsModule(node)) { registerForUnusedIdentifiersCheck(node); } if (!node.isDeclarationFile) { checkUnusedIdentifiers(); } deferredNodes = undefined; deferredUnusedIdentifierNodes = undefined; if (ts.isExternalOrCommonJsModule(node)) { checkExternalModuleExports(node); } if (potentialThisCollisions.length) { ts.forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope); ts.clear(potentialThisCollisions); } if (potentialNewTargetCollisions.length) { ts.forEach(potentialNewTargetCollisions, checkIfNewTargetIsCapturedInEnclosingScope); ts.clear(potentialNewTargetCollisions); } links.flags |= 1 /* TypeChecked */; } } function getDiagnostics(sourceFile, ct) { try { // Record the cancellation token so it can be checked later on during checkSourceElement. // Do this in a finally block so we can ensure that it gets reset back to nothing after // this call is done. cancellationToken = ct; return getDiagnosticsWorker(sourceFile); } finally { cancellationToken = undefined; } } function getDiagnosticsWorker(sourceFile) { throwIfNonDiagnosticsProducing(); if (sourceFile) { // Some global diagnostics are deferred until they are needed and // may not be reported in the firt call to getGlobalDiagnostics. // We should catch these changes and report them. var previousGlobalDiagnostics = diagnostics.getGlobalDiagnostics(); var previousGlobalDiagnosticsSize = previousGlobalDiagnostics.length; checkSourceFile(sourceFile); var semanticDiagnostics = diagnostics.getDiagnostics(sourceFile.fileName); var currentGlobalDiagnostics = diagnostics.getGlobalDiagnostics(); if (currentGlobalDiagnostics !== previousGlobalDiagnostics) { // If the arrays are not the same reference, new diagnostics were added. var deferredGlobalDiagnostics = ts.relativeComplement(previousGlobalDiagnostics, currentGlobalDiagnostics, ts.compareDiagnostics); return ts.concatenate(deferredGlobalDiagnostics, semanticDiagnostics); } else if (previousGlobalDiagnosticsSize === 0 && currentGlobalDiagnostics.length > 0) { // If the arrays are the same reference, but the length has changed, a single // new diagnostic was added as DiagnosticCollection attempts to reuse the // same array. return ts.concatenate(currentGlobalDiagnostics, semanticDiagnostics); } return semanticDiagnostics; } // Global diagnostics are always added when a file is not provided to // getDiagnostics ts.forEach(host.getSourceFiles(), checkSourceFile); return diagnostics.getDiagnostics(); } function getGlobalDiagnostics() { throwIfNonDiagnosticsProducing(); return diagnostics.getGlobalDiagnostics(); } function throwIfNonDiagnosticsProducing() { if (!produceDiagnostics) { throw new Error("Trying to get diagnostics from a type checker that does not produce them."); } } // Language service support function getSymbolsInScope(location, meaning) { if (location.flags & 4194304 /* InWithStatement */) { // We cannot answer semantic questions within a with block, do not proceed any further return []; } var symbols = ts.createSymbolTable(); var isStatic = false; populateSymbols(); return symbolsToArray(symbols); function populateSymbols() { while (location) { if (location.locals && !isGlobalSourceFile(location)) { copySymbols(location.locals, meaning); } switch (location.kind) { case 234 /* ModuleDeclaration */: copySymbols(getSymbolOfNode(location).exports, meaning & 2623475 /* ModuleMember */); break; case 233 /* EnumDeclaration */: copySymbols(getSymbolOfNode(location).exports, meaning & 8 /* EnumMember */); break; case 200 /* ClassExpression */: var className = location.name; if (className) { copySymbol(location.symbol, meaning); } // falls through // this fall-through is necessary because we would like to handle // type parameter inside class expression similar to how we handle it in classDeclaration and interface Declaration case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: // If we didn't come from static member of class or interface, // add the type parameters into the symbol table // (type parameters of classDeclaration/classExpression and interface are in member property of the symbol. // Note: that the memberFlags come from previous iteration. if (!isStatic) { copySymbols(getMembersOfSymbol(getSymbolOfNode(location)), meaning & 793064 /* Type */); } break; case 187 /* FunctionExpression */: var funcName = location.name; if (funcName) { copySymbol(location.symbol, meaning); } break; } if (ts.introducesArgumentsExoticObject(location)) { copySymbol(argumentsSymbol, meaning); } isStatic = ts.hasModifier(location, 32 /* Static */); location = location.parent; } copySymbols(globals, meaning); } /** * Copy the given symbol into symbol tables if the symbol has the given meaning * and it doesn't already existed in the symbol table * @param key a key for storing in symbol table; if undefined, use symbol.name * @param symbol the symbol to be added into symbol table * @param meaning meaning of symbol to filter by before adding to symbol table */ function copySymbol(symbol, meaning) { if (ts.getCombinedLocalAndExportSymbolFlags(symbol) & meaning) { var id = symbol.escapedName; // We will copy all symbol regardless of its reserved name because // symbolsToArray will check whether the key is a reserved name and // it will not copy symbol with reserved name to the array if (!symbols.has(id)) { symbols.set(id, symbol); } } } function copySymbols(source, meaning) { if (meaning) { source.forEach(function (symbol) { copySymbol(symbol, meaning); }); } } } function isTypeDeclarationName(name) { return name.kind === 71 /* Identifier */ && isTypeDeclaration(name.parent) && name.parent.name === name; } function isTypeDeclaration(node) { switch (node.kind) { case 146 /* TypeParameter */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 233 /* 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 === 144 /* QualifiedName */) { node = node.parent; } return node.parent && node.parent.kind === 160 /* TypeReference */; } function isHeritageClauseElementIdentifier(entityName) { var node = entityName; while (node.parent && node.parent.kind === 180 /* PropertyAccessExpression */) { node = node.parent; } return node.parent && node.parent.kind === 202 /* ExpressionWithTypeArguments */; } function forEachEnclosingClass(node, callback) { var result; while (true) { node = ts.getContainingClass(node); if (!node) break; if (result = callback(node)) break; } return result; } function isNodeWithinConstructorOfClass(node, classDeclaration) { return ts.findAncestor(node, function (element) { if (ts.isConstructorDeclaration(element) && ts.nodeIsPresent(element.body) && element.parent === classDeclaration) { return true; } else if (element === classDeclaration || ts.isFunctionLikeDeclaration(element)) { return "quit"; } return false; }); } function isNodeWithinClass(node, classDeclaration) { return !!forEachEnclosingClass(node, function (n) { return n === classDeclaration; }); } function getLeftSideOfImportEqualsOrExportAssignment(nodeOnRightSide) { while (nodeOnRightSide.parent.kind === 144 /* QualifiedName */) { nodeOnRightSide = nodeOnRightSide.parent; } if (nodeOnRightSide.parent.kind === 238 /* ImportEqualsDeclaration */) { return nodeOnRightSide.parent.moduleReference === nodeOnRightSide && nodeOnRightSide.parent; } if (nodeOnRightSide.parent.kind === 244 /* ExportAssignment */) { return nodeOnRightSide.parent.expression === nodeOnRightSide && nodeOnRightSide.parent; } return undefined; } function isInRightSideOfImportOrExportAssignment(node) { return getLeftSideOfImportEqualsOrExportAssignment(node) !== undefined; } function getSpecialPropertyAssignmentSymbolFromEntityName(entityName) { var specialPropertyAssignmentKind = ts.getSpecialPropertyAssignmentKind(entityName.parent.parent); switch (specialPropertyAssignmentKind) { case 1 /* ExportsProperty */: case 3 /* PrototypeProperty */: return getSymbolOfNode(entityName.parent); case 4 /* ThisProperty */: case 2 /* ModuleExports */: case 5 /* Property */: return getSymbolOfNode(entityName.parent.parent); } } function getSymbolOfEntityNameOrPropertyAccessExpression(entityName) { if (ts.isDeclarationName(entityName)) { return getSymbolOfNode(entityName.parent); } if (ts.isInJavaScriptFile(entityName) && entityName.parent.kind === 180 /* PropertyAccessExpression */ && entityName.parent === entityName.parent.parent.left) { // Check if this is a special property assignment var specialPropertyAssignmentSymbol = getSpecialPropertyAssignmentSymbolFromEntityName(entityName); if (specialPropertyAssignmentSymbol) { return specialPropertyAssignmentSymbol; } } if (entityName.parent.kind === 244 /* ExportAssignment */ && ts.isEntityNameExpression(entityName)) { return resolveEntityName(entityName, /*all meanings*/ 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */); } if (entityName.kind !== 180 /* PropertyAccessExpression */ && isInRightSideOfImportOrExportAssignment(entityName)) { // Since we already checked for ExportAssignment, this really could only be an Import var importEqualsDeclaration = ts.getAncestor(entityName, 238 /* ImportEqualsDeclaration */); ts.Debug.assert(importEqualsDeclaration !== undefined); return getSymbolOfPartOfRightHandSideOfImportEquals(entityName, /*dontResolveAlias*/ true); } if (ts.isRightSideOfQualifiedNameOrPropertyAccess(entityName)) { entityName = entityName.parent; } if (isHeritageClauseElementIdentifier(entityName)) { var meaning = 0 /* None */; // In an interface or class, we're definitely interested in a type. if (entityName.parent.kind === 202 /* ExpressionWithTypeArguments */) { meaning = 793064 /* Type */; // In a class 'extends' clause we are also looking for a value. if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent)) { meaning |= 107455 /* Value */; } } else { meaning = 1920 /* Namespace */; } meaning |= 2097152 /* Alias */; var entityNameSymbol = resolveEntityName(entityName, meaning); if (entityNameSymbol) { return entityNameSymbol; } } if (entityName.parent.kind === 284 /* JSDocParameterTag */) { return ts.getParameterSymbolFromJSDoc(entityName.parent); } if (entityName.parent.kind === 146 /* TypeParameter */ && entityName.parent.parent.kind === 287 /* JSDocTemplateTag */) { ts.Debug.assert(!ts.isInJavaScriptFile(entityName)); // Otherwise `isDeclarationName` would have been true. var typeParameter = ts.getTypeParameterFromJsDoc(entityName.parent); return typeParameter && typeParameter.symbol; } if (ts.isExpressionNode(entityName)) { if (ts.nodeIsMissing(entityName)) { // Missing entity name. return undefined; } if (entityName.kind === 71 /* Identifier */) { if (ts.isJSXTagName(entityName) && isJsxIntrinsicIdentifier(entityName)) { return getIntrinsicTagSymbol(entityName.parent); } return resolveEntityName(entityName, 107455 /* Value */, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } else if (entityName.kind === 180 /* PropertyAccessExpression */ || entityName.kind === 144 /* QualifiedName */) { var links = getNodeLinks(entityName); if (links.resolvedSymbol) { return links.resolvedSymbol; } if (entityName.kind === 180 /* PropertyAccessExpression */) { checkPropertyAccessExpression(entityName); } else { checkQualifiedName(entityName); } return links.resolvedSymbol; } } else if (isTypeReferenceIdentifier(entityName)) { var meaning = entityName.parent.kind === 160 /* TypeReference */ ? 793064 /* Type */ : 1920 /* Namespace */; return resolveEntityName(entityName, meaning, /*ignoreErrors*/ false, /*dontResolveAlias*/ true); } else if (entityName.parent.kind === 257 /* JsxAttribute */) { return getJsxAttributePropertySymbol(entityName.parent); } if (entityName.parent.kind === 159 /* TypePredicate */) { return resolveEntityName(entityName, /*meaning*/ 1 /* FunctionScopedVariable */); } // Do we want to return undefined here? return undefined; } function getSymbolAtLocation(node) { if (node.kind === 269 /* SourceFile */) { return ts.isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined; } if (node.flags & 4194304 /* InWithStatement */) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } if (isDeclarationNameOrImportPropertyName(node)) { // This is a declaration, call getSymbolOfNode return getSymbolOfNode(node.parent); } else if (ts.isLiteralComputedPropertyDeclarationName(node)) { return getSymbolOfNode(node.parent.parent); } if (node.kind === 71 /* Identifier */) { if (isInRightSideOfImportOrExportAssignment(node)) { return getSymbolOfEntityNameOrPropertyAccessExpression(node); } else if (node.parent.kind === 177 /* BindingElement */ && node.parent.parent.kind === 175 /* ObjectBindingPattern */ && node === node.parent.propertyName) { var typeOfPattern = getTypeOfNode(node.parent.parent); var propertyDeclaration = typeOfPattern && getPropertyOfType(typeOfPattern, node.escapedText); if (propertyDeclaration) { return propertyDeclaration; } } } switch (node.kind) { case 71 /* Identifier */: case 180 /* PropertyAccessExpression */: case 144 /* QualifiedName */: return getSymbolOfEntityNameOrPropertyAccessExpression(node); case 99 /* ThisKeyword */: var container = ts.getThisContainer(node, /*includeArrowFunctions*/ false); if (ts.isFunctionLike(container)) { var sig = getSignatureFromDeclaration(container); if (sig.thisParameter) { return sig.thisParameter; } } if (ts.isInExpressionContext(node)) { return checkExpression(node).symbol; } // falls through case 170 /* ThisType */: return getTypeFromThisTypeNode(node).symbol; case 97 /* SuperKeyword */: return checkExpression(node).symbol; case 123 /* ConstructorKeyword */: // constructor keyword for an overload, should take us to the definition if it exist var constructorDeclaration = node.parent; if (constructorDeclaration && constructorDeclaration.kind === 153 /* Constructor */) { return constructorDeclaration.parent.symbol; } return undefined; case 9 /* StringLiteral */: // 1). import x = require("./mo/*gotToDefinitionHere*/d") // 2). External module name in an import declaration // 3). Dynamic import call or require in javascript if ((ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) || ((node.parent.kind === 239 /* ImportDeclaration */ || node.parent.kind === 245 /* ExportDeclaration */) && node.parent.moduleSpecifier === node) || ((ts.isInJavaScriptFile(node) && ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false)) || ts.isImportCall(node.parent))) { return resolveExternalModuleName(node, node); } // falls through case 8 /* NumericLiteral */: // index access var objectType = ts.isElementAccessExpression(node.parent) ? node.parent.argumentExpression === node ? getTypeOfExpression(node.parent.expression) : undefined : ts.isLiteralTypeNode(node.parent) && ts.isIndexedAccessTypeNode(node.parent.parent) ? getTypeFromTypeNode(node.parent.parent.objectType) : undefined; return objectType && getPropertyOfType(objectType, ts.escapeLeadingUnderscores(node.text)); case 79 /* DefaultKeyword */: case 89 /* FunctionKeyword */: case 36 /* EqualsGreaterThanToken */: return getSymbolOfNode(node.parent); default: return undefined; } } function getShorthandAssignmentValueSymbol(location) { // The function returns a value symbol of an identifier in the short-hand property assignment. // This is necessary as an identifier in short-hand property assignment can contains two meaning: // property name and property value. if (location && location.kind === 266 /* ShorthandPropertyAssignment */) { return resolveEntityName(location.name, 107455 /* Value */ | 2097152 /* Alias */); } return undefined; } /** Returns the target of an export specifier without following aliases */ function getExportSpecifierLocalTargetSymbol(node) { return node.parent.parent.moduleSpecifier ? getExternalModuleMember(node.parent.parent, node) : resolveEntityName(node.propertyName || node.name, 107455 /* Value */ | 793064 /* Type */ | 1920 /* Namespace */ | 2097152 /* Alias */); } function getTypeOfNode(node) { if (node.flags & 4194304 /* InWithStatement */) { // We cannot answer semantic questions within a with block, do not proceed any further return unknownType; } if (ts.isPartOfTypeNode(node)) { var typeFromTypeNode = getTypeFromTypeNode(node); if (typeFromTypeNode && ts.isExpressionWithTypeArgumentsInClassImplementsClause(node)) { var containingClass = ts.getContainingClass(node); var classType = getTypeOfNode(containingClass); typeFromTypeNode = getTypeWithThisArgument(typeFromTypeNode, classType.thisType); } return typeFromTypeNode; } if (ts.isExpressionNode(node)) { return getRegularTypeOfExpression(node); } if (ts.isExpressionWithTypeArgumentsInClassExtendsClause(node)) { // A SyntaxKind.ExpressionWithTypeArguments is considered a type node, except when it occurs in the // extends clause of a class. We handle that case here. var classNode = ts.getContainingClass(node); var classType = getDeclaredTypeOfSymbol(getSymbolOfNode(classNode)); var baseType = getBaseTypes(classType)[0]; return baseType && getTypeWithThisArgument(baseType, classType.thisType); } if (isTypeDeclaration(node)) { // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration var symbol = getSymbolOfNode(node); return getDeclaredTypeOfSymbol(symbol); } if (isTypeDeclarationName(node)) { var symbol = getSymbolAtLocation(node); return symbol && getDeclaredTypeOfSymbol(symbol); } if (ts.isDeclaration(node)) { // In this case, we call getSymbolOfNode instead of getSymbolAtLocation because it is a declaration var symbol = getSymbolOfNode(node); return getTypeOfSymbol(symbol); } if (isDeclarationNameOrImportPropertyName(node)) { var symbol = getSymbolAtLocation(node); return symbol && getTypeOfSymbol(symbol); } if (ts.isBindingPattern(node)) { return getTypeForVariableLikeDeclaration(node.parent, /*includeOptionality*/ true); } if (isInRightSideOfImportOrExportAssignment(node)) { var symbol = getSymbolAtLocation(node); var declaredType = symbol && getDeclaredTypeOfSymbol(symbol); return declaredType !== unknownType ? declaredType : getTypeOfSymbol(symbol); } return unknownType; } // Gets the type of object literal or array literal of destructuring assignment. // { a } from // for ( { a } of elems) { // } // [ a ] from // [a] = [ some array ...] function getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr) { ts.Debug.assert(expr.kind === 179 /* ObjectLiteralExpression */ || expr.kind === 178 /* ArrayLiteralExpression */); // If this is from "for of" // for ( { a } of elems) { // } if (expr.parent.kind === 217 /* ForOfStatement */) { var iteratedType = checkRightHandSideOfForOf(expr.parent.expression, expr.parent.awaitModifier); return checkDestructuringAssignment(expr, iteratedType || unknownType); } // If this is from "for" initializer // for ({a } = elems[0];.....) { } if (expr.parent.kind === 195 /* BinaryExpression */) { var iteratedType = getTypeOfExpression(expr.parent.right); return checkDestructuringAssignment(expr, iteratedType || unknownType); } // If this is from nested object binding pattern // for ({ skills: { primary, secondary } } = multiRobot, i = 0; i < 1; i++) { if (expr.parent.kind === 265 /* 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 === 178 /* ArrayLiteralExpression */); // [{ property1: p1, property2 }] = elems; var typeOfArrayLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(expr.parent); var elementType = checkIteratedTypeOrElementType(typeOfArrayLiteral || unknownType, expr.parent, /*allowStringInput*/ false, /*allowAsyncIterables*/ false) || unknownType; return checkArrayLiteralDestructuringElementAssignment(expr.parent, typeOfArrayLiteral, ts.indexOf(expr.parent.elements, expr), elementType || unknownType); } // Gets the property symbol corresponding to the property in destructuring assignment // 'property1' from // for ( { property1: a } of elems) { // } // 'property1' at location 'a' from: // [a] = [ property1, property2 ] function getPropertySymbolOfDestructuringAssignment(location) { // Get the type of the object or array literal and then look for property of given name in the type var typeOfObjectLiteral = getTypeOfArrayLiteralOrObjectLiteralDestructuringAssignment(location.parent.parent); return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.escapedText); } function getRegularTypeOfExpression(expr) { if (ts.isRightSideOfQualifiedNameOrPropertyAccess(expr)) { expr = expr.parent; } return getRegularTypeOfLiteralType(getTypeOfExpression(expr)); } /** * Gets either the static or instance type of a class element, based on * whether the element is declared as "static". */ function getParentTypeOfClassElement(node) { var classSymbol = getSymbolOfNode(node.parent); return ts.hasModifier(node, 32 /* Static */) ? getTypeOfSymbol(classSymbol) : getDeclaredTypeOfSymbol(classSymbol); } // Return the list of properties of the given type, augmented with properties from Function // if the type has call or construct signatures function getAugmentedPropertiesOfType(type) { type = getApparentType(type); var propsByName = ts.createSymbolTable(getPropertiesOfType(type)); if (typeHasCallOrConstructSignatures(type)) { ts.forEach(getPropertiesOfType(globalFunctionType), function (p) { if (!propsByName.has(p.escapedName)) { propsByName.set(p.escapedName, p); } }); } return getNamedMembers(propsByName); } function typeHasCallOrConstructSignatures(type) { return ts.typeHasCallOrConstructSignatures(type, checker); } function getRootSymbols(symbol) { if (ts.getCheckFlags(symbol) & 6 /* Synthetic */) { var symbols_4 = []; var name_4 = symbol.escapedName; ts.forEach(getSymbolLinks(symbol).containingType.types, function (t) { var symbol = getPropertyOfType(t, name_4); if (symbol) { symbols_4.push(symbol); } }); return symbols_4; } else if (symbol.flags & 33554432 /* Transient */) { var transient = symbol; if (transient.leftSpread) { return getRootSymbols(transient.leftSpread).concat(getRootSymbols(transient.rightSpread)); } if (transient.syntheticOrigin) { return getRootSymbols(transient.syntheticOrigin); } var target = void 0; var next = symbol; while (next = getSymbolLinks(next).target) { target = next; } if (target) { return [target]; } } return [symbol]; } // Emitter support function isArgumentsLocalBinding(node) { if (!ts.isGeneratedIdentifier(node)) { node = ts.getParseTreeNode(node, ts.isIdentifier); if (node) { var isPropertyName_1 = node.parent.kind === 180 /* PropertyAccessExpression */ && node.parent.name === node; return !isPropertyName_1 && getReferencedValueSymbol(node) === argumentsSymbol; } } return false; } function moduleExportsSomeValue(moduleReferenceExpression) { var moduleSymbol = resolveExternalModuleName(moduleReferenceExpression.parent, moduleReferenceExpression); if (!moduleSymbol || ts.isShorthandAmbientModuleSymbol(moduleSymbol)) { // If the module is not found or is shorthand, assume that it may export a value. return true; } var hasExportAssignment = hasExportAssignmentSymbol(moduleSymbol); // if module has export assignment then 'resolveExternalModuleSymbol' will return resolved symbol for export assignment // otherwise it will return moduleSymbol itself moduleSymbol = resolveExternalModuleSymbol(moduleSymbol); var symbolLinks = getSymbolLinks(moduleSymbol); if (symbolLinks.exportsSomeValue === undefined) { // for export assignments - check if resolved symbol for RHS is itself a value // otherwise - check if at least one export is value symbolLinks.exportsSomeValue = hasExportAssignment ? !!(moduleSymbol.flags & 107455 /* Value */) : ts.forEachEntry(getExportsOfModule(moduleSymbol), isValue); } return symbolLinks.exportsSomeValue; function isValue(s) { s = resolveSymbol(s); return s && !!(s.flags & 107455 /* Value */); } } function isNameOfModuleOrEnumDeclaration(node) { var parent = node.parent; return parent && ts.isModuleOrEnumDeclaration(parent) && node === parent.name; } // When resolved as an expression identifier, if the given node references an exported entity, return the declaration // node of the exported entity's container. Otherwise, return undefined. function getReferencedExportContainer(node, prefixLocals) { node = ts.getParseTreeNode(node, ts.isIdentifier); if (node) { // When resolving the export container for the name of a module or enum // declaration, we need to start resolution at the declaration's container. // Otherwise, we could incorrectly resolve the export container as the // declaration if it contains an exported member with the same name. var symbol = getReferencedValueSymbol(node, /*startInDeclarationContainer*/ isNameOfModuleOrEnumDeclaration(node)); if (symbol) { if (symbol.flags & 1048576 /* ExportValue */) { // If we reference an exported entity within the same module declaration, then whether // we prefix depends on the kind of entity. SymbolFlags.ExportHasLocal encompasses all the // kinds that we do NOT prefix. var exportSymbol = getMergedSymbol(symbol.exportSymbol); if (!prefixLocals && exportSymbol.flags & 944 /* ExportHasLocal */) { return undefined; } symbol = exportSymbol; } var parentSymbol_1 = getParentOfSymbol(symbol); if (parentSymbol_1) { if (parentSymbol_1.flags & 512 /* ValueModule */ && parentSymbol_1.valueDeclaration.kind === 269 /* SourceFile */) { var symbolFile = parentSymbol_1.valueDeclaration; var referenceFile = ts.getSourceFileOfNode(node); // If `node` accesses an export and that export isn't in the same file, then symbol is a namespace export, so return undefined. var symbolIsUmdExport = symbolFile !== referenceFile; return symbolIsUmdExport ? undefined : symbolFile; } return ts.findAncestor(node.parent, function (n) { return ts.isModuleOrEnumDeclaration(n) && getSymbolOfNode(n) === parentSymbol_1; }); } } } } // When resolved as an expression identifier, if the given node references an import, return the declaration of // that import. Otherwise, return undefined. function getReferencedImportDeclaration(node) { node = ts.getParseTreeNode(node, ts.isIdentifier); if (node) { var symbol = getReferencedValueSymbol(node); // We should only get the declaration of an alias if there isn't a local value // declaration for the symbol if (isNonLocalAlias(symbol, /*excludes*/ 107455 /* Value */)) { return getDeclarationOfAliasSymbol(symbol); } } return undefined; } function isSymbolOfDeclarationWithCollidingName(symbol) { if (symbol.flags & 418 /* BlockScoped */) { var links = getSymbolLinks(symbol); if (links.isDeclarationWithCollidingName === undefined) { var container = ts.getEnclosingBlockScopeContainer(symbol.valueDeclaration); if (ts.isStatementWithLocals(container)) { var nodeLinks_1 = getNodeLinks(symbol.valueDeclaration); if (resolveName(container.parent, symbol.escapedName, 107455 /* Value */, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false)) { // redeclaration - always should be renamed links.isDeclarationWithCollidingName = true; } else if (nodeLinks_1.flags & 131072 /* CapturedBlockScopedBinding */) { // binding is captured in the function // should be renamed if: // - binding is not top level - top level bindings never collide with anything // AND // - binding is not declared in loop, should be renamed to avoid name reuse across siblings // let a, b // { let x = 1; a = () => x; } // { let x = 100; b = () => x; } // console.log(a()); // should print '1' // console.log(b()); // should print '100' // OR // - binding is declared inside loop but not in inside initializer of iteration statement or directly inside loop body // * variables from initializer are passed to rewritten loop body as parameters so they are not captured directly // * variables that are declared immediately in loop body will become top level variable after loop is rewritten and thus // they will not collide with anything var isDeclaredInLoop = nodeLinks_1.flags & 262144 /* BlockScopedBindingInLoop */; var inLoopInitializer = ts.isIterationStatement(container, /*lookInLabeledStatements*/ false); var inLoopBodyBlock = container.kind === 208 /* Block */ && ts.isIterationStatement(container.parent, /*lookInLabeledStatements*/ false); links.isDeclarationWithCollidingName = !ts.isBlockScopedContainerTopLevel(container) && (!isDeclaredInLoop || (!inLoopInitializer && !inLoopBodyBlock)); } else { links.isDeclarationWithCollidingName = false; } } } return links.isDeclarationWithCollidingName; } return false; } // When resolved as an expression identifier, if the given node references a nested block scoped entity with // a name that either hides an existing name or might hide it when compiled downlevel, // return the declaration of that entity. Otherwise, return undefined. function getReferencedDeclarationWithCollidingName(node) { if (!ts.isGeneratedIdentifier(node)) { node = ts.getParseTreeNode(node, ts.isIdentifier); if (node) { var symbol = getReferencedValueSymbol(node); if (symbol && isSymbolOfDeclarationWithCollidingName(symbol)) { return symbol.valueDeclaration; } } } return undefined; } // Return true if the given node is a declaration of a nested block scoped entity with a name that either hides an // existing name or might hide a name when compiled downlevel function isDeclarationWithCollidingName(node) { node = ts.getParseTreeNode(node, ts.isDeclaration); if (node) { var symbol = getSymbolOfNode(node); if (symbol) { return isSymbolOfDeclarationWithCollidingName(symbol); } } return false; } function isValueAliasDeclaration(node) { switch (node.kind) { case 238 /* ImportEqualsDeclaration */: case 240 /* ImportClause */: case 241 /* NamespaceImport */: case 243 /* ImportSpecifier */: case 247 /* ExportSpecifier */: return isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol); case 245 /* ExportDeclaration */: var exportClause = node.exportClause; return exportClause && ts.forEach(exportClause.elements, isValueAliasDeclaration); case 244 /* ExportAssignment */: return node.expression && node.expression.kind === 71 /* Identifier */ ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) : true; } return false; } function isTopLevelValueImportEqualsWithEntityName(node) { node = ts.getParseTreeNode(node, ts.isImportEqualsDeclaration); if (node === undefined || node.parent.kind !== 269 /* SourceFile */ || !ts.isInternalModuleImportEqualsDeclaration(node)) { // parent is not source file or it is not reference to internal module return false; } var isValue = isAliasResolvedToValue(getSymbolOfNode(node)); return isValue && node.moduleReference && !ts.nodeIsMissing(node.moduleReference); } function isAliasResolvedToValue(symbol) { var target = resolveAlias(symbol); if (target === unknownSymbol) { return true; } // const enums and modules that contain only const enums are not considered values from the emit perspective // unless 'preserveConstEnums' option is set to true return target.flags & 107455 /* Value */ && (compilerOptions.preserveConstEnums || !isConstEnumOrConstEnumOnlyModule(target)); } function isConstEnumOrConstEnumOnlyModule(s) { return isConstEnumSymbol(s) || s.constEnumOnlyModule; } function isReferencedAliasDeclaration(node, checkChildren) { if (ts.isAliasSymbolDeclaration(node)) { var symbol = getSymbolOfNode(node); if (symbol && getSymbolLinks(symbol).referenced) { return true; } var target = getSymbolLinks(symbol).target; if (target && ts.getModifierFlags(node) & 1 /* Export */ && target.flags & 107455 /* Value */) { // An `export import ... =` of a value symbol is always considered referenced return true; } } if (checkChildren) { return ts.forEachChild(node, function (node) { return isReferencedAliasDeclaration(node, checkChildren); }); } return false; } function isImplementationOfOverload(node) { if (ts.nodeIsPresent(node.body)) { var symbol = getSymbolOfNode(node); var signaturesOfSymbol = getSignaturesOfSymbol(symbol); // If this function body corresponds to function with multiple signature, it is implementation of overload // e.g.: function foo(a: string): string; // function foo(a: number): number; // function foo(a: any) { // This is implementation of the overloads // return a; // } return signaturesOfSymbol.length > 1 || // If there is single signature for the symbol, it is overload if that signature isn't coming from the node // e.g.: function foo(a: string): string; // function foo(a: any) { // This is implementation of the overloads // return a; // } (signaturesOfSymbol.length === 1 && signaturesOfSymbol[0].declaration !== node); } return false; } function isRequiredInitializedParameter(parameter) { return strictNullChecks && !isOptionalParameter(parameter) && parameter.initializer && !ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function isOptionalUninitializedParameterProperty(parameter) { return strictNullChecks && isOptionalParameter(parameter) && !parameter.initializer && ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */); } function getNodeCheckFlags(node) { return getNodeLinks(node).flags; } function getEnumMemberValue(node) { computeEnumMemberValues(node.parent); return getNodeLinks(node).enumMemberValue; } function canHaveConstantValue(node) { switch (node.kind) { case 268 /* EnumMember */: case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: return true; } return false; } function getConstantValue(node) { if (node.kind === 268 /* 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 & 65536 /* Object */ && getSignaturesOfType(type, 0 /* Call */).length > 0; } function getTypeReferenceSerializationKind(typeName, location) { // ensure both `typeName` and `location` are parse tree nodes. typeName = ts.getParseTreeNode(typeName, ts.isEntityName); if (!typeName) return ts.TypeReferenceSerializationKind.Unknown; if (location) { location = ts.getParseTreeNode(location); if (!location) return ts.TypeReferenceSerializationKind.Unknown; } // Resolve the symbol as a value to ensure the type can be reached at runtime during emit. var valueSymbol = resolveEntityName(typeName, 107455 /* Value */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); // Resolve the symbol as a type so that we can provide a more useful hint for the type serializer. var typeSymbol = resolveEntityName(typeName, 793064 /* Type */, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location); if (valueSymbol && valueSymbol === typeSymbol) { var globalPromiseSymbol = getGlobalPromiseConstructorSymbol(/*reportErrors*/ false); if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) { return ts.TypeReferenceSerializationKind.Promise; } var constructorType = getTypeOfSymbol(valueSymbol); if (constructorType && isConstructorType(constructorType)) { return ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue; } } // We might not be able to resolve type symbol so use unknown type in that case (eg error case) if (!typeSymbol) { return ts.TypeReferenceSerializationKind.ObjectType; } var type = getDeclaredTypeOfSymbol(typeSymbol); if (type === unknownType) { return ts.TypeReferenceSerializationKind.Unknown; } else if (type.flags & 1 /* Any */) { return ts.TypeReferenceSerializationKind.ObjectType; } else if (isTypeAssignableToKind(type, 2048 /* Void */ | 12288 /* Nullable */ | 16384 /* Never */)) { return ts.TypeReferenceSerializationKind.VoidNullableOrNeverType; } else if (isTypeAssignableToKind(type, 136 /* BooleanLike */)) { return ts.TypeReferenceSerializationKind.BooleanType; } else if (isTypeAssignableToKind(type, 84 /* NumberLike */)) { return ts.TypeReferenceSerializationKind.NumberLikeType; } else if (isTypeAssignableToKind(type, 524322 /* StringLike */)) { return ts.TypeReferenceSerializationKind.StringLikeType; } else if (isTupleType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } else if (isTypeAssignableToKind(type, 1536 /* ESSymbolLike */)) { return ts.TypeReferenceSerializationKind.ESSymbolType; } else if (isFunctionType(type)) { return ts.TypeReferenceSerializationKind.TypeWithCallSignature; } else if (isArrayType(type)) { return ts.TypeReferenceSerializationKind.ArrayLikeType; } else { return ts.TypeReferenceSerializationKind.ObjectType; } } function writeTypeOfDeclaration(declaration, enclosingDeclaration, flags, writer) { // Get type of the symbol if this is the valid symbol otherwise get type at location var symbol = getSymbolOfNode(declaration); var type = symbol && !(symbol.flags & (2048 /* TypeLiteral */ | 131072 /* Signature */)) ? getWidenedLiteralType(getTypeOfSymbol(symbol)) : unknownType; if (type.flags & 1024 /* UniqueESSymbol */ && type.symbol === symbol) { flags |= 131072 /* AllowUniqueESSymbolType */; } if (flags & 8192 /* AddUndefined */) { type = getOptionalType(type); } getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); } function writeReturnTypeOfSignatureDeclaration(signatureDeclaration, enclosingDeclaration, flags, writer) { var signature = getSignatureFromDeclaration(signatureDeclaration); getSymbolDisplayBuilder().buildTypeDisplay(getReturnTypeOfSignature(signature), writer, enclosingDeclaration, flags); } function writeTypeOfExpression(expr, enclosingDeclaration, flags, writer) { var type = getWidenedType(getRegularTypeOfExpression(expr)); getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); } function hasGlobalName(name) { return globals.has(ts.escapeLeadingUnderscores(name)); } function getReferencedValueSymbol(reference, startInDeclarationContainer) { var resolvedSymbol = getNodeLinks(reference).resolvedSymbol; if (resolvedSymbol) { return resolvedSymbol; } var location = reference; if (startInDeclarationContainer) { // When resolving the name of a declaration as a value, we need to start resolution // at a point outside of the declaration. var parent = reference.parent; if (ts.isDeclaration(parent) && reference === parent.name) { location = getDeclarationContainer(parent); } } return resolveName(location, reference.escapedText, 107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */, /*nodeNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ true); } function getReferencedValueDeclaration(reference) { if (!ts.isGeneratedIdentifier(reference)) { reference = ts.getParseTreeNode(reference, ts.isIdentifier); if (reference) { var symbol = getReferencedValueSymbol(reference); if (symbol) { return getExportSymbolOfValueSymbolIfExported(symbol).valueDeclaration; } } } return undefined; } function isLiteralConstDeclaration(node) { if (ts.isConst(node)) { var type = getTypeOfSymbol(getSymbolOfNode(node)); return !!(type.flags & 96 /* StringOrNumberLiteral */ && type.flags & 2097152 /* FreshLiteral */); } return false; } function writeLiteralConstValue(node, writer) { var type = getTypeOfSymbol(getSymbolOfNode(node)); writer.writeStringLiteral(literalTypeToString(type)); } function createResolver() { // this variable and functions that use it are deliberately moved here from the outer scope // to avoid scope pollution var resolvedTypeReferenceDirectives = host.getResolvedTypeReferenceDirectives(); var fileToDirective; if (resolvedTypeReferenceDirectives) { // populate reverse mapping: file path -> type reference directive that was resolved to this file fileToDirective = ts.createMap(); resolvedTypeReferenceDirectives.forEach(function (resolvedDirective, key) { if (!resolvedDirective) { return; } var file = host.getSourceFile(resolvedDirective.resolvedFileName); fileToDirective.set(file.path, key); }); } return { getReferencedExportContainer: getReferencedExportContainer, getReferencedImportDeclaration: getReferencedImportDeclaration, getReferencedDeclarationWithCollidingName: getReferencedDeclarationWithCollidingName, isDeclarationWithCollidingName: isDeclarationWithCollidingName, isValueAliasDeclaration: function (node) { node = ts.getParseTreeNode(node); // Synthesized nodes are always treated like values. return node ? isValueAliasDeclaration(node) : true; }, hasGlobalName: hasGlobalName, isReferencedAliasDeclaration: function (node, checkChildren) { node = ts.getParseTreeNode(node); // Synthesized nodes are always treated as referenced. return node ? isReferencedAliasDeclaration(node, checkChildren) : true; }, getNodeCheckFlags: function (node) { node = ts.getParseTreeNode(node); return node ? getNodeCheckFlags(node) : undefined; }, isTopLevelValueImportEqualsWithEntityName: isTopLevelValueImportEqualsWithEntityName, isDeclarationVisible: isDeclarationVisible, isImplementationOfOverload: isImplementationOfOverload, isRequiredInitializedParameter: isRequiredInitializedParameter, isOptionalUninitializedParameterProperty: isOptionalUninitializedParameterProperty, writeTypeOfDeclaration: writeTypeOfDeclaration, writeReturnTypeOfSignatureDeclaration: writeReturnTypeOfSignatureDeclaration, writeTypeOfExpression: writeTypeOfExpression, isSymbolAccessible: isSymbolAccessible, isEntityNameVisible: isEntityNameVisible, getConstantValue: function (node) { node = ts.getParseTreeNode(node, canHaveConstantValue); return node ? getConstantValue(node) : undefined; }, collectLinkedAliases: collectLinkedAliases, getReferencedValueDeclaration: getReferencedValueDeclaration, getTypeReferenceSerializationKind: getTypeReferenceSerializationKind, isOptionalParameter: isOptionalParameter, moduleExportsSomeValue: moduleExportsSomeValue, isArgumentsLocalBinding: isArgumentsLocalBinding, getExternalModuleFileFromDeclaration: getExternalModuleFileFromDeclaration, getTypeReferenceDirectivesForEntityName: getTypeReferenceDirectivesForEntityName, getTypeReferenceDirectivesForSymbol: getTypeReferenceDirectivesForSymbol, isLiteralConstDeclaration: isLiteralConstDeclaration, isLateBound: function (node) { node = ts.getParseTreeNode(node, ts.isDeclaration); var symbol = node && getSymbolOfNode(node); return !!(symbol && ts.getCheckFlags(symbol) & 1024 /* Late */); }, writeLiteralConstValue: writeLiteralConstValue, getJsxFactoryEntity: function () { return _jsxFactoryEntity; } }; // defined here to avoid outer scope pollution function getTypeReferenceDirectivesForEntityName(node) { // program does not have any files with type reference directives - bail out if (!fileToDirective) { return undefined; } // property access can only be used as values // qualified names can only be used as types\namespaces // identifiers are treated as values only if they appear in type queries var meaning = (node.kind === 180 /* PropertyAccessExpression */) || (node.kind === 71 /* Identifier */ && isInTypeQuery(node)) ? 107455 /* Value */ | 1048576 /* ExportValue */ : 793064 /* Type */ | 1920 /* Namespace */; var symbol = resolveEntityName(node, meaning, /*ignoreErrors*/ true); return symbol && symbol !== unknownSymbol ? getTypeReferenceDirectivesForSymbol(symbol, meaning) : undefined; } // defined here to avoid outer scope pollution function getTypeReferenceDirectivesForSymbol(symbol, meaning) { // program does not have any files with type reference directives - bail out if (!fileToDirective) { return undefined; } if (!isSymbolFromTypeDeclarationFile(symbol)) { return undefined; } // check what declarations in the symbol can contribute to the target meaning var typeReferenceDirectives; for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; // check meaning of the local symbol to see if declaration needs to be analyzed further if (decl.symbol && decl.symbol.flags & meaning) { var file = ts.getSourceFileOfNode(decl); var typeReferenceDirective = fileToDirective.get(file.path); if (typeReferenceDirective) { (typeReferenceDirectives || (typeReferenceDirectives = [])).push(typeReferenceDirective); } else { // found at least one entry that does not originate from type reference directive return undefined; } } } return typeReferenceDirectives; } function isSymbolFromTypeDeclarationFile(symbol) { // bail out if symbol does not have associated declarations (i.e. this is transient symbol created for property in binding pattern) if (!symbol.declarations) { return false; } // walk the parent chain for symbols to make sure that top level parent symbol is in the global scope // external modules cannot define or contribute to type declaration files var current = symbol; while (true) { var parent = getParentOfSymbol(current); if (parent) { current = parent; } else { break; } } if (current.valueDeclaration && current.valueDeclaration.kind === 269 /* SourceFile */ && current.flags & 512 /* ValueModule */) { return false; } // check that at least one declaration of top level symbol originates from type declaration file for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; var file = ts.getSourceFileOfNode(decl); if (fileToDirective.has(file.path)) { return true; } } return false; } } function getExternalModuleFileFromDeclaration(declaration) { var specifier = ts.getExternalModuleName(declaration); var moduleSymbol = resolveExternalModuleNameWorker(specifier, specifier, /*moduleNotFoundError*/ undefined); if (!moduleSymbol) { return undefined; } return ts.getDeclarationOfKind(moduleSymbol, 269 /* SourceFile */); } function initializeTypeChecker() { // Bind all source files and propagate errors for (var _i = 0, _a = host.getSourceFiles(); _i < _a.length; _i++) { var file = _a[_i]; ts.bindSourceFile(file, compilerOptions); } // Initialize global symbol table var augmentations; for (var _b = 0, _c = host.getSourceFiles(); _b < _c.length; _b++) { var file = _c[_b]; if (!ts.isExternalOrCommonJsModule(file)) { mergeSymbolTable(globals, file.locals); } if (file.patternAmbientModules && file.patternAmbientModules.length) { patternAmbientModules = ts.concatenate(patternAmbientModules, file.patternAmbientModules); } if (file.moduleAugmentations.length) { (augmentations || (augmentations = [])).push(file.moduleAugmentations); } if (file.symbol && file.symbol.globalExports) { // Merge in UMD exports with first-in-wins semantics (see #9771) var source = file.symbol.globalExports; source.forEach(function (sourceSymbol, id) { if (!globals.has(id)) { globals.set(id, sourceSymbol); } }); } } if (augmentations) { // merge module augmentations. // this needs to be done after global symbol table is initialized to make sure that all ambient modules are indexed for (var _d = 0, augmentations_1 = augmentations; _d < augmentations_1.length; _d++) { var list = augmentations_1[_d]; for (var _e = 0, list_1 = list; _e < list_1.length; _e++) { var augmentation = list_1[_e]; mergeModuleAugmentation(augmentation); } } } // Setup global builtins addToSymbolTable(globals, builtinGlobals, ts.Diagnostics.Declaration_name_conflicts_with_built_in_global_identifier_0); getSymbolLinks(undefinedSymbol).type = undefinedWideningType; getSymbolLinks(argumentsSymbol).type = getGlobalType("IArguments", /*arity*/ 0, /*reportErrors*/ true); getSymbolLinks(unknownSymbol).type = unknownType; // Initialize special types globalArrayType = getGlobalType("Array", /*arity*/ 1, /*reportErrors*/ true); globalObjectType = getGlobalType("Object", /*arity*/ 0, /*reportErrors*/ true); globalFunctionType = getGlobalType("Function", /*arity*/ 0, /*reportErrors*/ true); globalStringType = getGlobalType("String", /*arity*/ 0, /*reportErrors*/ true); globalNumberType = getGlobalType("Number", /*arity*/ 0, /*reportErrors*/ true); globalBooleanType = getGlobalType("Boolean", /*arity*/ 0, /*reportErrors*/ true); globalRegExpType = getGlobalType("RegExp", /*arity*/ 0, /*reportErrors*/ true); anyArrayType = createArrayType(anyType); autoArrayType = createArrayType(autoType); if (autoArrayType === emptyObjectType) { // autoArrayType is used as a marker, so even if global Array type is not defined, it needs to be a unique type autoArrayType = createAnonymousType(undefined, emptySymbols, ts.emptyArray, ts.emptyArray, undefined, undefined); } globalReadonlyArrayType = getGlobalTypeOrUndefined("ReadonlyArray", /*arity*/ 1); anyReadonlyArrayType = globalReadonlyArrayType ? createTypeFromGenericGlobalType(globalReadonlyArrayType, [anyType]) : anyArrayType; globalThisType = getGlobalTypeOrUndefined("ThisType", /*arity*/ 1); } function checkExternalEmitHelpers(location, helpers) { if ((requestedExternalEmitHelpers & helpers) !== helpers && compilerOptions.importHelpers) { var sourceFile = ts.getSourceFileOfNode(location); if (ts.isEffectiveExternalModule(sourceFile, compilerOptions) && !(location.flags & 2097152 /* Ambient */)) { var helpersModule = resolveHelpersModule(sourceFile, location); if (helpersModule !== unknownSymbol) { var uncheckedHelpers = helpers & ~requestedExternalEmitHelpers; for (var helper = 1 /* FirstEmitHelper */; helper <= 65536 /* LastEmitHelper */; helper <<= 1) { if (uncheckedHelpers & helper) { var name = getHelperName(helper); var symbol = getSymbol(helpersModule.exports, ts.escapeLeadingUnderscores(name), 107455 /* Value */); if (!symbol) { error(location, ts.Diagnostics.This_syntax_requires_an_imported_helper_named_1_but_module_0_has_no_exported_member_1, ts.externalHelpersModuleNameText, name); } } } } requestedExternalEmitHelpers |= helpers; } } } function getHelperName(helper) { switch (helper) { case 1 /* Extends */: return "__extends"; case 2 /* Assign */: return "__assign"; case 4 /* Rest */: return "__rest"; case 8 /* Decorate */: return "__decorate"; case 16 /* Metadata */: return "__metadata"; case 32 /* Param */: return "__param"; case 64 /* Awaiter */: return "__awaiter"; case 128 /* Generator */: return "__generator"; case 256 /* Values */: return "__values"; case 512 /* Read */: return "__read"; case 1024 /* Spread */: return "__spread"; case 2048 /* Await */: return "__await"; case 4096 /* AsyncGenerator */: return "__asyncGenerator"; case 8192 /* AsyncDelegator */: return "__asyncDelegator"; case 16384 /* AsyncValues */: return "__asyncValues"; case 32768 /* ExportStar */: return "__exportStar"; case 65536 /* MakeTemplateObject */: return "__makeTemplateObject"; default: ts.Debug.fail("Unrecognized helper"); } } function resolveHelpersModule(node, errorNode) { if (!externalHelpersModule) { externalHelpersModule = resolveExternalModule(node, ts.externalHelpersModuleNameText, ts.Diagnostics.This_syntax_requires_an_imported_helper_but_module_0_cannot_be_found, errorNode) || unknownSymbol; } return externalHelpersModule; } // GRAMMAR CHECKING function checkGrammarDecoratorsAndModifiers(node) { return checkGrammarDecorators(node) || checkGrammarModifiers(node); } function checkGrammarDecorators(node) { if (!node.decorators) { return false; } if (!ts.nodeCanBeDecorated(node, node.parent, node.parent.parent)) { if (node.kind === 152 /* 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 === 154 /* GetAccessor */ || node.kind === 155 /* SetAccessor */) { var accessors = ts.getAllAccessorDeclarations(node.parent.members, node); if (accessors.firstAccessor.decorators && node === accessors.secondAccessor) { return grammarErrorOnFirstToken(node, ts.Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name); } } return false; } function checkGrammarModifiers(node) { var quickResult = reportObviousModifierErrors(node); if (quickResult !== undefined) { return quickResult; } var lastStatic, lastDeclare, lastAsync, lastReadonly; var flags = 0 /* None */; for (var _i = 0, _a = node.modifiers; _i < _a.length; _i++) { var modifier = _a[_i]; if (modifier.kind !== 131 /* ReadonlyKeyword */) { if (node.kind === 149 /* PropertySignature */ || node.kind === 151 /* MethodSignature */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_type_member, ts.tokenToString(modifier.kind)); } if (node.kind === 158 /* IndexSignature */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_an_index_signature, ts.tokenToString(modifier.kind)); } } switch (modifier.kind) { case 76 /* ConstKeyword */: if (node.kind !== 233 /* EnumDeclaration */ && node.parent.kind === 230 /* ClassDeclaration */) { return grammarErrorOnNode(node, ts.Diagnostics.A_class_member_cannot_have_the_0_keyword, ts.tokenToString(76 /* ConstKeyword */)); } break; case 114 /* PublicKeyword */: case 113 /* ProtectedKeyword */: case 112 /* PrivateKeyword */: var text = visibilityToString(ts.modifierToFlag(modifier.kind)); if (flags & 28 /* AccessibilityModifier */) { return grammarErrorOnNode(modifier, ts.Diagnostics.Accessibility_modifier_already_seen); } else if (flags & 32 /* Static */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "static"); } else if (flags & 64 /* Readonly */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "readonly"); } else if (flags & 256 /* Async */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "async"); } else if (node.parent.kind === 235 /* ModuleBlock */ || node.parent.kind === 269 /* SourceFile */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, text); } else if (flags & 128 /* Abstract */) { if (modifier.kind === 112 /* PrivateKeyword */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, text, "abstract"); } else { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, text, "abstract"); } } flags |= ts.modifierToFlag(modifier.kind); break; case 115 /* StaticKeyword */: if (flags & 32 /* Static */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "static"); } else if (flags & 64 /* Readonly */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "readonly"); } else if (flags & 256 /* Async */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "static", "async"); } else if (node.parent.kind === 235 /* ModuleBlock */ || node.parent.kind === 269 /* SourceFile */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_module_or_namespace_element, "static"); } else if (node.kind === 147 /* Parameter */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "static"); } else if (flags & 128 /* Abstract */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } flags |= 32 /* Static */; lastStatic = modifier; break; case 131 /* ReadonlyKeyword */: if (flags & 64 /* Readonly */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "readonly"); } else if (node.kind !== 150 /* PropertyDeclaration */ && node.kind !== 149 /* PropertySignature */ && node.kind !== 158 /* IndexSignature */ && node.kind !== 147 /* Parameter */) { // If node.kind === SyntaxKind.Parameter, checkParameter report an error if it's not a parameter property. return grammarErrorOnNode(modifier, ts.Diagnostics.readonly_modifier_can_only_appear_on_a_property_declaration_or_index_signature); } flags |= 64 /* Readonly */; lastReadonly = modifier; break; case 84 /* ExportKeyword */: if (flags & 1 /* Export */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "export"); } else if (flags & 2 /* Ambient */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare"); } else if (flags & 128 /* Abstract */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "abstract"); } else if (flags & 256 /* Async */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_must_precede_1_modifier, "export", "async"); } else if (node.parent.kind === 230 /* ClassDeclaration */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export"); } else if (node.kind === 147 /* Parameter */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "export"); } flags |= 1 /* Export */; break; case 79 /* DefaultKeyword */: var container = node.parent.kind === 269 /* SourceFile */ ? node.parent : node.parent.parent; if (container.kind === 234 /* ModuleDeclaration */ && !ts.isAmbientModule(container)) { return grammarErrorOnNode(modifier, ts.Diagnostics.A_default_export_can_only_be_used_in_an_ECMAScript_style_module); } flags |= 512 /* Default */; break; case 124 /* DeclareKeyword */: if (flags & 2 /* Ambient */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "declare"); } else if (flags & 256 /* Async */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } else if (node.parent.kind === 230 /* ClassDeclaration */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare"); } else if (node.kind === 147 /* Parameter */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "declare"); } else if ((node.parent.flags & 2097152 /* Ambient */) && node.parent.kind === 235 /* ModuleBlock */) { return grammarErrorOnNode(modifier, ts.Diagnostics.A_declare_modifier_cannot_be_used_in_an_already_ambient_context); } flags |= 2 /* Ambient */; lastDeclare = modifier; break; case 117 /* AbstractKeyword */: if (flags & 128 /* Abstract */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "abstract"); } if (node.kind !== 230 /* ClassDeclaration */) { if (node.kind !== 152 /* MethodDeclaration */ && node.kind !== 150 /* PropertyDeclaration */ && node.kind !== 154 /* GetAccessor */ && node.kind !== 155 /* SetAccessor */) { return grammarErrorOnNode(modifier, ts.Diagnostics.abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration); } if (!(node.parent.kind === 230 /* ClassDeclaration */ && ts.hasModifier(node.parent, 128 /* Abstract */))) { return grammarErrorOnNode(modifier, ts.Diagnostics.Abstract_methods_can_only_appear_within_an_abstract_class); } if (flags & 32 /* Static */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "static", "abstract"); } if (flags & 8 /* Private */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "private", "abstract"); } } flags |= 128 /* Abstract */; break; case 120 /* AsyncKeyword */: if (flags & 256 /* Async */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_already_seen, "async"); } else if (flags & 2 /* Ambient */ || node.parent.flags & 2097152 /* Ambient */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async"); } else if (node.kind === 147 /* Parameter */) { return grammarErrorOnNode(modifier, ts.Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async"); } flags |= 256 /* Async */; lastAsync = modifier; break; } } if (node.kind === 153 /* 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 === 239 /* ImportDeclaration */ || node.kind === 238 /* ImportEqualsDeclaration */) && flags & 2 /* Ambient */) { return grammarErrorOnNode(lastDeclare, ts.Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare"); } else if (node.kind === 147 /* 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 === 147 /* Parameter */ && (flags & 92 /* ParameterPropertyModifier */) && node.dotDotDotToken) { return grammarErrorOnNode(node, ts.Diagnostics.A_parameter_property_cannot_be_declared_using_a_rest_parameter); } if (flags & 256 /* Async */) { return checkGrammarAsyncModifier(node, lastAsync); } } /** * true | false: Early return this value from checkGrammarModifiers. * undefined: Need to do full checking on the modifiers. */ function reportObviousModifierErrors(node) { return !node.modifiers ? false : shouldReportBadModifier(node) ? grammarErrorOnFirstToken(node, ts.Diagnostics.Modifiers_cannot_appear_here) : undefined; } function shouldReportBadModifier(node) { switch (node.kind) { case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 153 /* Constructor */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 158 /* IndexSignature */: case 234 /* ModuleDeclaration */: case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: case 245 /* ExportDeclaration */: case 244 /* ExportAssignment */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 147 /* Parameter */: return false; default: if (node.parent.kind === 235 /* ModuleBlock */ || node.parent.kind === 269 /* SourceFile */) { return false; } switch (node.kind) { case 229 /* FunctionDeclaration */: return nodeHasAnyModifiersExcept(node, 120 /* AsyncKeyword */); case 230 /* ClassDeclaration */: return nodeHasAnyModifiersExcept(node, 117 /* AbstractKeyword */); case 231 /* InterfaceDeclaration */: case 209 /* VariableStatement */: case 232 /* TypeAliasDeclaration */: return true; case 233 /* EnumDeclaration */: return nodeHasAnyModifiersExcept(node, 76 /* ConstKeyword */); default: ts.Debug.fail(); return false; } } } function nodeHasAnyModifiersExcept(node, allowedModifier) { return node.modifiers.length > 1 || node.modifiers[0].kind !== allowedModifier; } function checkGrammarAsyncModifier(node, asyncModifier) { switch (node.kind) { case 152 /* MethodDeclaration */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return false; } return grammarErrorOnNode(asyncModifier, ts.Diagnostics._0_modifier_cannot_be_used_here, "async"); } function checkGrammarForDisallowedTrailingComma(list) { if (list && list.hasTrailingComma) { var start = list.end - ",".length; var end = list.end; return grammarErrorAtPos(list[0], start, end - start, ts.Diagnostics.Trailing_comma_not_allowed); } } function checkGrammarTypeParameterList(typeParameters, file) { if (checkGrammarForDisallowedTrailingComma(typeParameters)) { return true; } if (typeParameters && typeParameters.length === 0) { var start = typeParameters.pos - "<".length; var end = ts.skipTrivia(file.text, typeParameters.end) + ">".length; return grammarErrorAtPos(file, start, end - start, ts.Diagnostics.Type_parameter_list_cannot_be_empty); } } function checkGrammarParameterList(parameters) { var seenOptionalParameter = false; var parameterCount = parameters.length; for (var i = 0; i < parameterCount; i++) { var parameter = parameters[i]; if (parameter.dotDotDotToken) { if (i !== (parameterCount - 1)) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list); } if (ts.isBindingPattern(parameter.name)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); } if (parameter.questionToken) { return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.A_rest_parameter_cannot_be_optional); } if (parameter.initializer) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_rest_parameter_cannot_have_an_initializer); } } else if (parameter.questionToken) { seenOptionalParameter = true; if (parameter.initializer) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.Parameter_cannot_have_question_mark_and_initializer); } } else if (seenOptionalParameter && !parameter.initializer) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.A_required_parameter_cannot_follow_an_optional_parameter); } } } function checkGrammarFunctionLikeDeclaration(node) { // Prevent cascading error by short-circuit var file = ts.getSourceFileOfNode(node); return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) || checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file); } function checkGrammarClassLikeDeclaration(node) { var file = ts.getSourceFileOfNode(node); return checkGrammarClassDeclarationHeritageClauses(node) || checkGrammarTypeParameterList(node.typeParameters, file); } function checkGrammarArrowFunction(node, file) { if (node.kind === 188 /* ArrowFunction */) { var arrowFunction = node; var startLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.pos).line; var endLine = ts.getLineAndCharacterOfPosition(file, arrowFunction.equalsGreaterThanToken.end).line; if (startLine !== endLine) { return grammarErrorOnNode(arrowFunction.equalsGreaterThanToken, ts.Diagnostics.Line_terminator_not_permitted_before_arrow); } } return false; } function checkGrammarIndexSignatureParameters(node) { var parameter = node.parameters[0]; if (node.parameters.length !== 1) { if (parameter) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter); } else { return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_exactly_one_parameter); } } if (parameter.dotDotDotToken) { return grammarErrorOnNode(parameter.dotDotDotToken, ts.Diagnostics.An_index_signature_cannot_have_a_rest_parameter); } if (ts.hasModifiers(parameter)) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_accessibility_modifier); } if (parameter.questionToken) { return grammarErrorOnNode(parameter.questionToken, ts.Diagnostics.An_index_signature_parameter_cannot_have_a_question_mark); } if (parameter.initializer) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_cannot_have_an_initializer); } if (!parameter.type) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_must_have_a_type_annotation); } if (parameter.type.kind !== 136 /* StringKeyword */ && parameter.type.kind !== 133 /* NumberKeyword */) { return grammarErrorOnNode(parameter.name, ts.Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); } if (!node.type) { return grammarErrorOnNode(node, ts.Diagnostics.An_index_signature_must_have_a_type_annotation); } } function checkGrammarIndexSignature(node) { // Prevent cascading error by short-circuit return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node); } function checkGrammarForAtLeastOneTypeArgument(node, typeArguments) { if (typeArguments && typeArguments.length === 0) { var sourceFile = ts.getSourceFileOfNode(node); var start = typeArguments.pos - "<".length; var end = ts.skipTrivia(sourceFile.text, typeArguments.end) + ">".length; return grammarErrorAtPos(sourceFile, start, end - start, ts.Diagnostics.Type_argument_list_cannot_be_empty); } } function checkGrammarTypeArguments(node, typeArguments) { return checkGrammarForDisallowedTrailingComma(typeArguments) || checkGrammarForAtLeastOneTypeArgument(node, typeArguments); } function checkGrammarForOmittedArgument(args) { if (args) { for (var _i = 0, args_5 = args; _i < args_5.length; _i++) { var arg = args_5[_i]; if (arg.kind === 201 /* OmittedExpression */) { return grammarErrorAtPos(arg, arg.pos, 0, ts.Diagnostics.Argument_expression_expected); } } } } function checkGrammarArguments(args) { return checkGrammarForOmittedArgument(args); } function checkGrammarHeritageClause(node) { var types = node.types; if (checkGrammarForDisallowedTrailingComma(types)) { return true; } if (types && types.length === 0) { var listType = ts.tokenToString(node.token); return grammarErrorAtPos(node, types.pos, 0, ts.Diagnostics._0_list_cannot_be_empty, listType); } return ts.forEach(types, checkGrammarExpressionWithTypeArguments); } function checkGrammarExpressionWithTypeArguments(node) { return checkGrammarTypeArguments(node, node.typeArguments); } function checkGrammarClassDeclarationHeritageClauses(node) { var seenExtendsClause = false; var seenImplementsClause = false; if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) { for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) { var heritageClause = _a[_i]; if (heritageClause.token === 85 /* ExtendsKeyword */) { if (seenExtendsClause) { return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen); } if (seenImplementsClause) { return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_must_precede_implements_clause); } if (heritageClause.types.length > 1) { return grammarErrorOnFirstToken(heritageClause.types[1], ts.Diagnostics.Classes_can_only_extend_a_single_class); } seenExtendsClause = true; } else { ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */); if (seenImplementsClause) { return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.implements_clause_already_seen); } seenImplementsClause = true; } // Grammar checking heritageClause inside class declaration checkGrammarHeritageClause(heritageClause); } } } function checkGrammarInterfaceDeclaration(node) { var seenExtendsClause = false; if (node.heritageClauses) { for (var _i = 0, _a = node.heritageClauses; _i < _a.length; _i++) { var heritageClause = _a[_i]; if (heritageClause.token === 85 /* ExtendsKeyword */) { if (seenExtendsClause) { return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.extends_clause_already_seen); } seenExtendsClause = true; } else { ts.Debug.assert(heritageClause.token === 108 /* ImplementsKeyword */); return grammarErrorOnFirstToken(heritageClause, ts.Diagnostics.Interface_declaration_cannot_have_implements_clause); } // Grammar checking heritageClause inside class declaration checkGrammarHeritageClause(heritageClause); } } return false; } function checkGrammarComputedPropertyName(node) { // If node is not a computedPropertyName, just skip the grammar checking if (node.kind !== 145 /* ComputedPropertyName */) { return false; } var computedPropertyName = node; if (computedPropertyName.expression.kind === 195 /* BinaryExpression */ && computedPropertyName.expression.operatorToken.kind === 26 /* CommaToken */) { return grammarErrorOnNode(computedPropertyName.expression, ts.Diagnostics.A_comma_expression_is_not_allowed_in_a_computed_property_name); } } function checkGrammarForGenerator(node) { if (node.asteriskToken) { ts.Debug.assert(node.kind === 229 /* FunctionDeclaration */ || node.kind === 187 /* FunctionExpression */ || node.kind === 152 /* MethodDeclaration */); if (node.flags & 2097152 /* Ambient */) { return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.Generators_are_not_allowed_in_an_ambient_context); } if (!node.body) { return grammarErrorOnNode(node.asteriskToken, ts.Diagnostics.An_overload_signature_cannot_be_declared_as_a_generator); } } } function checkGrammarForInvalidQuestionMark(questionToken, message) { if (questionToken) { return grammarErrorOnNode(questionToken, message); } } function checkGrammarObjectLiteralExpression(node, inDestructuring) { var Flags; (function (Flags) { Flags[Flags["Property"] = 1] = "Property"; Flags[Flags["GetAccessor"] = 2] = "GetAccessor"; Flags[Flags["SetAccessor"] = 4] = "SetAccessor"; Flags[Flags["GetOrSetAccessor"] = 6] = "GetOrSetAccessor"; })(Flags || (Flags = {})); var seen = ts.createUnderscoreEscapedMap(); for (var _i = 0, _a = node.properties; _i < _a.length; _i++) { var prop = _a[_i]; if (prop.kind === 267 /* SpreadAssignment */) { continue; } var name = prop.name; if (name.kind === 145 /* ComputedPropertyName */) { // If the name is not a ComputedPropertyName, the grammar checking will skip it checkGrammarComputedPropertyName(name); } if (prop.kind === 266 /* ShorthandPropertyAssignment */ && !inDestructuring && prop.objectAssignmentInitializer) { // having objectAssignmentInitializer is only valid in ObjectAssignmentPattern // outside of destructuring it is a syntax error return grammarErrorOnNode(prop.equalsToken, ts.Diagnostics.can_only_be_used_in_an_object_literal_property_inside_a_destructuring_assignment); } // Modifiers are never allowed on properties except for 'async' on a method declaration if (prop.modifiers) { for (var _b = 0, _c = prop.modifiers; _b < _c.length; _b++) { var mod = _c[_b]; if (mod.kind !== 120 /* AsyncKeyword */ || prop.kind !== 152 /* 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; switch (prop.kind) { case 265 /* PropertyAssignment */: case 266 /* ShorthandPropertyAssignment */: // Grammar checking for computedPropertyName and shorthandPropertyAssignment checkGrammarForInvalidQuestionMark(prop.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional); if (name.kind === 8 /* NumericLiteral */) { checkGrammarNumericLiteral(name); } // falls through case 152 /* MethodDeclaration */: currentKind = 1 /* Property */; break; case 154 /* GetAccessor */: currentKind = 2 /* GetAccessor */; break; case 155 /* SetAccessor */: currentKind = 4 /* SetAccessor */; break; default: ts.Debug.assertNever(prop, "Unexpected syntax kind:" + prop.kind); } var effectiveName = ts.getPropertyNameForPropertyNameNode(name); if (effectiveName === undefined) { continue; } var existingKind = seen.get(effectiveName); if (!existingKind) { seen.set(effectiveName, currentKind); } else { if (currentKind === 1 /* Property */ && existingKind === 1 /* Property */) { grammarErrorOnNode(name, ts.Diagnostics.Duplicate_identifier_0, ts.getTextOfNode(name)); } else if ((currentKind & 6 /* GetOrSetAccessor */) && (existingKind & 6 /* GetOrSetAccessor */)) { if (existingKind !== 6 /* GetOrSetAccessor */ && currentKind !== existingKind) { seen.set(effectiveName, currentKind | existingKind); } else { return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name); } } else { return grammarErrorOnNode(name, ts.Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name); } } } } function checkGrammarJsxElement(node) { var seen = ts.createUnderscoreEscapedMap(); for (var _i = 0, _a = node.attributes.properties; _i < _a.length; _i++) { var attr = _a[_i]; if (attr.kind === 259 /* JsxSpreadAttribute */) { continue; } var jsxAttr = attr; var name = jsxAttr.name; if (!seen.get(name.escapedText)) { seen.set(name.escapedText, true); } else { return grammarErrorOnNode(name, ts.Diagnostics.JSX_elements_cannot_have_multiple_attributes_with_the_same_name); } var initializer = jsxAttr.initializer; if (initializer && initializer.kind === 260 /* JsxExpression */ && !initializer.expression) { return grammarErrorOnNode(jsxAttr.initializer, ts.Diagnostics.JSX_attributes_must_only_be_assigned_a_non_empty_expression); } } } function checkGrammarForInOrForOfStatement(forInOrOfStatement) { if (checkGrammarStatementInAmbientContext(forInOrOfStatement)) { return true; } if (forInOrOfStatement.kind === 217 /* ForOfStatement */ && forInOrOfStatement.awaitModifier) { if ((forInOrOfStatement.flags & 16384 /* AwaitContext */) === 0 /* None */) { return grammarErrorOnNode(forInOrOfStatement.awaitModifier, ts.Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator); } } if (forInOrOfStatement.initializer.kind === 228 /* 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 === 216 /* 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 === 216 /* 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 === 216 /* 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 (accessor.flags & 2097152 /* Ambient */) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_be_declared_in_an_ambient_context); } else if (accessor.body === undefined && !ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorAtPos(accessor, accessor.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } else if (accessor.body && ts.hasModifier(accessor, 128 /* Abstract */)) { return grammarErrorOnNode(accessor, ts.Diagnostics.An_abstract_accessor_cannot_have_an_implementation); } else if (accessor.typeParameters) { return grammarErrorOnNode(accessor.name, ts.Diagnostics.An_accessor_cannot_have_type_parameters); } else if (!doesAccessorHaveCorrectParameterCount(accessor)) { return grammarErrorOnNode(accessor.name, kind === 154 /* GetAccessor */ ? ts.Diagnostics.A_get_accessor_cannot_have_parameters : ts.Diagnostics.A_set_accessor_must_have_exactly_one_parameter); } else if (kind === 155 /* 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 === 154 /* GetAccessor */ ? 0 : 1); } function getAccessorThisParameter(accessor) { if (accessor.parameters.length === (accessor.kind === 154 /* GetAccessor */ ? 1 : 2)) { return ts.getThisParameter(accessor); } } function checkGrammarTypeOperatorNode(node) { if (node.operator === 140 /* UniqueKeyword */) { if (node.type.kind !== 137 /* SymbolKeyword */) { return grammarErrorOnNode(node.type, ts.Diagnostics._0_expected, ts.tokenToString(137 /* SymbolKeyword */)); } var parent = ts.walkUpParenthesizedTypes(node.parent); switch (parent.kind) { case 227 /* VariableDeclaration */: var decl = parent; if (decl.name.kind !== 71 /* Identifier */) { return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_may_not_be_used_on_a_variable_declaration_with_a_binding_name); } if (!ts.isVariableDeclarationInVariableStatement(decl)) { return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_only_allowed_on_variables_in_a_variable_statement); } if (!(decl.parent.flags & 2 /* Const */)) { return grammarErrorOnNode(parent.name, ts.Diagnostics.A_variable_whose_type_is_a_unique_symbol_type_must_be_const); } break; case 150 /* PropertyDeclaration */: if (!ts.hasModifier(parent, 32 /* Static */) || !ts.hasModifier(parent, 64 /* Readonly */)) { return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_a_class_whose_type_is_a_unique_symbol_type_must_be_both_static_and_readonly); } break; case 149 /* PropertySignature */: if (!ts.hasModifier(parent, 64 /* Readonly */)) { return grammarErrorOnNode(parent.name, ts.Diagnostics.A_property_of_an_interface_or_type_literal_whose_type_is_a_unique_symbol_type_must_be_readonly); } break; default: return grammarErrorOnNode(node, ts.Diagnostics.unique_symbol_types_are_not_allowed_here); } } } function checkGrammarForInvalidDynamicName(node, message) { if (isNonBindableDynamicName(node)) { return grammarErrorOnNode(node, message); } } function checkGrammarMethod(node) { if (checkGrammarDisallowedModifiersOnObjectLiteralExpressionMethod(node) || checkGrammarFunctionLikeDeclaration(node) || checkGrammarForGenerator(node)) { return true; } if (node.parent.kind === 179 /* ObjectLiteralExpression */) { if (checkGrammarForInvalidQuestionMark(node.questionToken, ts.Diagnostics.An_object_member_cannot_be_declared_optional)) { return true; } else if (node.body === undefined) { return grammarErrorAtPos(node, node.end - 1, ";".length, ts.Diagnostics._0_expected, "{"); } } if (ts.isClassLike(node.parent)) { // Technically, computed properties in ambient contexts is disallowed // for property declarations and accessors too, not just methods. // However, property declarations disallow computed names in general, // and accessors are not allowed in ambient contexts in general, // so this error only really matters for methods. if (node.flags & 2097152 /* Ambient */) { return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_ambient_context_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } else if (!node.body) { return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_method_overload_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } } else if (node.parent.kind === 231 /* InterfaceDeclaration */) { return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } else if (node.parent.kind === 164 /* TypeLiteral */) { return checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type); } } 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 223 /* LabeledStatement */: if (node.label && current.label.escapedText === node.label.escapedText) { // found matching label - verify that label usage is correct // continue can only target labels that are on iteration statements var isMisplacedContinueLabel = node.kind === 218 /* 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 222 /* SwitchStatement */: if (node.kind === 219 /* 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 === 219 /* 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 === 219 /* BreakStatement */ ? ts.Diagnostics.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement : ts.Diagnostics.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement; return grammarErrorOnNode(node, message); } } function checkGrammarBindingElement(node) { if (node.dotDotDotToken) { var elements = node.parent.elements; if (node !== ts.lastOrUndefined(elements)) { return grammarErrorOnNode(node, ts.Diagnostics.A_rest_element_must_be_last_in_a_destructuring_pattern); } if (node.name.kind === 176 /* ArrayBindingPattern */ || node.name.kind === 175 /* ObjectBindingPattern */) { return grammarErrorOnNode(node.name, ts.Diagnostics.A_rest_element_cannot_contain_a_binding_pattern); } if (node.initializer) { // Error on equals token which immediately precedes the initializer return grammarErrorAtPos(node, node.initializer.pos - 1, 1, ts.Diagnostics.A_rest_element_cannot_have_an_initializer); } } } function isStringOrNumberLiteralExpression(expr) { return expr.kind === 9 /* StringLiteral */ || expr.kind === 8 /* NumericLiteral */ || expr.kind === 193 /* PrefixUnaryExpression */ && expr.operator === 38 /* MinusToken */ && expr.operand.kind === 8 /* NumericLiteral */; } function checkGrammarVariableDeclaration(node) { if (node.parent.parent.kind !== 216 /* ForInStatement */ && node.parent.parent.kind !== 217 /* ForOfStatement */) { if (node.flags & 2097152 /* Ambient */) { if (node.initializer) { if (ts.isConst(node) && !node.type) { if (!isStringOrNumberLiteralExpression(node.initializer)) { return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal); } } else { // Error on equals token which immediate precedes the initializer var equalsTokenLength = "=".length; return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } if (node.initializer && !(ts.isConst(node) && isStringOrNumberLiteralExpression(node.initializer))) { // Error on equals token which immediate precedes the initializer var equalsTokenLength = "=".length; return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } } else if (!node.initializer) { if (ts.isBindingPattern(node.name) && !ts.isBindingPattern(node.parent)) { return grammarErrorOnNode(node, ts.Diagnostics.A_destructuring_declaration_must_have_an_initializer); } if (ts.isConst(node)) { return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_must_be_initialized); } } } if (node.exclamationToken && (node.parent.parent.kind !== 209 /* VariableStatement */ || !node.type || node.initializer || node.flags & 2097152 /* Ambient */)) { return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); } if (compilerOptions.module !== ts.ModuleKind.ES2015 && compilerOptions.module !== ts.ModuleKind.ESNext && compilerOptions.module !== ts.ModuleKind.System && !compilerOptions.noEmit && !(node.parent.parent.flags & 2097152 /* Ambient */) && ts.hasModifier(node.parent.parent, 1 /* Export */)) { checkESModuleMarker(node.name); } var checkLetConstNames = (ts.isLet(node) || ts.isConst(node)); // 1. LexicalDeclaration : LetOrConst BindingList ; // It is a Syntax Error if the BoundNames of BindingList contains "let". // 2. ForDeclaration: ForDeclaration : LetOrConst ForBinding // It is a Syntax Error if the BoundNames of ForDeclaration contains "let". // It is a SyntaxError if a VariableDeclaration or VariableDeclarationNoIn occurs within strict code // and its Identifier is eval or arguments return checkLetConstNames && checkGrammarNameInLetOrConstDeclarations(node.name); } function checkESModuleMarker(name) { if (name.kind === 71 /* Identifier */) { if (ts.idText(name) === "__esModule") { return grammarErrorOnNode(name, ts.Diagnostics.Identifier_expected_esModule_is_reserved_as_an_exported_marker_when_transforming_ECMAScript_modules); } } else { var elements = name.elements; for (var _i = 0, elements_1 = elements; _i < elements_1.length; _i++) { var element = elements_1[_i]; if (!ts.isOmittedExpression(element)) { return checkESModuleMarker(element.name); } } } } function checkGrammarNameInLetOrConstDeclarations(name) { if (name.kind === 71 /* Identifier */) { if (name.originalKeywordKind === 110 /* LetKeyword */) { return grammarErrorOnNode(name, ts.Diagnostics.let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations); } } else { var elements = name.elements; for (var _i = 0, elements_2 = elements; _i < elements_2.length; _i++) { var element = elements_2[_i]; if (!ts.isOmittedExpression(element)) { checkGrammarNameInLetOrConstDeclarations(element.name); } } } } function checkGrammarVariableDeclarationList(declarationList) { var declarations = declarationList.declarations; if (checkGrammarForDisallowedTrailingComma(declarationList.declarations)) { return true; } if (!declarationList.declarations.length) { return grammarErrorAtPos(declarationList, declarations.pos, declarations.end - declarations.pos, ts.Diagnostics.Variable_declaration_list_cannot_be_empty); } } function allowLetAndConstDeclarations(parent) { switch (parent.kind) { case 212 /* IfStatement */: case 213 /* DoStatement */: case 214 /* WhileStatement */: case 221 /* WithStatement */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: return false; case 223 /* LabeledStatement */: return allowLetAndConstDeclarations(parent.parent); } return true; } function checkGrammarForDisallowedLetOrConstStatement(node) { if (!allowLetAndConstDeclarations(node.parent)) { if (ts.isLet(node.declarationList)) { return grammarErrorOnNode(node, ts.Diagnostics.let_declarations_can_only_be_declared_inside_a_block); } else if (ts.isConst(node.declarationList)) { return grammarErrorOnNode(node, ts.Diagnostics.const_declarations_can_only_be_declared_inside_a_block); } } } function checkGrammarMetaProperty(node) { if (node.keywordToken === 94 /* NewKeyword */) { if (node.name.escapedText !== "target") { return grammarErrorOnNode(node.name, ts.Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, ts.tokenToString(node.keywordToken), "target"); } } } function hasParseDiagnostics(sourceFile) { return sourceFile.parseDiagnostics.length > 0; } function grammarErrorOnFirstToken(node, message, arg0, arg1, arg2) { var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span_4 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); diagnostics.add(ts.createFileDiagnostic(sourceFile, span_4.start, span_4.length, message, arg0, arg1, arg2)); return true; } } function grammarErrorAtPos(nodeForSourceFile, start, length, message, arg0, arg1, arg2) { var sourceFile = ts.getSourceFileOfNode(nodeForSourceFile); if (!hasParseDiagnostics(sourceFile)) { diagnostics.add(ts.createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2)); return true; } } function grammarErrorOnNode(node, message, arg0, arg1, arg2) { var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { diagnostics.add(ts.createDiagnosticForNode(node, message, arg0, arg1, arg2)); return true; } } function checkGrammarConstructorTypeParameters(node) { var typeParameters = ts.getEffectiveTypeParameterDeclarations(node); if (typeParameters) { var _a = ts.isNodeArray(typeParameters) ? typeParameters : ts.first(typeParameters), pos = _a.pos, end = _a.end; return grammarErrorAtPos(node, pos, end - pos, ts.Diagnostics.Type_parameters_cannot_appear_on_a_constructor_declaration); } } function checkGrammarConstructorTypeAnnotation(node) { var type = ts.getEffectiveReturnTypeNode(node); if (type) { return grammarErrorOnNode(type, ts.Diagnostics.Type_annotation_cannot_appear_on_a_constructor_declaration); } } function checkGrammarProperty(node) { if (ts.isClassLike(node.parent)) { if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_class_property_declaration_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } } else if (node.parent.kind === 231 /* InterfaceDeclaration */) { if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_an_interface_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } if (node.initializer) { return grammarErrorOnNode(node.initializer, ts.Diagnostics.An_interface_property_cannot_have_an_initializer); } } else if (node.parent.kind === 164 /* TypeLiteral */) { if (checkGrammarForInvalidDynamicName(node.name, ts.Diagnostics.A_computed_property_name_in_a_type_literal_must_refer_to_an_expression_whose_type_is_a_literal_type_or_a_unique_symbol_type)) { return true; } if (node.initializer) { return grammarErrorOnNode(node.initializer, ts.Diagnostics.A_type_literal_property_cannot_have_an_initializer); } } if (node.flags & 2097152 /* Ambient */ && node.initializer) { return grammarErrorOnFirstToken(node.initializer, ts.Diagnostics.Initializers_are_not_allowed_in_ambient_contexts); } if (node.exclamationToken && (!ts.isClassLike(node.parent) || !node.type || node.initializer || node.flags & 2097152 /* Ambient */ || ts.hasModifier(node, 32 /* Static */ | 128 /* Abstract */))) { return grammarErrorOnNode(node.exclamationToken, ts.Diagnostics.A_definite_assignment_assertion_is_not_permitted_in_this_context); } } function checkGrammarTopLevelElementForRequiredDeclareModifier(node) { // A declare modifier is required for any top level .d.ts declaration except export=, export default, export as namespace // interfaces and imports categories: // // DeclarationElement: // ExportAssignment // export_opt InterfaceDeclaration // export_opt TypeAliasDeclaration // export_opt ImportDeclaration // export_opt ExternalImportDeclaration // export_opt AmbientDeclaration // // TODO: The spec needs to be amended to reflect this grammar. if (node.kind === 231 /* InterfaceDeclaration */ || node.kind === 232 /* TypeAliasDeclaration */ || node.kind === 239 /* ImportDeclaration */ || node.kind === 238 /* ImportEqualsDeclaration */ || node.kind === 245 /* ExportDeclaration */ || node.kind === 244 /* ExportAssignment */ || node.kind === 237 /* NamespaceExportDeclaration */ || ts.hasModifier(node, 2 /* Ambient */ | 1 /* Export */ | 512 /* Default */)) { return false; } return grammarErrorOnFirstToken(node, ts.Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); } function checkGrammarTopLevelElementsForRequiredDeclareModifier(file) { for (var _i = 0, _a = file.statements; _i < _a.length; _i++) { var decl = _a[_i]; if (ts.isDeclaration(decl) || decl.kind === 209 /* VariableStatement */) { if (checkGrammarTopLevelElementForRequiredDeclareModifier(decl)) { return true; } } } } function checkGrammarSourceFile(node) { return !!(node.flags & 2097152 /* Ambient */) && checkGrammarTopLevelElementsForRequiredDeclareModifier(node); } function checkGrammarStatementInAmbientContext(node) { if (node.flags & 2097152 /* Ambient */) { // An accessors is already reported about the ambient context if (ts.isAccessor(node.parent)) { return getNodeLinks(node).hasReportedStatementInAmbientContext = true; } // Find containing block which is either Block, ModuleBlock, SourceFile var links = getNodeLinks(node); if (!links.hasReportedStatementInAmbientContext && ts.isFunctionLike(node.parent)) { return getNodeLinks(node).hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts); } // We are either parented by another statement, or some sort of block. // If we're in a block, we only want to really report an error once // to prevent noisiness. So use a bit on the block to indicate if // this has already been reported, and don't report if it has. // if (node.parent.kind === 208 /* Block */ || node.parent.kind === 235 /* ModuleBlock */ || node.parent.kind === 269 /* SourceFile */) { var links_1 = getNodeLinks(node.parent); // Check if the containing block ever report this error if (!links_1.hasReportedStatementInAmbientContext) { return links_1.hasReportedStatementInAmbientContext = grammarErrorOnFirstToken(node, ts.Diagnostics.Statements_are_not_allowed_in_ambient_contexts); } } else { // We must be parented by a statement. If so, there's no need // to report the error as our parent will have already done it. // Debug.assert(isStatement(node.parent)); } } } function checkGrammarNumericLiteral(node) { // Grammar checking if (node.numericLiteralFlags & 32 /* Octal */) { var diagnosticMessage = void 0; if (languageVersion >= 1 /* ES5 */) { diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher_Use_the_syntax_0; } else if (ts.isChildOfNodeWithKind(node, 174 /* LiteralType */)) { diagnosticMessage = ts.Diagnostics.Octal_literal_types_must_use_ES2015_syntax_Use_the_syntax_0; } else if (ts.isChildOfNodeWithKind(node, 268 /* EnumMember */)) { diagnosticMessage = ts.Diagnostics.Octal_literals_are_not_allowed_in_enums_members_initializer_Use_the_syntax_0; } if (diagnosticMessage) { var withMinus = ts.isPrefixUnaryExpression(node.parent) && node.parent.operator === 38 /* MinusToken */; var literal = (withMinus ? "-" : "") + "0o" + node.text; return grammarErrorOnNode(withMinus ? node.parent : node, diagnosticMessage, literal); } } } function grammarErrorAfterFirstToken(node, message, arg0, arg1, arg2) { var sourceFile = ts.getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { var span_5 = ts.getSpanOfTokenAtPosition(sourceFile, node.pos); diagnostics.add(ts.createFileDiagnostic(sourceFile, ts.textSpanEnd(span_5), /*length*/ 0, message, arg0, arg1, arg2)); return true; } } function getAmbientModules() { if (!ambientModulesCache) { ambientModulesCache = []; globals.forEach(function (global, sym) { // No need to `unescapeLeadingUnderscores`, an escaped symbol is never an ambient module. if (ambientModuleSymbolRegex.test(sym)) { ambientModulesCache.push(global); } }); } return ambientModulesCache; } function checkGrammarImportCallExpression(node) { if (modulekind === ts.ModuleKind.ES2015) { return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules); } if (node.typeArguments) { return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_cannot_have_type_arguments); } var nodeArguments = node.arguments; if (nodeArguments.length !== 1) { return grammarErrorOnNode(node, ts.Diagnostics.Dynamic_import_must_have_one_specifier_as_an_argument); } // see: parseArgumentOrArrayLiteralElement...we use this function which parse arguments of callExpression to parse specifier for dynamic import. // parseArgumentOrArrayLiteralElement allows spread element to be in an argument list which is not allowed as specifier in dynamic import. if (ts.isSpreadElement(nodeArguments[0])) { return grammarErrorOnNode(nodeArguments[0], ts.Diagnostics.Specifier_of_dynamic_import_cannot_be_spread_element); } } } ts.createTypeChecker = createTypeChecker; /** Like 'isDeclarationName', but returns true for LHS of `import { x as y }` or `export { x as y }`. */ function isDeclarationNameOrImportPropertyName(name) { switch (name.parent.kind) { case 243 /* ImportSpecifier */: case 247 /* ExportSpecifier */: return true; default: return ts.isDeclarationName(name); } } function isSomeImportDeclaration(decl) { switch (decl.kind) { case 240 /* ImportClause */: // For default import case 238 /* ImportEqualsDeclaration */: case 241 /* NamespaceImport */: case 243 /* ImportSpecifier */:// For rename import `x as y` return true; case 71 /* Identifier */: // For regular import, `decl` is an Identifier under the ImportSpecifier. return decl.parent.kind === 243 /* ImportSpecifier */; default: return false; } } var JsxNames; (function (JsxNames) { // tslint:disable variable-name JsxNames.JSX = "JSX"; JsxNames.IntrinsicElements = "IntrinsicElements"; JsxNames.ElementClass = "ElementClass"; JsxNames.ElementAttributesPropertyNameContainer = "ElementAttributesProperty"; JsxNames.ElementChildrenAttributeNameContainer = "ElementChildrenAttribute"; JsxNames.Element = "Element"; JsxNames.IntrinsicAttributes = "IntrinsicAttributes"; JsxNames.IntrinsicClassAttributes = "IntrinsicClassAttributes"; // tslint:enable variable-name })(JsxNames || (JsxNames = {})); })(ts || (ts = {})); /// /// var ts; (function (ts) { function createSynthesizedNode(kind) { var node = ts.createNode(kind, -1, -1); node.flags |= 8 /* Synthesized */; return node; } /* @internal */ function updateNode(updated, original) { if (updated !== original) { setOriginalNode(updated, original); setTextRange(updated, original); ts.aggregateTransformFlags(updated); } return updated; } ts.updateNode = updateNode; /** * Make `elements` into a `NodeArray`. If `elements` is `undefined`, returns an empty `NodeArray`. */ function createNodeArray(elements, hasTrailingComma) { if (elements) { if (ts.isNodeArray(elements)) { return elements; } } else { elements = []; } var array = elements; array.pos = -1; array.end = -1; array.hasTrailingComma = hasTrailingComma; return array; } ts.createNodeArray = createNodeArray; /** * Creates a shallow, memberwise clone of a node with no source map location. */ /* @internal */ function getSynthesizedClone(node) { // We don't use "clone" from core.ts here, as we need to preserve the prototype chain of // the original node. We also need to exclude specific properties and only include own- // properties (to skip members already defined on the shared prototype). if (node === undefined) { return undefined; } var clone = createSynthesizedNode(node.kind); clone.flags |= node.flags; setOriginalNode(clone, node); for (var key in node) { if (clone.hasOwnProperty(key) || !node.hasOwnProperty(key)) { continue; } clone[key] = node[key]; } return clone; } ts.getSynthesizedClone = getSynthesizedClone; function createLiteral(value) { if (typeof value === "number") { return createNumericLiteral(value + ""); } if (typeof value === "boolean") { return value ? createTrue() : createFalse(); } if (ts.isString(value)) { return createStringLiteral(value); } return createLiteralFromNode(value); } ts.createLiteral = createLiteral; function createNumericLiteral(value) { var node = createSynthesizedNode(8 /* NumericLiteral */); node.text = value; node.numericLiteralFlags = 0; return node; } ts.createNumericLiteral = createNumericLiteral; function createStringLiteral(text) { var node = createSynthesizedNode(9 /* StringLiteral */); node.text = text; return node; } function createLiteralFromNode(sourceNode) { var node = createStringLiteral(ts.getTextOfIdentifierOrLiteral(sourceNode)); node.textSourceNode = sourceNode; return node; } function createIdentifier(text, typeArguments) { var node = createSynthesizedNode(71 /* Identifier */); node.escapedText = ts.escapeLeadingUnderscores(text); node.originalKeywordKind = text ? ts.stringToToken(text) : 0 /* Unknown */; node.autoGenerateKind = 0 /* None */; node.autoGenerateId = 0; if (typeArguments) { node.typeArguments = createNodeArray(typeArguments); } return node; } ts.createIdentifier = createIdentifier; function updateIdentifier(node, typeArguments) { return node.typeArguments !== typeArguments ? updateNode(createIdentifier(ts.idText(node), typeArguments), node) : node; } ts.updateIdentifier = updateIdentifier; var nextAutoGenerateId = 0; /** Create a unique temporary variable. */ function createTempVariable(recordTempVariable) { var name = createIdentifier(""); name.autoGenerateKind = 1 /* Auto */; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; if (recordTempVariable) { recordTempVariable(name); } return name; } ts.createTempVariable = createTempVariable; /** Create a unique temporary variable for use in a loop. */ function createLoopVariable() { var name = createIdentifier(""); name.autoGenerateKind = 2 /* Loop */; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; } ts.createLoopVariable = createLoopVariable; /** Create a unique name based on the supplied text. */ function createUniqueName(text) { var name = createIdentifier(text); name.autoGenerateKind = 3 /* Unique */; name.autoGenerateId = nextAutoGenerateId; nextAutoGenerateId++; return name; } ts.createUniqueName = createUniqueName; function getGeneratedNameForNode(node, shouldSkipNameGenerationScope) { var name = createIdentifier(""); name.autoGenerateKind = 4 /* Node */; name.autoGenerateId = nextAutoGenerateId; name.original = node; name.skipNameGenerationScope = !!shouldSkipNameGenerationScope; nextAutoGenerateId++; return name; } ts.getGeneratedNameForNode = getGeneratedNameForNode; // Punctuation function createToken(token) { return createSynthesizedNode(token); } ts.createToken = createToken; // Reserved words function createSuper() { return createSynthesizedNode(97 /* SuperKeyword */); } ts.createSuper = createSuper; function createThis() { return createSynthesizedNode(99 /* ThisKeyword */); } ts.createThis = createThis; function createNull() { return createSynthesizedNode(95 /* NullKeyword */); } ts.createNull = createNull; function createTrue() { return createSynthesizedNode(101 /* TrueKeyword */); } ts.createTrue = createTrue; function createFalse() { return createSynthesizedNode(86 /* FalseKeyword */); } ts.createFalse = createFalse; // Names function createQualifiedName(left, right) { var node = createSynthesizedNode(144 /* QualifiedName */); node.left = left; node.right = asName(right); return node; } ts.createQualifiedName = createQualifiedName; function updateQualifiedName(node, left, right) { return node.left !== left || node.right !== right ? updateNode(createQualifiedName(left, right), node) : node; } ts.updateQualifiedName = updateQualifiedName; function createComputedPropertyName(expression) { var node = createSynthesizedNode(145 /* ComputedPropertyName */); node.expression = expression; return node; } ts.createComputedPropertyName = createComputedPropertyName; function updateComputedPropertyName(node, expression) { return node.expression !== expression ? updateNode(createComputedPropertyName(expression), node) : node; } ts.updateComputedPropertyName = updateComputedPropertyName; // Signature elements function createTypeParameterDeclaration(name, constraint, defaultType) { var node = createSynthesizedNode(146 /* TypeParameter */); node.name = asName(name); node.constraint = constraint; node.default = defaultType; return node; } ts.createTypeParameterDeclaration = createTypeParameterDeclaration; function updateTypeParameterDeclaration(node, name, constraint, defaultType) { return node.name !== name || node.constraint !== constraint || node.default !== defaultType ? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node) : node; } ts.updateTypeParameterDeclaration = updateTypeParameterDeclaration; function createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) { var node = createSynthesizedNode(147 /* Parameter */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.dotDotDotToken = dotDotDotToken; node.name = asName(name); node.questionToken = questionToken; node.type = type; node.initializer = initializer ? ts.parenthesizeExpressionForList(initializer) : undefined; return node; } ts.createParameter = createParameter; function updateParameter(node, decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer) { return node.decorators !== decorators || node.modifiers !== modifiers || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer ? updateNode(createParameter(decorators, modifiers, dotDotDotToken, name, questionToken, type, initializer), node) : node; } ts.updateParameter = updateParameter; function createDecorator(expression) { var node = createSynthesizedNode(148 /* Decorator */); node.expression = ts.parenthesizeForAccess(expression); return node; } ts.createDecorator = createDecorator; function updateDecorator(node, expression) { return node.expression !== expression ? updateNode(createDecorator(expression), node) : node; } ts.updateDecorator = updateDecorator; // Type Elements function createPropertySignature(modifiers, name, questionToken, type, initializer) { var node = createSynthesizedNode(149 /* PropertySignature */); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.questionToken = questionToken; node.type = type; node.initializer = initializer; return node; } ts.createPropertySignature = createPropertySignature; function updatePropertySignature(node, modifiers, name, questionToken, type, initializer) { return node.modifiers !== modifiers || node.name !== name || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer ? updateNode(createPropertySignature(modifiers, name, questionToken, type, initializer), node) : node; } ts.updatePropertySignature = updatePropertySignature; function createProperty(decorators, modifiers, name, questionToken, type, initializer) { var node = createSynthesizedNode(150 /* PropertyDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.questionToken = questionToken; node.type = type; node.initializer = initializer; return node; } ts.createProperty = createProperty; function updateProperty(node, decorators, modifiers, name, questionToken, type, initializer) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.questionToken !== questionToken || node.type !== type || node.initializer !== initializer ? updateNode(createProperty(decorators, modifiers, name, questionToken, type, initializer), node) : node; } ts.updateProperty = updateProperty; function createMethodSignature(typeParameters, parameters, type, name, questionToken) { var node = createSignatureDeclaration(151 /* MethodSignature */, typeParameters, parameters, type); node.name = asName(name); node.questionToken = questionToken; return node; } ts.createMethodSignature = createMethodSignature; function updateMethodSignature(node, typeParameters, parameters, type, name, questionToken) { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.name !== name || node.questionToken !== questionToken ? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node) : node; } ts.updateMethodSignature = updateMethodSignature; function createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) { var node = createSynthesizedNode(152 /* MethodDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; node.name = asName(name); node.questionToken = questionToken; node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; return node; } ts.createMethod = createMethod; function updateMethod(node, decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken || node.name !== name || node.questionToken !== questionToken || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body ? updateNode(createMethod(decorators, modifiers, asteriskToken, name, questionToken, typeParameters, parameters, type, body), node) : node; } ts.updateMethod = updateMethod; function createConstructor(decorators, modifiers, parameters, body) { var node = createSynthesizedNode(153 /* Constructor */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.type = undefined; node.body = body; return node; } ts.createConstructor = createConstructor; function updateConstructor(node, decorators, modifiers, parameters, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.parameters !== parameters || node.body !== body ? updateNode(createConstructor(decorators, modifiers, parameters, body), node) : node; } ts.updateConstructor = updateConstructor; function createGetAccessor(decorators, modifiers, name, parameters, type, body) { var node = createSynthesizedNode(154 /* GetAccessor */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.type = type; node.body = body; return node; } ts.createGetAccessor = createGetAccessor; function updateGetAccessor(node, decorators, modifiers, name, parameters, type, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.type !== type || node.body !== body ? updateNode(createGetAccessor(decorators, modifiers, name, parameters, type, body), node) : node; } ts.updateGetAccessor = updateGetAccessor; function createSetAccessor(decorators, modifiers, name, parameters, body) { var node = createSynthesizedNode(155 /* SetAccessor */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = undefined; node.parameters = createNodeArray(parameters); node.body = body; return node; } ts.createSetAccessor = createSetAccessor; function updateSetAccessor(node, decorators, modifiers, name, parameters, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.parameters !== parameters || node.body !== body ? updateNode(createSetAccessor(decorators, modifiers, name, parameters, body), node) : node; } ts.updateSetAccessor = updateSetAccessor; function createCallSignature(typeParameters, parameters, type) { return createSignatureDeclaration(156 /* CallSignature */, typeParameters, parameters, type); } ts.createCallSignature = createCallSignature; function updateCallSignature(node, typeParameters, parameters, type) { return updateSignatureDeclaration(node, typeParameters, parameters, type); } ts.updateCallSignature = updateCallSignature; function createConstructSignature(typeParameters, parameters, type) { return createSignatureDeclaration(157 /* ConstructSignature */, typeParameters, parameters, type); } ts.createConstructSignature = createConstructSignature; function updateConstructSignature(node, typeParameters, parameters, type) { return updateSignatureDeclaration(node, typeParameters, parameters, type); } ts.updateConstructSignature = updateConstructSignature; function createIndexSignature(decorators, modifiers, parameters, type) { var node = createSynthesizedNode(158 /* IndexSignature */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.parameters = createNodeArray(parameters); node.type = type; return node; } ts.createIndexSignature = createIndexSignature; function updateIndexSignature(node, decorators, modifiers, parameters, type) { return node.parameters !== parameters || node.type !== type || node.decorators !== decorators || node.modifiers !== modifiers ? updateNode(createIndexSignature(decorators, modifiers, parameters, type), node) : node; } ts.updateIndexSignature = updateIndexSignature; /* @internal */ function createSignatureDeclaration(kind, typeParameters, parameters, type) { var node = createSynthesizedNode(kind); node.typeParameters = asNodeArray(typeParameters); node.parameters = asNodeArray(parameters); node.type = type; return node; } ts.createSignatureDeclaration = createSignatureDeclaration; function updateSignatureDeclaration(node, typeParameters, parameters, type) { return node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type ? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node) : node; } // Types function createKeywordTypeNode(kind) { return createSynthesizedNode(kind); } ts.createKeywordTypeNode = createKeywordTypeNode; function createTypePredicateNode(parameterName, type) { var node = createSynthesizedNode(159 /* TypePredicate */); node.parameterName = asName(parameterName); node.type = type; return node; } ts.createTypePredicateNode = createTypePredicateNode; function updateTypePredicateNode(node, parameterName, type) { return node.parameterName !== parameterName || node.type !== type ? updateNode(createTypePredicateNode(parameterName, type), node) : node; } ts.updateTypePredicateNode = updateTypePredicateNode; function createTypeReferenceNode(typeName, typeArguments) { var node = createSynthesizedNode(160 /* TypeReference */); node.typeName = asName(typeName); node.typeArguments = typeArguments && ts.parenthesizeTypeParameters(typeArguments); return node; } ts.createTypeReferenceNode = createTypeReferenceNode; function updateTypeReferenceNode(node, typeName, typeArguments) { return node.typeName !== typeName || node.typeArguments !== typeArguments ? updateNode(createTypeReferenceNode(typeName, typeArguments), node) : node; } ts.updateTypeReferenceNode = updateTypeReferenceNode; function createFunctionTypeNode(typeParameters, parameters, type) { return createSignatureDeclaration(161 /* FunctionType */, typeParameters, parameters, type); } ts.createFunctionTypeNode = createFunctionTypeNode; function updateFunctionTypeNode(node, typeParameters, parameters, type) { return updateSignatureDeclaration(node, typeParameters, parameters, type); } ts.updateFunctionTypeNode = updateFunctionTypeNode; function createConstructorTypeNode(typeParameters, parameters, type) { return createSignatureDeclaration(162 /* ConstructorType */, typeParameters, parameters, type); } ts.createConstructorTypeNode = createConstructorTypeNode; function updateConstructorTypeNode(node, typeParameters, parameters, type) { return updateSignatureDeclaration(node, typeParameters, parameters, type); } ts.updateConstructorTypeNode = updateConstructorTypeNode; function createTypeQueryNode(exprName) { var node = createSynthesizedNode(163 /* TypeQuery */); node.exprName = exprName; return node; } ts.createTypeQueryNode = createTypeQueryNode; function updateTypeQueryNode(node, exprName) { return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName), node) : node; } ts.updateTypeQueryNode = updateTypeQueryNode; function createTypeLiteralNode(members) { var node = createSynthesizedNode(164 /* TypeLiteral */); node.members = createNodeArray(members); return node; } ts.createTypeLiteralNode = createTypeLiteralNode; function updateTypeLiteralNode(node, members) { return node.members !== members ? updateNode(createTypeLiteralNode(members), node) : node; } ts.updateTypeLiteralNode = updateTypeLiteralNode; function createArrayTypeNode(elementType) { var node = createSynthesizedNode(165 /* ArrayType */); node.elementType = ts.parenthesizeArrayTypeMember(elementType); return node; } ts.createArrayTypeNode = createArrayTypeNode; function updateArrayTypeNode(node, elementType) { return node.elementType !== elementType ? updateNode(createArrayTypeNode(elementType), node) : node; } ts.updateArrayTypeNode = updateArrayTypeNode; function createTupleTypeNode(elementTypes) { var node = createSynthesizedNode(166 /* TupleType */); node.elementTypes = createNodeArray(elementTypes); return node; } ts.createTupleTypeNode = createTupleTypeNode; function updateTypleTypeNode(node, elementTypes) { return node.elementTypes !== elementTypes ? updateNode(createTupleTypeNode(elementTypes), node) : node; } ts.updateTypleTypeNode = updateTypleTypeNode; function createUnionTypeNode(types) { return createUnionOrIntersectionTypeNode(167 /* UnionType */, types); } ts.createUnionTypeNode = createUnionTypeNode; function updateUnionTypeNode(node, types) { return updateUnionOrIntersectionTypeNode(node, types); } ts.updateUnionTypeNode = updateUnionTypeNode; function createIntersectionTypeNode(types) { return createUnionOrIntersectionTypeNode(168 /* IntersectionType */, types); } ts.createIntersectionTypeNode = createIntersectionTypeNode; function updateIntersectionTypeNode(node, types) { return updateUnionOrIntersectionTypeNode(node, types); } ts.updateIntersectionTypeNode = updateIntersectionTypeNode; function createUnionOrIntersectionTypeNode(kind, types) { var node = createSynthesizedNode(kind); node.types = ts.parenthesizeElementTypeMembers(types); return node; } ts.createUnionOrIntersectionTypeNode = createUnionOrIntersectionTypeNode; function updateUnionOrIntersectionTypeNode(node, types) { return node.types !== types ? updateNode(createUnionOrIntersectionTypeNode(node.kind, types), node) : node; } function createParenthesizedType(type) { var node = createSynthesizedNode(169 /* ParenthesizedType */); node.type = type; return node; } ts.createParenthesizedType = createParenthesizedType; function updateParenthesizedType(node, type) { return node.type !== type ? updateNode(createParenthesizedType(type), node) : node; } ts.updateParenthesizedType = updateParenthesizedType; function createThisTypeNode() { return createSynthesizedNode(170 /* ThisType */); } ts.createThisTypeNode = createThisTypeNode; function createTypeOperatorNode(operatorOrType, type) { var node = createSynthesizedNode(171 /* TypeOperator */); node.operator = typeof operatorOrType === "number" ? operatorOrType : 127 /* KeyOfKeyword */; node.type = ts.parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type : operatorOrType); return node; } ts.createTypeOperatorNode = createTypeOperatorNode; function updateTypeOperatorNode(node, type) { return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node; } ts.updateTypeOperatorNode = updateTypeOperatorNode; function createIndexedAccessTypeNode(objectType, indexType) { var node = createSynthesizedNode(172 /* IndexedAccessType */); node.objectType = ts.parenthesizeElementTypeMember(objectType); node.indexType = indexType; return node; } ts.createIndexedAccessTypeNode = createIndexedAccessTypeNode; function updateIndexedAccessTypeNode(node, objectType, indexType) { return node.objectType !== objectType || node.indexType !== indexType ? updateNode(createIndexedAccessTypeNode(objectType, indexType), node) : node; } ts.updateIndexedAccessTypeNode = updateIndexedAccessTypeNode; function createMappedTypeNode(readonlyToken, typeParameter, questionToken, type) { var node = createSynthesizedNode(173 /* MappedType */); node.readonlyToken = readonlyToken; node.typeParameter = typeParameter; node.questionToken = questionToken; node.type = type; return node; } ts.createMappedTypeNode = createMappedTypeNode; function updateMappedTypeNode(node, readonlyToken, typeParameter, questionToken, type) { return node.readonlyToken !== readonlyToken || node.typeParameter !== typeParameter || node.questionToken !== questionToken || node.type !== type ? updateNode(createMappedTypeNode(readonlyToken, typeParameter, questionToken, type), node) : node; } ts.updateMappedTypeNode = updateMappedTypeNode; function createLiteralTypeNode(literal) { var node = createSynthesizedNode(174 /* LiteralType */); node.literal = literal; return node; } ts.createLiteralTypeNode = createLiteralTypeNode; function updateLiteralTypeNode(node, literal) { return node.literal !== literal ? updateNode(createLiteralTypeNode(literal), node) : node; } ts.updateLiteralTypeNode = updateLiteralTypeNode; // Binding Patterns function createObjectBindingPattern(elements) { var node = createSynthesizedNode(175 /* ObjectBindingPattern */); node.elements = createNodeArray(elements); return node; } ts.createObjectBindingPattern = createObjectBindingPattern; function updateObjectBindingPattern(node, elements) { return node.elements !== elements ? updateNode(createObjectBindingPattern(elements), node) : node; } ts.updateObjectBindingPattern = updateObjectBindingPattern; function createArrayBindingPattern(elements) { var node = createSynthesizedNode(176 /* ArrayBindingPattern */); node.elements = createNodeArray(elements); return node; } ts.createArrayBindingPattern = createArrayBindingPattern; function updateArrayBindingPattern(node, elements) { return node.elements !== elements ? updateNode(createArrayBindingPattern(elements), node) : node; } ts.updateArrayBindingPattern = updateArrayBindingPattern; function createBindingElement(dotDotDotToken, propertyName, name, initializer) { var node = createSynthesizedNode(177 /* BindingElement */); node.dotDotDotToken = dotDotDotToken; node.propertyName = asName(propertyName); node.name = asName(name); node.initializer = initializer; return node; } ts.createBindingElement = createBindingElement; function updateBindingElement(node, dotDotDotToken, propertyName, name, initializer) { return node.propertyName !== propertyName || node.dotDotDotToken !== dotDotDotToken || node.name !== name || node.initializer !== initializer ? updateNode(createBindingElement(dotDotDotToken, propertyName, name, initializer), node) : node; } ts.updateBindingElement = updateBindingElement; // Expression function createArrayLiteral(elements, multiLine) { var node = createSynthesizedNode(178 /* ArrayLiteralExpression */); node.elements = ts.parenthesizeListElements(createNodeArray(elements)); if (multiLine) node.multiLine = true; return node; } ts.createArrayLiteral = createArrayLiteral; function updateArrayLiteral(node, elements) { return node.elements !== elements ? updateNode(createArrayLiteral(elements, node.multiLine), node) : node; } ts.updateArrayLiteral = updateArrayLiteral; function createObjectLiteral(properties, multiLine) { var node = createSynthesizedNode(179 /* ObjectLiteralExpression */); node.properties = createNodeArray(properties); if (multiLine) node.multiLine = true; return node; } ts.createObjectLiteral = createObjectLiteral; function updateObjectLiteral(node, properties) { return node.properties !== properties ? updateNode(createObjectLiteral(properties, node.multiLine), node) : node; } ts.updateObjectLiteral = updateObjectLiteral; function createPropertyAccess(expression, name) { var node = createSynthesizedNode(180 /* PropertyAccessExpression */); node.expression = ts.parenthesizeForAccess(expression); node.name = asName(name); setEmitFlags(node, 131072 /* NoIndentation */); return node; } ts.createPropertyAccess = createPropertyAccess; function updatePropertyAccess(node, expression, name) { // Because we are updating existed propertyAccess we want to inherit its emitFlags // instead of using the default from createPropertyAccess return node.expression !== expression || node.name !== name ? updateNode(setEmitFlags(createPropertyAccess(expression, name), ts.getEmitFlags(node)), node) : node; } ts.updatePropertyAccess = updatePropertyAccess; function createElementAccess(expression, index) { var node = createSynthesizedNode(181 /* ElementAccessExpression */); node.expression = ts.parenthesizeForAccess(expression); node.argumentExpression = asExpression(index); return node; } ts.createElementAccess = createElementAccess; function updateElementAccess(node, expression, argumentExpression) { return node.expression !== expression || node.argumentExpression !== argumentExpression ? updateNode(createElementAccess(expression, argumentExpression), node) : node; } ts.updateElementAccess = updateElementAccess; function createCall(expression, typeArguments, argumentsArray) { var node = createSynthesizedNode(182 /* CallExpression */); node.expression = ts.parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); node.arguments = ts.parenthesizeListElements(createNodeArray(argumentsArray)); return node; } ts.createCall = createCall; function updateCall(node, expression, typeArguments, argumentsArray) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray ? updateNode(createCall(expression, typeArguments, argumentsArray), node) : node; } ts.updateCall = updateCall; function createNew(expression, typeArguments, argumentsArray) { var node = createSynthesizedNode(183 /* NewExpression */); node.expression = ts.parenthesizeForNew(expression); node.typeArguments = asNodeArray(typeArguments); node.arguments = argumentsArray ? ts.parenthesizeListElements(createNodeArray(argumentsArray)) : undefined; return node; } ts.createNew = createNew; function updateNew(node, expression, typeArguments, argumentsArray) { return node.expression !== expression || node.typeArguments !== typeArguments || node.arguments !== argumentsArray ? updateNode(createNew(expression, typeArguments, argumentsArray), node) : node; } ts.updateNew = updateNew; function createTaggedTemplate(tag, template) { var node = createSynthesizedNode(184 /* TaggedTemplateExpression */); node.tag = ts.parenthesizeForAccess(tag); node.template = template; return node; } ts.createTaggedTemplate = createTaggedTemplate; function updateTaggedTemplate(node, tag, template) { return node.tag !== tag || node.template !== template ? updateNode(createTaggedTemplate(tag, template), node) : node; } ts.updateTaggedTemplate = updateTaggedTemplate; function createTypeAssertion(type, expression) { var node = createSynthesizedNode(185 /* TypeAssertionExpression */); node.type = type; node.expression = ts.parenthesizePrefixOperand(expression); return node; } ts.createTypeAssertion = createTypeAssertion; function updateTypeAssertion(node, type, expression) { return node.type !== type || node.expression !== expression ? updateNode(createTypeAssertion(type, expression), node) : node; } ts.updateTypeAssertion = updateTypeAssertion; function createParen(expression) { var node = createSynthesizedNode(186 /* ParenthesizedExpression */); node.expression = expression; return node; } ts.createParen = createParen; function updateParen(node, expression) { return node.expression !== expression ? updateNode(createParen(expression), node) : node; } ts.updateParen = updateParen; function createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body) { var node = createSynthesizedNode(187 /* FunctionExpression */); node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; return node; } ts.createFunctionExpression = createFunctionExpression; function updateFunctionExpression(node, modifiers, asteriskToken, name, typeParameters, parameters, type, body) { return node.name !== name || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body ? updateNode(createFunctionExpression(modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) : node; } ts.updateFunctionExpression = updateFunctionExpression; function createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body) { var node = createSynthesizedNode(188 /* ArrowFunction */); node.modifiers = asNodeArray(modifiers); node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.equalsGreaterThanToken = equalsGreaterThanToken || createToken(36 /* EqualsGreaterThanToken */); node.body = ts.parenthesizeConciseBody(body); return node; } ts.createArrowFunction = createArrowFunction; function updateArrowFunction(node, modifiers, typeParameters, parameters, type, equalsGreaterThanTokenOrBody, bodyOrUndefined) { var equalsGreaterThanToken; var body; if (bodyOrUndefined === undefined) { equalsGreaterThanToken = node.equalsGreaterThanToken; body = ts.cast(equalsGreaterThanTokenOrBody, ts.isConciseBody); } else { equalsGreaterThanToken = ts.cast(equalsGreaterThanTokenOrBody, function (n) { return n.kind === 36 /* EqualsGreaterThanToken */; }); body = bodyOrUndefined; } return node.modifiers !== modifiers || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.equalsGreaterThanToken !== equalsGreaterThanToken || node.body !== body ? updateNode(createArrowFunction(modifiers, typeParameters, parameters, type, equalsGreaterThanToken, body), node) : node; } ts.updateArrowFunction = updateArrowFunction; function createDelete(expression) { var node = createSynthesizedNode(189 /* DeleteExpression */); node.expression = ts.parenthesizePrefixOperand(expression); return node; } ts.createDelete = createDelete; function updateDelete(node, expression) { return node.expression !== expression ? updateNode(createDelete(expression), node) : node; } ts.updateDelete = updateDelete; function createTypeOf(expression) { var node = createSynthesizedNode(190 /* TypeOfExpression */); node.expression = ts.parenthesizePrefixOperand(expression); return node; } ts.createTypeOf = createTypeOf; function updateTypeOf(node, expression) { return node.expression !== expression ? updateNode(createTypeOf(expression), node) : node; } ts.updateTypeOf = updateTypeOf; function createVoid(expression) { var node = createSynthesizedNode(191 /* VoidExpression */); node.expression = ts.parenthesizePrefixOperand(expression); return node; } ts.createVoid = createVoid; function updateVoid(node, expression) { return node.expression !== expression ? updateNode(createVoid(expression), node) : node; } ts.updateVoid = updateVoid; function createAwait(expression) { var node = createSynthesizedNode(192 /* AwaitExpression */); node.expression = ts.parenthesizePrefixOperand(expression); return node; } ts.createAwait = createAwait; function updateAwait(node, expression) { return node.expression !== expression ? updateNode(createAwait(expression), node) : node; } ts.updateAwait = updateAwait; function createPrefix(operator, operand) { var node = createSynthesizedNode(193 /* PrefixUnaryExpression */); node.operator = operator; node.operand = ts.parenthesizePrefixOperand(operand); return node; } ts.createPrefix = createPrefix; function updatePrefix(node, operand) { return node.operand !== operand ? updateNode(createPrefix(node.operator, operand), node) : node; } ts.updatePrefix = updatePrefix; function createPostfix(operand, operator) { var node = createSynthesizedNode(194 /* PostfixUnaryExpression */); node.operand = ts.parenthesizePostfixOperand(operand); node.operator = operator; return node; } ts.createPostfix = createPostfix; function updatePostfix(node, operand) { return node.operand !== operand ? updateNode(createPostfix(operand, node.operator), node) : node; } ts.updatePostfix = updatePostfix; function createBinary(left, operator, right) { var node = createSynthesizedNode(195 /* BinaryExpression */); var operatorToken = asToken(operator); var operatorKind = operatorToken.kind; node.left = ts.parenthesizeBinaryOperand(operatorKind, left, /*isLeftSideOfBinary*/ true, /*leftOperand*/ undefined); node.operatorToken = operatorToken; node.right = ts.parenthesizeBinaryOperand(operatorKind, right, /*isLeftSideOfBinary*/ false, node.left); return node; } ts.createBinary = createBinary; function updateBinary(node, left, right, operator) { return node.left !== left || node.right !== right ? updateNode(createBinary(left, operator || node.operatorToken, right), node) : node; } ts.updateBinary = updateBinary; function createConditional(condition, questionTokenOrWhenTrue, whenTrueOrWhenFalse, colonToken, whenFalse) { var node = createSynthesizedNode(196 /* ConditionalExpression */); node.condition = ts.parenthesizeForConditionalHead(condition); node.questionToken = whenFalse ? questionTokenOrWhenTrue : createToken(55 /* QuestionToken */); node.whenTrue = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenTrueOrWhenFalse : questionTokenOrWhenTrue); node.colonToken = whenFalse ? colonToken : createToken(56 /* ColonToken */); node.whenFalse = ts.parenthesizeSubexpressionOfConditionalExpression(whenFalse ? whenFalse : whenTrueOrWhenFalse); return node; } ts.createConditional = createConditional; function updateConditional(node, condition) { var args = []; for (var _i = 2; _i < arguments.length; _i++) { args[_i - 2] = arguments[_i]; } if (args.length === 2) { var whenTrue_1 = args[0], whenFalse_1 = args[1]; return updateConditional(node, condition, node.questionToken, whenTrue_1, node.colonToken, whenFalse_1); } ts.Debug.assert(args.length === 4); var questionToken = args[0], whenTrue = args[1], colonToken = args[2], whenFalse = args[3]; return node.condition !== condition || node.questionToken !== questionToken || node.whenTrue !== whenTrue || node.colonToken !== colonToken || node.whenFalse !== whenFalse ? updateNode(createConditional(condition, questionToken, whenTrue, colonToken, whenFalse), node) : node; } ts.updateConditional = updateConditional; function createTemplateExpression(head, templateSpans) { var node = createSynthesizedNode(197 /* TemplateExpression */); node.head = head; node.templateSpans = createNodeArray(templateSpans); return node; } ts.createTemplateExpression = createTemplateExpression; function updateTemplateExpression(node, head, templateSpans) { return node.head !== head || node.templateSpans !== templateSpans ? updateNode(createTemplateExpression(head, templateSpans), node) : node; } ts.updateTemplateExpression = updateTemplateExpression; function createTemplateHead(text) { var node = createSynthesizedNode(14 /* TemplateHead */); node.text = text; return node; } ts.createTemplateHead = createTemplateHead; function createTemplateMiddle(text) { var node = createSynthesizedNode(15 /* TemplateMiddle */); node.text = text; return node; } ts.createTemplateMiddle = createTemplateMiddle; function createTemplateTail(text) { var node = createSynthesizedNode(16 /* TemplateTail */); node.text = text; return node; } ts.createTemplateTail = createTemplateTail; function createNoSubstitutionTemplateLiteral(text) { var node = createSynthesizedNode(13 /* NoSubstitutionTemplateLiteral */); node.text = text; return node; } ts.createNoSubstitutionTemplateLiteral = createNoSubstitutionTemplateLiteral; function createYield(asteriskTokenOrExpression, expression) { var node = createSynthesizedNode(198 /* YieldExpression */); node.asteriskToken = asteriskTokenOrExpression && asteriskTokenOrExpression.kind === 39 /* AsteriskToken */ ? asteriskTokenOrExpression : undefined; node.expression = asteriskTokenOrExpression && asteriskTokenOrExpression.kind !== 39 /* AsteriskToken */ ? asteriskTokenOrExpression : expression; return node; } ts.createYield = createYield; function updateYield(node, asteriskToken, expression) { return node.expression !== expression || node.asteriskToken !== asteriskToken ? updateNode(createYield(asteriskToken, expression), node) : node; } ts.updateYield = updateYield; function createSpread(expression) { var node = createSynthesizedNode(199 /* SpreadElement */); node.expression = ts.parenthesizeExpressionForList(expression); return node; } ts.createSpread = createSpread; function updateSpread(node, expression) { return node.expression !== expression ? updateNode(createSpread(expression), node) : node; } ts.updateSpread = updateSpread; function createClassExpression(modifiers, name, typeParameters, heritageClauses, members) { var node = createSynthesizedNode(200 /* ClassExpression */); node.decorators = undefined; node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.heritageClauses = asNodeArray(heritageClauses); node.members = createNodeArray(members); return node; } ts.createClassExpression = createClassExpression; function updateClassExpression(node, modifiers, name, typeParameters, heritageClauses, members) { return node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members ? updateNode(createClassExpression(modifiers, name, typeParameters, heritageClauses, members), node) : node; } ts.updateClassExpression = updateClassExpression; function createOmittedExpression() { return createSynthesizedNode(201 /* OmittedExpression */); } ts.createOmittedExpression = createOmittedExpression; function createExpressionWithTypeArguments(typeArguments, expression) { var node = createSynthesizedNode(202 /* ExpressionWithTypeArguments */); node.expression = ts.parenthesizeForAccess(expression); node.typeArguments = asNodeArray(typeArguments); return node; } ts.createExpressionWithTypeArguments = createExpressionWithTypeArguments; function updateExpressionWithTypeArguments(node, typeArguments, expression) { return node.typeArguments !== typeArguments || node.expression !== expression ? updateNode(createExpressionWithTypeArguments(typeArguments, expression), node) : node; } ts.updateExpressionWithTypeArguments = updateExpressionWithTypeArguments; function createAsExpression(expression, type) { var node = createSynthesizedNode(203 /* AsExpression */); node.expression = expression; node.type = type; return node; } ts.createAsExpression = createAsExpression; function updateAsExpression(node, expression, type) { return node.expression !== expression || node.type !== type ? updateNode(createAsExpression(expression, type), node) : node; } ts.updateAsExpression = updateAsExpression; function createNonNullExpression(expression) { var node = createSynthesizedNode(204 /* NonNullExpression */); node.expression = ts.parenthesizeForAccess(expression); return node; } ts.createNonNullExpression = createNonNullExpression; function updateNonNullExpression(node, expression) { return node.expression !== expression ? updateNode(createNonNullExpression(expression), node) : node; } ts.updateNonNullExpression = updateNonNullExpression; function createMetaProperty(keywordToken, name) { var node = createSynthesizedNode(205 /* MetaProperty */); node.keywordToken = keywordToken; node.name = name; return node; } ts.createMetaProperty = createMetaProperty; function updateMetaProperty(node, name) { return node.name !== name ? updateNode(createMetaProperty(node.keywordToken, name), node) : node; } ts.updateMetaProperty = updateMetaProperty; // Misc function createTemplateSpan(expression, literal) { var node = createSynthesizedNode(206 /* TemplateSpan */); node.expression = expression; node.literal = literal; return node; } ts.createTemplateSpan = createTemplateSpan; function updateTemplateSpan(node, expression, literal) { return node.expression !== expression || node.literal !== literal ? updateNode(createTemplateSpan(expression, literal), node) : node; } ts.updateTemplateSpan = updateTemplateSpan; function createSemicolonClassElement() { return createSynthesizedNode(207 /* SemicolonClassElement */); } ts.createSemicolonClassElement = createSemicolonClassElement; // Element function createBlock(statements, multiLine) { var block = createSynthesizedNode(208 /* Block */); block.statements = createNodeArray(statements); if (multiLine) block.multiLine = multiLine; return block; } ts.createBlock = createBlock; function updateBlock(node, statements) { return node.statements !== statements ? updateNode(createBlock(statements, node.multiLine), node) : node; } ts.updateBlock = updateBlock; function createVariableStatement(modifiers, declarationList) { var node = createSynthesizedNode(209 /* VariableStatement */); node.decorators = undefined; node.modifiers = asNodeArray(modifiers); node.declarationList = ts.isArray(declarationList) ? createVariableDeclarationList(declarationList) : declarationList; return node; } ts.createVariableStatement = createVariableStatement; function updateVariableStatement(node, modifiers, declarationList) { return node.modifiers !== modifiers || node.declarationList !== declarationList ? updateNode(createVariableStatement(modifiers, declarationList), node) : node; } ts.updateVariableStatement = updateVariableStatement; function createEmptyStatement() { return createSynthesizedNode(210 /* EmptyStatement */); } ts.createEmptyStatement = createEmptyStatement; function createStatement(expression) { var node = createSynthesizedNode(211 /* ExpressionStatement */); node.expression = ts.parenthesizeExpressionForExpressionStatement(expression); return node; } ts.createStatement = createStatement; function updateStatement(node, expression) { return node.expression !== expression ? updateNode(createStatement(expression), node) : node; } ts.updateStatement = updateStatement; function createIf(expression, thenStatement, elseStatement) { var node = createSynthesizedNode(212 /* IfStatement */); node.expression = expression; node.thenStatement = thenStatement; node.elseStatement = elseStatement; return node; } ts.createIf = createIf; function updateIf(node, expression, thenStatement, elseStatement) { return node.expression !== expression || node.thenStatement !== thenStatement || node.elseStatement !== elseStatement ? updateNode(createIf(expression, thenStatement, elseStatement), node) : node; } ts.updateIf = updateIf; function createDo(statement, expression) { var node = createSynthesizedNode(213 /* DoStatement */); node.statement = statement; node.expression = expression; return node; } ts.createDo = createDo; function updateDo(node, statement, expression) { return node.statement !== statement || node.expression !== expression ? updateNode(createDo(statement, expression), node) : node; } ts.updateDo = updateDo; function createWhile(expression, statement) { var node = createSynthesizedNode(214 /* WhileStatement */); node.expression = expression; node.statement = statement; return node; } ts.createWhile = createWhile; function updateWhile(node, expression, statement) { return node.expression !== expression || node.statement !== statement ? updateNode(createWhile(expression, statement), node) : node; } ts.updateWhile = updateWhile; function createFor(initializer, condition, incrementor, statement) { var node = createSynthesizedNode(215 /* ForStatement */); node.initializer = initializer; node.condition = condition; node.incrementor = incrementor; node.statement = statement; return node; } ts.createFor = createFor; function updateFor(node, initializer, condition, incrementor, statement) { return node.initializer !== initializer || node.condition !== condition || node.incrementor !== incrementor || node.statement !== statement ? updateNode(createFor(initializer, condition, incrementor, statement), node) : node; } ts.updateFor = updateFor; function createForIn(initializer, expression, statement) { var node = createSynthesizedNode(216 /* ForInStatement */); node.initializer = initializer; node.expression = expression; node.statement = statement; return node; } ts.createForIn = createForIn; function updateForIn(node, initializer, expression, statement) { return node.initializer !== initializer || node.expression !== expression || node.statement !== statement ? updateNode(createForIn(initializer, expression, statement), node) : node; } ts.updateForIn = updateForIn; function createForOf(awaitModifier, initializer, expression, statement) { var node = createSynthesizedNode(217 /* ForOfStatement */); node.awaitModifier = awaitModifier; node.initializer = initializer; node.expression = expression; node.statement = statement; return node; } ts.createForOf = createForOf; function updateForOf(node, awaitModifier, initializer, expression, statement) { return node.awaitModifier !== awaitModifier || node.initializer !== initializer || node.expression !== expression || node.statement !== statement ? updateNode(createForOf(awaitModifier, initializer, expression, statement), node) : node; } ts.updateForOf = updateForOf; function createContinue(label) { var node = createSynthesizedNode(218 /* ContinueStatement */); node.label = asName(label); return node; } ts.createContinue = createContinue; function updateContinue(node, label) { return node.label !== label ? updateNode(createContinue(label), node) : node; } ts.updateContinue = updateContinue; function createBreak(label) { var node = createSynthesizedNode(219 /* BreakStatement */); node.label = asName(label); return node; } ts.createBreak = createBreak; function updateBreak(node, label) { return node.label !== label ? updateNode(createBreak(label), node) : node; } ts.updateBreak = updateBreak; function createReturn(expression) { var node = createSynthesizedNode(220 /* ReturnStatement */); node.expression = expression; return node; } ts.createReturn = createReturn; function updateReturn(node, expression) { return node.expression !== expression ? updateNode(createReturn(expression), node) : node; } ts.updateReturn = updateReturn; function createWith(expression, statement) { var node = createSynthesizedNode(221 /* WithStatement */); node.expression = expression; node.statement = statement; return node; } ts.createWith = createWith; function updateWith(node, expression, statement) { return node.expression !== expression || node.statement !== statement ? updateNode(createWith(expression, statement), node) : node; } ts.updateWith = updateWith; function createSwitch(expression, caseBlock) { var node = createSynthesizedNode(222 /* SwitchStatement */); node.expression = ts.parenthesizeExpressionForList(expression); node.caseBlock = caseBlock; return node; } ts.createSwitch = createSwitch; function updateSwitch(node, expression, caseBlock) { return node.expression !== expression || node.caseBlock !== caseBlock ? updateNode(createSwitch(expression, caseBlock), node) : node; } ts.updateSwitch = updateSwitch; function createLabel(label, statement) { var node = createSynthesizedNode(223 /* LabeledStatement */); node.label = asName(label); node.statement = statement; return node; } ts.createLabel = createLabel; function updateLabel(node, label, statement) { return node.label !== label || node.statement !== statement ? updateNode(createLabel(label, statement), node) : node; } ts.updateLabel = updateLabel; function createThrow(expression) { var node = createSynthesizedNode(224 /* ThrowStatement */); node.expression = expression; return node; } ts.createThrow = createThrow; function updateThrow(node, expression) { return node.expression !== expression ? updateNode(createThrow(expression), node) : node; } ts.updateThrow = updateThrow; function createTry(tryBlock, catchClause, finallyBlock) { var node = createSynthesizedNode(225 /* TryStatement */); node.tryBlock = tryBlock; node.catchClause = catchClause; node.finallyBlock = finallyBlock; return node; } ts.createTry = createTry; function updateTry(node, tryBlock, catchClause, finallyBlock) { return node.tryBlock !== tryBlock || node.catchClause !== catchClause || node.finallyBlock !== finallyBlock ? updateNode(createTry(tryBlock, catchClause, finallyBlock), node) : node; } ts.updateTry = updateTry; function createDebuggerStatement() { return createSynthesizedNode(226 /* DebuggerStatement */); } ts.createDebuggerStatement = createDebuggerStatement; function createVariableDeclaration(name, type, initializer) { var node = createSynthesizedNode(227 /* VariableDeclaration */); node.name = asName(name); node.type = type; node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined; return node; } ts.createVariableDeclaration = createVariableDeclaration; function updateVariableDeclaration(node, name, type, initializer) { return node.name !== name || node.type !== type || node.initializer !== initializer ? updateNode(createVariableDeclaration(name, type, initializer), node) : node; } ts.updateVariableDeclaration = updateVariableDeclaration; function createVariableDeclarationList(declarations, flags) { var node = createSynthesizedNode(228 /* VariableDeclarationList */); node.flags |= flags & 3 /* BlockScoped */; node.declarations = createNodeArray(declarations); return node; } ts.createVariableDeclarationList = createVariableDeclarationList; function updateVariableDeclarationList(node, declarations) { return node.declarations !== declarations ? updateNode(createVariableDeclarationList(declarations, node.flags), node) : node; } ts.updateVariableDeclarationList = updateVariableDeclarationList; function createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) { var node = createSynthesizedNode(229 /* FunctionDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.asteriskToken = asteriskToken; node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.parameters = createNodeArray(parameters); node.type = type; node.body = body; return node; } ts.createFunctionDeclaration = createFunctionDeclaration; function updateFunctionDeclaration(node, decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.asteriskToken !== asteriskToken || node.name !== name || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type || node.body !== body ? updateNode(createFunctionDeclaration(decorators, modifiers, asteriskToken, name, typeParameters, parameters, type, body), node) : node; } ts.updateFunctionDeclaration = updateFunctionDeclaration; function createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) { var node = createSynthesizedNode(230 /* ClassDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.heritageClauses = asNodeArray(heritageClauses); node.members = createNodeArray(members); return node; } ts.createClassDeclaration = createClassDeclaration; function updateClassDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members ? updateNode(createClassDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) : node; } ts.updateClassDeclaration = updateClassDeclaration; function createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members) { var node = createSynthesizedNode(231 /* InterfaceDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.heritageClauses = asNodeArray(heritageClauses); node.members = createNodeArray(members); return node; } ts.createInterfaceDeclaration = createInterfaceDeclaration; function updateInterfaceDeclaration(node, decorators, modifiers, name, typeParameters, heritageClauses, members) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.heritageClauses !== heritageClauses || node.members !== members ? updateNode(createInterfaceDeclaration(decorators, modifiers, name, typeParameters, heritageClauses, members), node) : node; } ts.updateInterfaceDeclaration = updateInterfaceDeclaration; function createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type) { var node = createSynthesizedNode(232 /* TypeAliasDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.typeParameters = asNodeArray(typeParameters); node.type = type; return node; } ts.createTypeAliasDeclaration = createTypeAliasDeclaration; function updateTypeAliasDeclaration(node, decorators, modifiers, name, typeParameters, type) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.typeParameters !== typeParameters || node.type !== type ? updateNode(createTypeAliasDeclaration(decorators, modifiers, name, typeParameters, type), node) : node; } ts.updateTypeAliasDeclaration = updateTypeAliasDeclaration; function createEnumDeclaration(decorators, modifiers, name, members) { var node = createSynthesizedNode(233 /* EnumDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.members = createNodeArray(members); return node; } ts.createEnumDeclaration = createEnumDeclaration; function updateEnumDeclaration(node, decorators, modifiers, name, members) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.members !== members ? updateNode(createEnumDeclaration(decorators, modifiers, name, members), node) : node; } ts.updateEnumDeclaration = updateEnumDeclaration; function createModuleDeclaration(decorators, modifiers, name, body, flags) { var node = createSynthesizedNode(234 /* ModuleDeclaration */); node.flags |= flags & (16 /* Namespace */ | 4 /* NestedNamespace */ | 512 /* GlobalAugmentation */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = name; node.body = body; return node; } ts.createModuleDeclaration = createModuleDeclaration; function updateModuleDeclaration(node, decorators, modifiers, name, body) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.body !== body ? updateNode(createModuleDeclaration(decorators, modifiers, name, body, node.flags), node) : node; } ts.updateModuleDeclaration = updateModuleDeclaration; function createModuleBlock(statements) { var node = createSynthesizedNode(235 /* ModuleBlock */); node.statements = createNodeArray(statements); return node; } ts.createModuleBlock = createModuleBlock; function updateModuleBlock(node, statements) { return node.statements !== statements ? updateNode(createModuleBlock(statements), node) : node; } ts.updateModuleBlock = updateModuleBlock; function createCaseBlock(clauses) { var node = createSynthesizedNode(236 /* CaseBlock */); node.clauses = createNodeArray(clauses); return node; } ts.createCaseBlock = createCaseBlock; function updateCaseBlock(node, clauses) { return node.clauses !== clauses ? updateNode(createCaseBlock(clauses), node) : node; } ts.updateCaseBlock = updateCaseBlock; function createNamespaceExportDeclaration(name) { var node = createSynthesizedNode(237 /* NamespaceExportDeclaration */); node.name = asName(name); return node; } ts.createNamespaceExportDeclaration = createNamespaceExportDeclaration; function updateNamespaceExportDeclaration(node, name) { return node.name !== name ? updateNode(createNamespaceExportDeclaration(name), node) : node; } ts.updateNamespaceExportDeclaration = updateNamespaceExportDeclaration; function createImportEqualsDeclaration(decorators, modifiers, name, moduleReference) { var node = createSynthesizedNode(238 /* ImportEqualsDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.name = asName(name); node.moduleReference = moduleReference; return node; } ts.createImportEqualsDeclaration = createImportEqualsDeclaration; function updateImportEqualsDeclaration(node, decorators, modifiers, name, moduleReference) { return node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.moduleReference !== moduleReference ? updateNode(createImportEqualsDeclaration(decorators, modifiers, name, moduleReference), node) : node; } ts.updateImportEqualsDeclaration = updateImportEqualsDeclaration; function createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier) { var node = createSynthesizedNode(239 /* ImportDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.importClause = importClause; node.moduleSpecifier = moduleSpecifier; return node; } ts.createImportDeclaration = createImportDeclaration; function updateImportDeclaration(node, decorators, modifiers, importClause, moduleSpecifier) { return node.decorators !== decorators || node.modifiers !== modifiers || node.importClause !== importClause || node.moduleSpecifier !== moduleSpecifier ? updateNode(createImportDeclaration(decorators, modifiers, importClause, moduleSpecifier), node) : node; } ts.updateImportDeclaration = updateImportDeclaration; function createImportClause(name, namedBindings) { var node = createSynthesizedNode(240 /* ImportClause */); node.name = name; node.namedBindings = namedBindings; return node; } ts.createImportClause = createImportClause; function updateImportClause(node, name, namedBindings) { return node.name !== name || node.namedBindings !== namedBindings ? updateNode(createImportClause(name, namedBindings), node) : node; } ts.updateImportClause = updateImportClause; function createNamespaceImport(name) { var node = createSynthesizedNode(241 /* NamespaceImport */); node.name = name; return node; } ts.createNamespaceImport = createNamespaceImport; function updateNamespaceImport(node, name) { return node.name !== name ? updateNode(createNamespaceImport(name), node) : node; } ts.updateNamespaceImport = updateNamespaceImport; function createNamedImports(elements) { var node = createSynthesizedNode(242 /* NamedImports */); node.elements = createNodeArray(elements); return node; } ts.createNamedImports = createNamedImports; function updateNamedImports(node, elements) { return node.elements !== elements ? updateNode(createNamedImports(elements), node) : node; } ts.updateNamedImports = updateNamedImports; function createImportSpecifier(propertyName, name) { var node = createSynthesizedNode(243 /* ImportSpecifier */); node.propertyName = propertyName; node.name = name; return node; } ts.createImportSpecifier = createImportSpecifier; function updateImportSpecifier(node, propertyName, name) { return node.propertyName !== propertyName || node.name !== name ? updateNode(createImportSpecifier(propertyName, name), node) : node; } ts.updateImportSpecifier = updateImportSpecifier; function createExportAssignment(decorators, modifiers, isExportEquals, expression) { var node = createSynthesizedNode(244 /* ExportAssignment */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.isExportEquals = isExportEquals; node.expression = isExportEquals ? ts.parenthesizeBinaryOperand(58 /* EqualsToken */, expression, /*isLeftSideOfBinary*/ false, /*leftOperand*/ undefined) : ts.parenthesizeDefaultExpression(expression); return node; } ts.createExportAssignment = createExportAssignment; function updateExportAssignment(node, decorators, modifiers, expression) { return node.decorators !== decorators || node.modifiers !== modifiers || node.expression !== expression ? updateNode(createExportAssignment(decorators, modifiers, node.isExportEquals, expression), node) : node; } ts.updateExportAssignment = updateExportAssignment; function createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier) { var node = createSynthesizedNode(245 /* ExportDeclaration */); node.decorators = asNodeArray(decorators); node.modifiers = asNodeArray(modifiers); node.exportClause = exportClause; node.moduleSpecifier = moduleSpecifier; return node; } ts.createExportDeclaration = createExportDeclaration; function updateExportDeclaration(node, decorators, modifiers, exportClause, moduleSpecifier) { return node.decorators !== decorators || node.modifiers !== modifiers || node.exportClause !== exportClause || node.moduleSpecifier !== moduleSpecifier ? updateNode(createExportDeclaration(decorators, modifiers, exportClause, moduleSpecifier), node) : node; } ts.updateExportDeclaration = updateExportDeclaration; function createNamedExports(elements) { var node = createSynthesizedNode(246 /* NamedExports */); node.elements = createNodeArray(elements); return node; } ts.createNamedExports = createNamedExports; function updateNamedExports(node, elements) { return node.elements !== elements ? updateNode(createNamedExports(elements), node) : node; } ts.updateNamedExports = updateNamedExports; function createExportSpecifier(propertyName, name) { var node = createSynthesizedNode(247 /* ExportSpecifier */); node.propertyName = asName(propertyName); node.name = asName(name); return node; } ts.createExportSpecifier = createExportSpecifier; function updateExportSpecifier(node, propertyName, name) { return node.propertyName !== propertyName || node.name !== name ? updateNode(createExportSpecifier(propertyName, name), node) : node; } ts.updateExportSpecifier = updateExportSpecifier; // Module references function createExternalModuleReference(expression) { var node = createSynthesizedNode(249 /* ExternalModuleReference */); node.expression = expression; return node; } ts.createExternalModuleReference = createExternalModuleReference; function updateExternalModuleReference(node, expression) { return node.expression !== expression ? updateNode(createExternalModuleReference(expression), node) : node; } ts.updateExternalModuleReference = updateExternalModuleReference; // JSX function createJsxElement(openingElement, children, closingElement) { var node = createSynthesizedNode(250 /* JsxElement */); node.openingElement = openingElement; node.children = createNodeArray(children); node.closingElement = closingElement; return node; } ts.createJsxElement = createJsxElement; function updateJsxElement(node, openingElement, children, closingElement) { return node.openingElement !== openingElement || node.children !== children || node.closingElement !== closingElement ? updateNode(createJsxElement(openingElement, children, closingElement), node) : node; } ts.updateJsxElement = updateJsxElement; function createJsxSelfClosingElement(tagName, attributes) { var node = createSynthesizedNode(251 /* JsxSelfClosingElement */); node.tagName = tagName; node.attributes = attributes; return node; } ts.createJsxSelfClosingElement = createJsxSelfClosingElement; function updateJsxSelfClosingElement(node, tagName, attributes) { return node.tagName !== tagName || node.attributes !== attributes ? updateNode(createJsxSelfClosingElement(tagName, attributes), node) : node; } ts.updateJsxSelfClosingElement = updateJsxSelfClosingElement; function createJsxOpeningElement(tagName, attributes) { var node = createSynthesizedNode(252 /* JsxOpeningElement */); node.tagName = tagName; node.attributes = attributes; return node; } ts.createJsxOpeningElement = createJsxOpeningElement; function updateJsxOpeningElement(node, tagName, attributes) { return node.tagName !== tagName || node.attributes !== attributes ? updateNode(createJsxOpeningElement(tagName, attributes), node) : node; } ts.updateJsxOpeningElement = updateJsxOpeningElement; function createJsxClosingElement(tagName) { var node = createSynthesizedNode(253 /* JsxClosingElement */); node.tagName = tagName; return node; } ts.createJsxClosingElement = createJsxClosingElement; function updateJsxClosingElement(node, tagName) { return node.tagName !== tagName ? updateNode(createJsxClosingElement(tagName), node) : node; } ts.updateJsxClosingElement = updateJsxClosingElement; function createJsxFragment(openingFragment, children, closingFragment) { var node = createSynthesizedNode(254 /* JsxFragment */); node.openingFragment = openingFragment; node.children = createNodeArray(children); node.closingFragment = closingFragment; return node; } ts.createJsxFragment = createJsxFragment; function updateJsxFragment(node, openingFragment, children, closingFragment) { return node.openingFragment !== openingFragment || node.children !== children || node.closingFragment !== closingFragment ? updateNode(createJsxFragment(openingFragment, children, closingFragment), node) : node; } ts.updateJsxFragment = updateJsxFragment; function createJsxAttribute(name, initializer) { var node = createSynthesizedNode(257 /* JsxAttribute */); node.name = name; node.initializer = initializer; return node; } ts.createJsxAttribute = createJsxAttribute; function updateJsxAttribute(node, name, initializer) { return node.name !== name || node.initializer !== initializer ? updateNode(createJsxAttribute(name, initializer), node) : node; } ts.updateJsxAttribute = updateJsxAttribute; function createJsxAttributes(properties) { var node = createSynthesizedNode(258 /* JsxAttributes */); node.properties = createNodeArray(properties); return node; } ts.createJsxAttributes = createJsxAttributes; function updateJsxAttributes(node, properties) { return node.properties !== properties ? updateNode(createJsxAttributes(properties), node) : node; } ts.updateJsxAttributes = updateJsxAttributes; function createJsxSpreadAttribute(expression) { var node = createSynthesizedNode(259 /* JsxSpreadAttribute */); node.expression = expression; return node; } ts.createJsxSpreadAttribute = createJsxSpreadAttribute; function updateJsxSpreadAttribute(node, expression) { return node.expression !== expression ? updateNode(createJsxSpreadAttribute(expression), node) : node; } ts.updateJsxSpreadAttribute = updateJsxSpreadAttribute; function createJsxExpression(dotDotDotToken, expression) { var node = createSynthesizedNode(260 /* JsxExpression */); node.dotDotDotToken = dotDotDotToken; node.expression = expression; return node; } ts.createJsxExpression = createJsxExpression; function updateJsxExpression(node, expression) { return node.expression !== expression ? updateNode(createJsxExpression(node.dotDotDotToken, expression), node) : node; } ts.updateJsxExpression = updateJsxExpression; // Clauses function createCaseClause(expression, statements) { var node = createSynthesizedNode(261 /* CaseClause */); node.expression = ts.parenthesizeExpressionForList(expression); node.statements = createNodeArray(statements); return node; } ts.createCaseClause = createCaseClause; function updateCaseClause(node, expression, statements) { return node.expression !== expression || node.statements !== statements ? updateNode(createCaseClause(expression, statements), node) : node; } ts.updateCaseClause = updateCaseClause; function createDefaultClause(statements) { var node = createSynthesizedNode(262 /* DefaultClause */); node.statements = createNodeArray(statements); return node; } ts.createDefaultClause = createDefaultClause; function updateDefaultClause(node, statements) { return node.statements !== statements ? updateNode(createDefaultClause(statements), node) : node; } ts.updateDefaultClause = updateDefaultClause; function createHeritageClause(token, types) { var node = createSynthesizedNode(263 /* HeritageClause */); node.token = token; node.types = createNodeArray(types); return node; } ts.createHeritageClause = createHeritageClause; function updateHeritageClause(node, types) { return node.types !== types ? updateNode(createHeritageClause(node.token, types), node) : node; } ts.updateHeritageClause = updateHeritageClause; function createCatchClause(variableDeclaration, block) { var node = createSynthesizedNode(264 /* CatchClause */); node.variableDeclaration = ts.isString(variableDeclaration) ? createVariableDeclaration(variableDeclaration) : variableDeclaration; node.block = block; return node; } ts.createCatchClause = createCatchClause; function updateCatchClause(node, variableDeclaration, block) { return node.variableDeclaration !== variableDeclaration || node.block !== block ? updateNode(createCatchClause(variableDeclaration, block), node) : node; } ts.updateCatchClause = updateCatchClause; // Property assignments function createPropertyAssignment(name, initializer) { var node = createSynthesizedNode(265 /* PropertyAssignment */); node.name = asName(name); node.questionToken = undefined; node.initializer = initializer !== undefined ? ts.parenthesizeExpressionForList(initializer) : undefined; return node; } ts.createPropertyAssignment = createPropertyAssignment; function updatePropertyAssignment(node, name, initializer) { return node.name !== name || node.initializer !== initializer ? updateNode(createPropertyAssignment(name, initializer), node) : node; } ts.updatePropertyAssignment = updatePropertyAssignment; function createShorthandPropertyAssignment(name, objectAssignmentInitializer) { var node = createSynthesizedNode(266 /* ShorthandPropertyAssignment */); node.name = asName(name); node.objectAssignmentInitializer = objectAssignmentInitializer !== undefined ? ts.parenthesizeExpressionForList(objectAssignmentInitializer) : undefined; return node; } ts.createShorthandPropertyAssignment = createShorthandPropertyAssignment; function updateShorthandPropertyAssignment(node, name, objectAssignmentInitializer) { return node.name !== name || node.objectAssignmentInitializer !== objectAssignmentInitializer ? updateNode(createShorthandPropertyAssignment(name, objectAssignmentInitializer), node) : node; } ts.updateShorthandPropertyAssignment = updateShorthandPropertyAssignment; function createSpreadAssignment(expression) { var node = createSynthesizedNode(267 /* SpreadAssignment */); node.expression = expression !== undefined ? ts.parenthesizeExpressionForList(expression) : undefined; return node; } ts.createSpreadAssignment = createSpreadAssignment; function updateSpreadAssignment(node, expression) { return node.expression !== expression ? updateNode(createSpreadAssignment(expression), node) : node; } ts.updateSpreadAssignment = updateSpreadAssignment; // Enum function createEnumMember(name, initializer) { var node = createSynthesizedNode(268 /* EnumMember */); node.name = asName(name); node.initializer = initializer && ts.parenthesizeExpressionForList(initializer); return node; } ts.createEnumMember = createEnumMember; function updateEnumMember(node, name, initializer) { return node.name !== name || node.initializer !== initializer ? updateNode(createEnumMember(name, initializer), node) : node; } ts.updateEnumMember = updateEnumMember; // Top-level nodes function updateSourceFileNode(node, statements) { if (node.statements !== statements) { var updated = createSynthesizedNode(269 /* SourceFile */); updated.flags |= node.flags; updated.statements = createNodeArray(statements); updated.endOfFileToken = node.endOfFileToken; updated.fileName = node.fileName; updated.path = node.path; updated.text = node.text; if (node.amdDependencies !== undefined) updated.amdDependencies = node.amdDependencies; if (node.moduleName !== undefined) updated.moduleName = node.moduleName; if (node.referencedFiles !== undefined) updated.referencedFiles = node.referencedFiles; if (node.typeReferenceDirectives !== undefined) updated.typeReferenceDirectives = node.typeReferenceDirectives; if (node.languageVariant !== undefined) updated.languageVariant = node.languageVariant; if (node.isDeclarationFile !== undefined) updated.isDeclarationFile = node.isDeclarationFile; if (node.renamedDependencies !== undefined) updated.renamedDependencies = node.renamedDependencies; if (node.hasNoDefaultLib !== undefined) updated.hasNoDefaultLib = node.hasNoDefaultLib; if (node.languageVersion !== undefined) updated.languageVersion = node.languageVersion; if (node.scriptKind !== undefined) updated.scriptKind = node.scriptKind; if (node.externalModuleIndicator !== undefined) updated.externalModuleIndicator = node.externalModuleIndicator; if (node.commonJsModuleIndicator !== undefined) updated.commonJsModuleIndicator = node.commonJsModuleIndicator; if (node.identifiers !== undefined) updated.identifiers = node.identifiers; if (node.nodeCount !== undefined) updated.nodeCount = node.nodeCount; if (node.identifierCount !== undefined) updated.identifierCount = node.identifierCount; if (node.symbolCount !== undefined) updated.symbolCount = node.symbolCount; if (node.parseDiagnostics !== undefined) updated.parseDiagnostics = node.parseDiagnostics; if (node.bindDiagnostics !== undefined) updated.bindDiagnostics = node.bindDiagnostics; if (node.lineMap !== undefined) updated.lineMap = node.lineMap; if (node.classifiableNames !== undefined) updated.classifiableNames = node.classifiableNames; if (node.resolvedModules !== undefined) updated.resolvedModules = node.resolvedModules; if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames; if (node.imports !== undefined) updated.imports = node.imports; if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations; return updateNode(updated, node); } return node; } ts.updateSourceFileNode = updateSourceFileNode; /** * Creates a shallow, memberwise clone of a node for mutation. */ function getMutableClone(node) { var clone = getSynthesizedClone(node); clone.pos = node.pos; clone.end = node.end; clone.parent = node.parent; return clone; } ts.getMutableClone = getMutableClone; // Transformation nodes /** * Creates a synthetic statement to act as a placeholder for a not-emitted statement in * order to preserve comments. * * @param original The original statement. */ function createNotEmittedStatement(original) { var node = createSynthesizedNode(291 /* NotEmittedStatement */); node.original = original; setTextRange(node, original); return node; } ts.createNotEmittedStatement = createNotEmittedStatement; /** * Creates a synthetic element to act as a placeholder for the end of an emitted declaration in * order to properly emit exports. */ /* @internal */ function createEndOfDeclarationMarker(original) { var node = createSynthesizedNode(295 /* EndOfDeclarationMarker */); node.emitNode = {}; node.original = original; return node; } ts.createEndOfDeclarationMarker = createEndOfDeclarationMarker; /** * Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in * order to properly emit exports. */ /* @internal */ function createMergeDeclarationMarker(original) { var node = createSynthesizedNode(294 /* MergeDeclarationMarker */); node.emitNode = {}; node.original = original; return node; } ts.createMergeDeclarationMarker = createMergeDeclarationMarker; /** * Creates a synthetic expression to act as a placeholder for a not-emitted expression in * order to preserve comments or sourcemap positions. * * @param expression The inner expression to emit. * @param original The original outer expression. * @param location The location for the expression. Defaults to the positions from "original" if provided. */ function createPartiallyEmittedExpression(expression, original) { var node = createSynthesizedNode(292 /* PartiallyEmittedExpression */); node.expression = expression; node.original = original; setTextRange(node, original); return node; } ts.createPartiallyEmittedExpression = createPartiallyEmittedExpression; function updatePartiallyEmittedExpression(node, expression) { if (node.expression !== expression) { return updateNode(createPartiallyEmittedExpression(expression, node.original), node); } return node; } ts.updatePartiallyEmittedExpression = updatePartiallyEmittedExpression; function flattenCommaElements(node) { if (ts.nodeIsSynthesized(node) && !ts.isParseTreeNode(node) && !node.original && !node.emitNode && !node.id) { if (node.kind === 293 /* CommaListExpression */) { return node.elements; } if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) { return [node.left, node.right]; } } return node; } function createCommaList(elements) { var node = createSynthesizedNode(293 /* CommaListExpression */); node.elements = createNodeArray(ts.sameFlatMap(elements, flattenCommaElements)); return node; } ts.createCommaList = createCommaList; function updateCommaList(node, elements) { return node.elements !== elements ? updateNode(createCommaList(elements), node) : node; } ts.updateCommaList = updateCommaList; function createBundle(sourceFiles) { var node = ts.createNode(270 /* Bundle */); node.sourceFiles = sourceFiles; return node; } ts.createBundle = createBundle; function updateBundle(node, sourceFiles) { if (node.sourceFiles !== sourceFiles) { return createBundle(sourceFiles); } return node; } ts.updateBundle = updateBundle; function createImmediatelyInvokedFunctionExpression(statements, param, paramValue) { return createCall(createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ param ? [param] : [], /*type*/ undefined, createBlock(statements, /*multiLine*/ true)), /*typeArguments*/ undefined, /*argumentsArray*/ paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedFunctionExpression = createImmediatelyInvokedFunctionExpression; function createImmediatelyInvokedArrowFunction(statements, param, paramValue) { return createCall(createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, /*parameters*/ param ? [param] : [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, createBlock(statements, /*multiLine*/ true)), /*typeArguments*/ undefined, /*argumentsArray*/ paramValue ? [paramValue] : []); } ts.createImmediatelyInvokedArrowFunction = createImmediatelyInvokedArrowFunction; function createComma(left, right) { return createBinary(left, 26 /* CommaToken */, right); } ts.createComma = createComma; function createLessThan(left, right) { return createBinary(left, 27 /* LessThanToken */, right); } ts.createLessThan = createLessThan; function createAssignment(left, right) { return createBinary(left, 58 /* EqualsToken */, right); } ts.createAssignment = createAssignment; function createStrictEquality(left, right) { return createBinary(left, 34 /* EqualsEqualsEqualsToken */, right); } ts.createStrictEquality = createStrictEquality; function createStrictInequality(left, right) { return createBinary(left, 35 /* ExclamationEqualsEqualsToken */, right); } ts.createStrictInequality = createStrictInequality; function createAdd(left, right) { return createBinary(left, 37 /* PlusToken */, right); } ts.createAdd = createAdd; function createSubtract(left, right) { return createBinary(left, 38 /* MinusToken */, right); } ts.createSubtract = createSubtract; function createPostfixIncrement(operand) { return createPostfix(operand, 43 /* PlusPlusToken */); } ts.createPostfixIncrement = createPostfixIncrement; function createLogicalAnd(left, right) { return createBinary(left, 53 /* AmpersandAmpersandToken */, right); } ts.createLogicalAnd = createLogicalAnd; function createLogicalOr(left, right) { return createBinary(left, 54 /* BarBarToken */, right); } ts.createLogicalOr = createLogicalOr; function createLogicalNot(operand) { return createPrefix(51 /* ExclamationToken */, operand); } ts.createLogicalNot = createLogicalNot; function createVoidZero() { return createVoid(createLiteral(0)); } ts.createVoidZero = createVoidZero; function createExportDefault(expression) { return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression); } ts.createExportDefault = createExportDefault; function createExternalModuleExport(exportName) { return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(/*propertyName*/ undefined, exportName)])); } ts.createExternalModuleExport = createExternalModuleExport; function asName(name) { return ts.isString(name) ? createIdentifier(name) : name; } function asExpression(value) { return ts.isString(value) || typeof value === "number" ? createLiteral(value) : value; } function asNodeArray(array) { return array ? createNodeArray(array) : undefined; } function asToken(value) { return typeof value === "number" ? createToken(value) : value; } /** * Clears any EmitNode entries from parse-tree nodes. * @param sourceFile A source file. */ function disposeEmitNodes(sourceFile) { // During transformation we may need to annotate a parse tree node with transient // transformation properties. As parse tree nodes live longer than transformation // nodes, we need to make sure we reclaim any memory allocated for custom ranges // from these nodes to ensure we do not hold onto entire subtrees just for position // information. We also need to reset these nodes to a pre-transformation state // for incremental parsing scenarios so that we do not impact later emit. sourceFile = ts.getSourceFileOfNode(ts.getParseTreeNode(sourceFile)); var emitNode = sourceFile && sourceFile.emitNode; var annotatedNodes = emitNode && emitNode.annotatedNodes; if (annotatedNodes) { for (var _i = 0, annotatedNodes_1 = annotatedNodes; _i < annotatedNodes_1.length; _i++) { var node = annotatedNodes_1[_i]; node.emitNode = undefined; } } } ts.disposeEmitNodes = disposeEmitNodes; /** * Associates a node with the current transformation, initializing * various transient transformation properties. */ /* @internal */ function getOrCreateEmitNode(node) { if (!node.emitNode) { if (ts.isParseTreeNode(node)) { // To avoid holding onto transformation artifacts, we keep track of any // parse tree node we are annotating. This allows us to clean them up after // all transformations have completed. if (node.kind === 269 /* SourceFile */) { return node.emitNode = { annotatedNodes: [node] }; } var sourceFile = ts.getSourceFileOfNode(node); getOrCreateEmitNode(sourceFile).annotatedNodes.push(node); } node.emitNode = {}; } return node.emitNode; } ts.getOrCreateEmitNode = getOrCreateEmitNode; function setTextRange(range, location) { if (location) { range.pos = location.pos; range.end = location.end; } return range; } ts.setTextRange = setTextRange; /** * Sets flags that control emit behavior of a node. */ function setEmitFlags(node, emitFlags) { getOrCreateEmitNode(node).flags = emitFlags; return node; } ts.setEmitFlags = setEmitFlags; /** * Sets flags that control emit behavior of a node. */ /* @internal */ function addEmitFlags(node, emitFlags) { var emitNode = getOrCreateEmitNode(node); emitNode.flags = emitNode.flags | emitFlags; return node; } ts.addEmitFlags = addEmitFlags; /** * Gets a custom text range to use when emitting source maps. */ function getSourceMapRange(node) { var emitNode = node.emitNode; return (emitNode && emitNode.sourceMapRange) || node; } ts.getSourceMapRange = getSourceMapRange; /** * Sets a custom text range to use when emitting source maps. */ function setSourceMapRange(node, range) { getOrCreateEmitNode(node).sourceMapRange = range; return node; } ts.setSourceMapRange = setSourceMapRange; // tslint:disable-next-line variable-name var SourceMapSource; /** * Create an external source map source file reference */ function createSourceMapSource(fileName, text, skipTrivia) { return new (SourceMapSource || (SourceMapSource = ts.objectAllocator.getSourceMapSourceConstructor()))(fileName, text, skipTrivia); } ts.createSourceMapSource = createSourceMapSource; /** * Gets the TextRange to use for source maps for a token of a node. */ function getTokenSourceMapRange(node, token) { var emitNode = node.emitNode; var tokenSourceMapRanges = emitNode && emitNode.tokenSourceMapRanges; return tokenSourceMapRanges && tokenSourceMapRanges[token]; } ts.getTokenSourceMapRange = getTokenSourceMapRange; /** * Sets the TextRange to use for source maps for a token of a node. */ function setTokenSourceMapRange(node, token, range) { var emitNode = getOrCreateEmitNode(node); var tokenSourceMapRanges = emitNode.tokenSourceMapRanges || (emitNode.tokenSourceMapRanges = []); tokenSourceMapRanges[token] = range; return node; } ts.setTokenSourceMapRange = setTokenSourceMapRange; /** * Gets a custom text range to use when emitting comments. */ /*@internal*/ function getStartsOnNewLine(node) { var emitNode = node.emitNode; return emitNode && emitNode.startsOnNewLine; } ts.getStartsOnNewLine = getStartsOnNewLine; /** * Sets a custom text range to use when emitting comments. */ /*@internal*/ function setStartsOnNewLine(node, newLine) { getOrCreateEmitNode(node).startsOnNewLine = newLine; return node; } ts.setStartsOnNewLine = setStartsOnNewLine; /** * Gets a custom text range to use when emitting comments. */ function getCommentRange(node) { var emitNode = node.emitNode; return (emitNode && emitNode.commentRange) || node; } ts.getCommentRange = getCommentRange; /** * Sets a custom text range to use when emitting comments. */ function setCommentRange(node, range) { getOrCreateEmitNode(node).commentRange = range; return node; } ts.setCommentRange = setCommentRange; function getSyntheticLeadingComments(node) { var emitNode = node.emitNode; return emitNode && emitNode.leadingComments; } ts.getSyntheticLeadingComments = getSyntheticLeadingComments; function setSyntheticLeadingComments(node, comments) { getOrCreateEmitNode(node).leadingComments = comments; return node; } ts.setSyntheticLeadingComments = setSyntheticLeadingComments; function addSyntheticLeadingComment(node, kind, text, hasTrailingNewLine) { return setSyntheticLeadingComments(node, ts.append(getSyntheticLeadingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text })); } ts.addSyntheticLeadingComment = addSyntheticLeadingComment; function getSyntheticTrailingComments(node) { var emitNode = node.emitNode; return emitNode && emitNode.trailingComments; } ts.getSyntheticTrailingComments = getSyntheticTrailingComments; function setSyntheticTrailingComments(node, comments) { getOrCreateEmitNode(node).trailingComments = comments; return node; } ts.setSyntheticTrailingComments = setSyntheticTrailingComments; function addSyntheticTrailingComment(node, kind, text, hasTrailingNewLine) { return setSyntheticTrailingComments(node, ts.append(getSyntheticTrailingComments(node), { kind: kind, pos: -1, end: -1, hasTrailingNewLine: hasTrailingNewLine, text: text })); } ts.addSyntheticTrailingComment = addSyntheticTrailingComment; /** * Gets the constant value to emit for an expression. */ function getConstantValue(node) { var emitNode = node.emitNode; return emitNode && emitNode.constantValue; } ts.getConstantValue = getConstantValue; /** * Sets the constant value to emit for an expression. */ function setConstantValue(node, value) { var emitNode = getOrCreateEmitNode(node); emitNode.constantValue = value; return node; } ts.setConstantValue = setConstantValue; /** * Adds an EmitHelper to a node. */ function addEmitHelper(node, helper) { var emitNode = getOrCreateEmitNode(node); emitNode.helpers = ts.append(emitNode.helpers, helper); return node; } ts.addEmitHelper = addEmitHelper; /** * Add EmitHelpers to a node. */ function addEmitHelpers(node, helpers) { if (ts.some(helpers)) { var emitNode = getOrCreateEmitNode(node); for (var _i = 0, helpers_1 = helpers; _i < helpers_1.length; _i++) { var helper = helpers_1[_i]; emitNode.helpers = ts.appendIfUnique(emitNode.helpers, helper); } } return node; } ts.addEmitHelpers = addEmitHelpers; /** * Removes an EmitHelper from a node. */ function removeEmitHelper(node, helper) { var emitNode = node.emitNode; if (emitNode) { var helpers = emitNode.helpers; if (helpers) { return ts.orderedRemoveItem(helpers, helper); } } return false; } ts.removeEmitHelper = removeEmitHelper; /** * Gets the EmitHelpers of a node. */ function getEmitHelpers(node) { var emitNode = node.emitNode; return emitNode && emitNode.helpers; } ts.getEmitHelpers = getEmitHelpers; /** * Moves matching emit helpers from a source node to a target node. */ function moveEmitHelpers(source, target, predicate) { var sourceEmitNode = source.emitNode; var sourceEmitHelpers = sourceEmitNode && sourceEmitNode.helpers; if (!ts.some(sourceEmitHelpers)) return; var targetEmitNode = getOrCreateEmitNode(target); var helpersRemoved = 0; for (var i = 0; i < sourceEmitHelpers.length; i++) { var helper = sourceEmitHelpers[i]; if (predicate(helper)) { helpersRemoved++; targetEmitNode.helpers = ts.appendIfUnique(targetEmitNode.helpers, helper); } else if (helpersRemoved > 0) { sourceEmitHelpers[i - helpersRemoved] = helper; } } if (helpersRemoved > 0) { sourceEmitHelpers.length -= helpersRemoved; } } ts.moveEmitHelpers = moveEmitHelpers; /* @internal */ function compareEmitHelpers(x, y) { if (x === y) return 0 /* EqualTo */; if (x.priority === y.priority) return 0 /* EqualTo */; if (x.priority === undefined) return 1 /* GreaterThan */; if (y.priority === undefined) return -1 /* LessThan */; return ts.compareValues(x.priority, y.priority); } ts.compareEmitHelpers = compareEmitHelpers; function setOriginalNode(node, original) { node.original = original; if (original) { var emitNode = original.emitNode; if (emitNode) node.emitNode = mergeEmitNode(emitNode, node.emitNode); } return node; } ts.setOriginalNode = setOriginalNode; function mergeEmitNode(sourceEmitNode, destEmitNode) { var flags = sourceEmitNode.flags, leadingComments = sourceEmitNode.leadingComments, trailingComments = sourceEmitNode.trailingComments, commentRange = sourceEmitNode.commentRange, sourceMapRange = sourceEmitNode.sourceMapRange, tokenSourceMapRanges = sourceEmitNode.tokenSourceMapRanges, constantValue = sourceEmitNode.constantValue, helpers = sourceEmitNode.helpers, startsOnNewLine = sourceEmitNode.startsOnNewLine; if (!destEmitNode) destEmitNode = {}; // We are using `.slice()` here in case `destEmitNode.leadingComments` is pushed to later. if (leadingComments) destEmitNode.leadingComments = ts.addRange(leadingComments.slice(), destEmitNode.leadingComments); if (trailingComments) destEmitNode.trailingComments = ts.addRange(trailingComments.slice(), destEmitNode.trailingComments); if (flags) destEmitNode.flags = flags; if (commentRange) destEmitNode.commentRange = commentRange; if (sourceMapRange) destEmitNode.sourceMapRange = sourceMapRange; if (tokenSourceMapRanges) destEmitNode.tokenSourceMapRanges = mergeTokenSourceMapRanges(tokenSourceMapRanges, destEmitNode.tokenSourceMapRanges); if (constantValue !== undefined) destEmitNode.constantValue = constantValue; if (helpers) destEmitNode.helpers = ts.addRange(destEmitNode.helpers, helpers); if (startsOnNewLine !== undefined) destEmitNode.startsOnNewLine = startsOnNewLine; return destEmitNode; } function mergeTokenSourceMapRanges(sourceRanges, destRanges) { if (!destRanges) destRanges = []; for (var key in sourceRanges) { destRanges[key] = sourceRanges[key]; } return destRanges; } })(ts || (ts = {})); /* @internal */ (function (ts) { ts.nullTransformationContext = { enableEmitNotification: ts.noop, enableSubstitution: ts.noop, endLexicalEnvironment: function () { return undefined; }, getCompilerOptions: ts.notImplemented, getEmitHost: ts.notImplemented, getEmitResolver: ts.notImplemented, hoistFunctionDeclaration: ts.noop, hoistVariableDeclaration: ts.noop, isEmitNotificationEnabled: ts.notImplemented, isSubstitutionEnabled: ts.notImplemented, onEmitNode: ts.noop, onSubstituteNode: ts.notImplemented, readEmitHelpers: ts.notImplemented, requestEmitHelper: ts.noop, resumeLexicalEnvironment: ts.noop, startLexicalEnvironment: ts.noop, suspendLexicalEnvironment: ts.noop }; function createTypeCheck(value, tag) { return tag === "undefined" ? ts.createStrictEquality(value, ts.createVoidZero()) : ts.createStrictEquality(ts.createTypeOf(value), ts.createLiteral(tag)); } ts.createTypeCheck = createTypeCheck; function createMemberAccessForPropertyName(target, memberName, location) { if (ts.isComputedPropertyName(memberName)) { return ts.setTextRange(ts.createElementAccess(target, memberName.expression), location); } else { var expression = ts.setTextRange(ts.isIdentifier(memberName) ? ts.createPropertyAccess(target, memberName) : ts.createElementAccess(target, memberName), memberName); ts.getOrCreateEmitNode(expression).flags |= 64 /* NoNestedSourceMaps */; return expression; } } ts.createMemberAccessForPropertyName = createMemberAccessForPropertyName; function createFunctionCall(func, thisArg, argumentsList, location) { return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "call"), /*typeArguments*/ undefined, [ thisArg ].concat(argumentsList)), location); } ts.createFunctionCall = createFunctionCall; function createFunctionApply(func, thisArg, argumentsExpression, location) { return ts.setTextRange(ts.createCall(ts.createPropertyAccess(func, "apply"), /*typeArguments*/ undefined, [ thisArg, argumentsExpression ]), location); } ts.createFunctionApply = createFunctionApply; function createArraySlice(array, start) { var argumentsList = []; if (start !== undefined) { argumentsList.push(typeof start === "number" ? ts.createLiteral(start) : start); } return ts.createCall(ts.createPropertyAccess(array, "slice"), /*typeArguments*/ undefined, argumentsList); } ts.createArraySlice = createArraySlice; function createArrayConcat(array, values) { return ts.createCall(ts.createPropertyAccess(array, "concat"), /*typeArguments*/ undefined, values); } ts.createArrayConcat = createArrayConcat; function createMathPow(left, right, location) { return ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Math"), "pow"), /*typeArguments*/ undefined, [left, right]), location); } ts.createMathPow = createMathPow; function createReactNamespace(reactNamespace, parent) { // To ensure the emit resolver can properly resolve the namespace, we need to // treat this identifier as if it were a source tree node by clearing the `Synthesized` // flag and setting a parent node. var react = ts.createIdentifier(reactNamespace || "React"); react.flags &= ~8 /* Synthesized */; // Set the parent that is in parse tree // this makes sure that parent chain is intact for checker to traverse complete scope tree react.parent = ts.getParseTreeNode(parent); return react; } function createJsxFactoryExpressionFromEntityName(jsxFactory, parent) { if (ts.isQualifiedName(jsxFactory)) { var left = createJsxFactoryExpressionFromEntityName(jsxFactory.left, parent); var right = ts.createIdentifier(ts.idText(jsxFactory.right)); right.escapedText = jsxFactory.right.escapedText; return ts.createPropertyAccess(left, right); } else { return createReactNamespace(ts.idText(jsxFactory), parent); } } function createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parent) { return jsxFactoryEntity ? createJsxFactoryExpressionFromEntityName(jsxFactoryEntity, parent) : ts.createPropertyAccess(createReactNamespace(reactNamespace, parent), "createElement"); } function createExpressionForJsxElement(jsxFactoryEntity, reactNamespace, tagName, props, children, parentElement, location) { var argumentsList = [tagName]; if (props) { argumentsList.push(props); } if (children && children.length > 0) { if (!props) { argumentsList.push(ts.createNull()); } if (children.length > 1) { for (var _i = 0, children_1 = children; _i < children_1.length; _i++) { var child = children_1[_i]; startOnNewLine(child); argumentsList.push(child); } } else { argumentsList.push(children[0]); } } return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), /*typeArguments*/ undefined, argumentsList), location); } ts.createExpressionForJsxElement = createExpressionForJsxElement; function createExpressionForJsxFragment(jsxFactoryEntity, reactNamespace, children, parentElement, location) { var tagName = ts.createPropertyAccess(createReactNamespace(reactNamespace, parentElement), "Fragment"); var argumentsList = [tagName]; argumentsList.push(ts.createNull()); if (children && children.length > 0) { if (children.length > 1) { for (var _i = 0, children_2 = children; _i < children_2.length; _i++) { var child = children_2[_i]; startOnNewLine(child); argumentsList.push(child); } } else { argumentsList.push(children[0]); } } return ts.setTextRange(ts.createCall(createJsxFactoryExpression(jsxFactoryEntity, reactNamespace, parentElement), /*typeArguments*/ undefined, argumentsList), location); } ts.createExpressionForJsxFragment = createExpressionForJsxFragment; // Helpers function getHelperName(name) { return ts.setEmitFlags(ts.createIdentifier(name), 4096 /* HelperName */ | 2 /* AdviseOnEmitNode */); } ts.getHelperName = getHelperName; var valuesHelper = { name: "typescript:values", scoped: false, text: "\n var __values = (this && this.__values) || function (o) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\n if (m) return m.call(o);\n return {\n next: function () {\n if (o && i >= o.length) o = void 0;\n return { value: o && o[i++], done: !o };\n }\n };\n };\n " }; function createValuesHelper(context, expression, location) { context.requestEmitHelper(valuesHelper); return ts.setTextRange(ts.createCall(getHelperName("__values"), /*typeArguments*/ undefined, [expression]), location); } ts.createValuesHelper = createValuesHelper; var readHelper = { name: "typescript:read", scoped: false, text: "\n var __read = (this && this.__read) || function (o, n) {\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\n if (!m) return o;\n var i = m.call(o), r, ar = [], e;\n try {\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\n }\n catch (error) { e = { error: error }; }\n finally {\n try {\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\n }\n finally { if (e) throw e.error; }\n }\n return ar;\n };\n " }; function createReadHelper(context, iteratorRecord, count, location) { context.requestEmitHelper(readHelper); return ts.setTextRange(ts.createCall(getHelperName("__read"), /*typeArguments*/ undefined, count !== undefined ? [iteratorRecord, ts.createLiteral(count)] : [iteratorRecord]), location); } ts.createReadHelper = createReadHelper; var spreadHelper = { name: "typescript:spread", scoped: false, text: "\n var __spread = (this && this.__spread) || function () {\n for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));\n return ar;\n };" }; function createSpreadHelper(context, argumentList, location) { context.requestEmitHelper(readHelper); context.requestEmitHelper(spreadHelper); return ts.setTextRange(ts.createCall(getHelperName("__spread"), /*typeArguments*/ undefined, argumentList), location); } ts.createSpreadHelper = createSpreadHelper; // Utilities function createForOfBindingStatement(node, boundValue) { if (ts.isVariableDeclarationList(node)) { var firstDeclaration = ts.firstOrUndefined(node.declarations); var updatedDeclaration = ts.updateVariableDeclaration(firstDeclaration, firstDeclaration.name, /*typeNode*/ undefined, boundValue); return ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.updateVariableDeclarationList(node, [updatedDeclaration])), /*location*/ node); } else { var updatedExpression = ts.setTextRange(ts.createAssignment(node, boundValue), /*location*/ node); return ts.setTextRange(ts.createStatement(updatedExpression), /*location*/ node); } } ts.createForOfBindingStatement = createForOfBindingStatement; function insertLeadingStatement(dest, source) { if (ts.isBlock(dest)) { return ts.updateBlock(dest, ts.setTextRange(ts.createNodeArray([source].concat(dest.statements)), dest.statements)); } else { return ts.createBlock(ts.createNodeArray([dest, source]), /*multiLine*/ true); } } ts.insertLeadingStatement = insertLeadingStatement; function restoreEnclosingLabel(node, outermostLabeledStatement, afterRestoreLabelCallback) { if (!outermostLabeledStatement) { return node; } var updated = ts.updateLabel(outermostLabeledStatement, outermostLabeledStatement.label, outermostLabeledStatement.statement.kind === 223 /* LabeledStatement */ ? restoreEnclosingLabel(node, outermostLabeledStatement.statement) : node); if (afterRestoreLabelCallback) { afterRestoreLabelCallback(outermostLabeledStatement); } return updated; } ts.restoreEnclosingLabel = restoreEnclosingLabel; function shouldBeCapturedInTempVariable(node, cacheIdentifiers) { var target = skipParentheses(node); switch (target.kind) { case 71 /* Identifier */: return cacheIdentifiers; case 99 /* ThisKeyword */: case 8 /* NumericLiteral */: case 9 /* StringLiteral */: return false; case 178 /* ArrayLiteralExpression */: var elements = target.elements; if (elements.length === 0) { return false; } return true; case 179 /* ObjectLiteralExpression */: return target.properties.length > 0; default: return true; } } function createCallBinding(expression, recordTempVariable, languageVersion, cacheIdentifiers) { var callee = skipOuterExpressions(expression, 7 /* All */); var thisArg; var target; if (ts.isSuperProperty(callee)) { thisArg = ts.createThis(); target = callee; } else if (callee.kind === 97 /* SuperKeyword */) { thisArg = ts.createThis(); target = languageVersion < 2 /* ES2015 */ ? ts.setTextRange(ts.createIdentifier("_super"), callee) : callee; } else if (ts.getEmitFlags(callee) & 4096 /* HelperName */) { thisArg = ts.createVoidZero(); target = parenthesizeForAccess(callee); } else { switch (callee.kind) { case 180 /* PropertyAccessExpression */: { if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { // for `a.b()` target is `(_a = a).b` and thisArg is `_a` thisArg = ts.createTempVariable(recordTempVariable); target = ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.name); ts.setTextRange(target, callee); } else { thisArg = callee.expression; target = callee; } break; } case 181 /* ElementAccessExpression */: { if (shouldBeCapturedInTempVariable(callee.expression, cacheIdentifiers)) { // for `a[b]()` target is `(_a = a)[b]` and thisArg is `_a` thisArg = ts.createTempVariable(recordTempVariable); target = ts.createElementAccess(ts.setTextRange(ts.createAssignment(thisArg, callee.expression), callee.expression), callee.argumentExpression); ts.setTextRange(target, callee); } else { thisArg = callee.expression; target = callee; } break; } default: { // for `a()` target is `a` and thisArg is `void 0` thisArg = ts.createVoidZero(); target = parenthesizeForAccess(expression); break; } } } return { target: target, thisArg: thisArg }; } ts.createCallBinding = createCallBinding; function inlineExpressions(expressions) { // Avoid deeply nested comma expressions as traversing them during emit can result in "Maximum call // stack size exceeded" errors. return expressions.length > 10 ? ts.createCommaList(expressions) : ts.reduceLeft(expressions, ts.createComma); } ts.inlineExpressions = inlineExpressions; function createExpressionFromEntityName(node) { if (ts.isQualifiedName(node)) { var left = createExpressionFromEntityName(node.left); var right = ts.getMutableClone(node.right); return ts.setTextRange(ts.createPropertyAccess(left, right), node); } else { return ts.getMutableClone(node); } } ts.createExpressionFromEntityName = createExpressionFromEntityName; function createExpressionForPropertyName(memberName) { if (ts.isIdentifier(memberName)) { return ts.createLiteral(memberName); } else if (ts.isComputedPropertyName(memberName)) { return ts.getMutableClone(memberName.expression); } else { return ts.getMutableClone(memberName); } } ts.createExpressionForPropertyName = createExpressionForPropertyName; function createExpressionForObjectLiteralElementLike(node, property, receiver) { switch (property.kind) { case 154 /* GetAccessor */: case 155 /* SetAccessor */: return createExpressionForAccessorDeclaration(node.properties, property, receiver, node.multiLine); case 265 /* PropertyAssignment */: return createExpressionForPropertyAssignment(property, receiver); case 266 /* ShorthandPropertyAssignment */: return createExpressionForShorthandPropertyAssignment(property, receiver); case 152 /* MethodDeclaration */: return createExpressionForMethodDeclaration(property, receiver); } } ts.createExpressionForObjectLiteralElementLike = createExpressionForObjectLiteralElementLike; function createExpressionForAccessorDeclaration(properties, property, receiver, multiLine) { var _a = ts.getAllAccessorDeclarations(properties, property), firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; if (property === firstAccessor) { var properties_9 = []; if (getAccessor) { var getterFunction = ts.createFunctionExpression(getAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, getAccessor.parameters, /*type*/ undefined, getAccessor.body); ts.setTextRange(getterFunction, getAccessor); ts.setOriginalNode(getterFunction, getAccessor); var getter = ts.createPropertyAssignment("get", getterFunction); properties_9.push(getter); } if (setAccessor) { var setterFunction = ts.createFunctionExpression(setAccessor.modifiers, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, setAccessor.parameters, /*type*/ undefined, setAccessor.body); ts.setTextRange(setterFunction, setAccessor); ts.setOriginalNode(setterFunction, setAccessor); var setter = ts.createPropertyAssignment("set", setterFunction); properties_9.push(setter); } properties_9.push(ts.createPropertyAssignment("enumerable", ts.createTrue())); properties_9.push(ts.createPropertyAssignment("configurable", ts.createTrue())); var expression = ts.setTextRange(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ receiver, createExpressionForPropertyName(property.name), ts.createObjectLiteral(properties_9, multiLine) ]), /*location*/ firstAccessor); return ts.aggregateTransformFlags(expression); } return undefined; } function createExpressionForPropertyAssignment(property, receiver) { return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), property.initializer), property), property)); } function createExpressionForShorthandPropertyAssignment(property, receiver) { return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, property.name, /*location*/ property.name), ts.getSynthesizedClone(property.name)), /*location*/ property), /*original*/ property)); } function createExpressionForMethodDeclaration(method, receiver) { return ts.aggregateTransformFlags(ts.setOriginalNode(ts.setTextRange(ts.createAssignment(createMemberAccessForPropertyName(receiver, method.name, /*location*/ method.name), ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression(method.modifiers, method.asteriskToken, /*name*/ undefined, /*typeParameters*/ undefined, method.parameters, /*type*/ undefined, method.body), /*location*/ method), /*original*/ method)), /*location*/ method), /*original*/ method)); } /** * Gets the internal name of a declaration. This is primarily used for declarations that can be * referred to by name in the body of an ES5 class function body. An internal name will *never* * be prefixed with an module or namespace export modifier like "exports." when emitted as an * expression. An internal name will also *never* be renamed due to a collision with a block * scoped variable. * * @param node The declaration. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getInternalName(node, allowComments, allowSourceMaps) { return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */ | 32768 /* InternalName */); } ts.getInternalName = getInternalName; /** * Gets whether an identifier should only be referred to by its internal name. */ function isInternalName(node) { return (ts.getEmitFlags(node) & 32768 /* InternalName */) !== 0; } ts.isInternalName = isInternalName; /** * Gets the local name of a declaration. This is primarily used for declarations that can be * referred to by name in the declaration's immediate scope (classes, enums, namespaces). A * local name will *never* be prefixed with an module or namespace export modifier like * "exports." when emitted as an expression. * * @param node The declaration. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getLocalName(node, allowComments, allowSourceMaps) { return getName(node, allowComments, allowSourceMaps, 16384 /* LocalName */); } ts.getLocalName = getLocalName; /** * Gets whether an identifier should only be referred to by its local name. */ function isLocalName(node) { return (ts.getEmitFlags(node) & 16384 /* LocalName */) !== 0; } ts.isLocalName = isLocalName; /** * Gets the export name of a declaration. This is primarily used for declarations that can be * referred to by name in the declaration's immediate scope (classes, enums, namespaces). An * export name will *always* be prefixed with an module or namespace export modifier like * `"exports."` when emitted as an expression if the name points to an exported symbol. * * @param node The declaration. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getExportName(node, allowComments, allowSourceMaps) { return getName(node, allowComments, allowSourceMaps, 8192 /* ExportName */); } ts.getExportName = getExportName; /** * Gets whether an identifier should only be referred to by its export representation if the * name points to an exported symbol. */ function isExportName(node) { return (ts.getEmitFlags(node) & 8192 /* ExportName */) !== 0; } ts.isExportName = isExportName; /** * Gets the name of a declaration for use in declarations. * * @param node The declaration. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getDeclarationName(node, allowComments, allowSourceMaps) { return getName(node, allowComments, allowSourceMaps); } ts.getDeclarationName = getDeclarationName; function getName(node, allowComments, allowSourceMaps, emitFlags) { var nodeName = ts.getNameOfDeclaration(node); if (nodeName && ts.isIdentifier(nodeName) && !ts.isGeneratedIdentifier(nodeName)) { var name = ts.getMutableClone(nodeName); emitFlags |= ts.getEmitFlags(nodeName); if (!allowSourceMaps) emitFlags |= 48 /* NoSourceMap */; if (!allowComments) emitFlags |= 1536 /* NoComments */; if (emitFlags) ts.setEmitFlags(name, emitFlags); return name; } return ts.getGeneratedNameForNode(node); } /** * Gets the exported name of a declaration for use in expressions. * * An exported name will *always* be prefixed with an module or namespace export modifier like * "exports." if the name points to an exported symbol. * * @param ns The namespace identifier. * @param node The declaration. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getExternalModuleOrNamespaceExportName(ns, node, allowComments, allowSourceMaps) { if (ns && ts.hasModifier(node, 1 /* Export */)) { return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps); } return getExportName(node, allowComments, allowSourceMaps); } ts.getExternalModuleOrNamespaceExportName = getExternalModuleOrNamespaceExportName; /** * Gets a namespace-qualified name for use in expressions. * * @param ns The namespace identifier. * @param name The name. * @param allowComments A value indicating whether comments may be emitted for the name. * @param allowSourceMaps A value indicating whether source maps may be emitted for the name. */ function getNamespaceMemberName(ns, name, allowComments, allowSourceMaps) { var qualifiedName = ts.createPropertyAccess(ns, ts.nodeIsSynthesized(name) ? name : ts.getSynthesizedClone(name)); ts.setTextRange(qualifiedName, name); var emitFlags; if (!allowSourceMaps) emitFlags |= 48 /* NoSourceMap */; if (!allowComments) emitFlags |= 1536 /* NoComments */; if (emitFlags) ts.setEmitFlags(qualifiedName, emitFlags); return qualifiedName; } ts.getNamespaceMemberName = getNamespaceMemberName; function convertToFunctionBody(node, multiLine) { return ts.isBlock(node) ? node : ts.setTextRange(ts.createBlock([ts.setTextRange(ts.createReturn(node), node)], multiLine), node); } ts.convertToFunctionBody = convertToFunctionBody; function convertFunctionDeclarationToExpression(node) { ts.Debug.assert(!!node.body); var updated = ts.createFunctionExpression(node.modifiers, node.asteriskToken, node.name, node.typeParameters, node.parameters, node.type, node.body); ts.setOriginalNode(updated, node); ts.setTextRange(updated, node); if (ts.getStartsOnNewLine(node)) { ts.setStartsOnNewLine(updated, /*newLine*/ true); } ts.aggregateTransformFlags(updated); return updated; } ts.convertFunctionDeclarationToExpression = convertFunctionDeclarationToExpression; function isUseStrictPrologue(node) { return ts.isStringLiteral(node.expression) && node.expression.text === "use strict"; } /** * Add any necessary prologue-directives into target statement-array. * The function needs to be called during each transformation step. * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. * * @param target: result statements array * @param source: origin statements array * @param ensureUseStrict: boolean determining whether the function need to add prologue-directives * @param visitor: Optional callback used to visit any custom prologue directives. */ function addPrologue(target, source, ensureUseStrict, visitor) { var offset = addStandardPrologue(target, source, ensureUseStrict); return addCustomPrologue(target, source, offset, visitor); } ts.addPrologue = addPrologue; /** * Add just the standard (string-expression) prologue-directives into target statement-array. * The function needs to be called during each transformation step. * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. */ function addStandardPrologue(target, source, ensureUseStrict) { ts.Debug.assert(target.length === 0, "Prologue directives should be at the first statement in the target statements array"); var foundUseStrict = false; var statementOffset = 0; var numStatements = source.length; while (statementOffset < numStatements) { var statement = source[statementOffset]; if (ts.isPrologueDirective(statement)) { if (isUseStrictPrologue(statement)) { foundUseStrict = true; } target.push(statement); } else { break; } statementOffset++; } if (ensureUseStrict && !foundUseStrict) { target.push(startOnNewLine(ts.createStatement(ts.createLiteral("use strict")))); } return statementOffset; } ts.addStandardPrologue = addStandardPrologue; /** * Add just the custom prologue-directives into target statement-array. * The function needs to be called during each transformation step. * This function needs to be called whenever we transform the statement * list of a source file, namespace, or function-like body. */ function addCustomPrologue(target, source, statementOffset, visitor) { var numStatements = source.length; while (statementOffset < numStatements) { var statement = source[statementOffset]; if (ts.getEmitFlags(statement) & 1048576 /* CustomPrologue */) { ts.append(target, visitor ? ts.visitNode(statement, visitor, ts.isStatement) : statement); } else { break; } statementOffset++; } return statementOffset; } ts.addCustomPrologue = addCustomPrologue; function startsWithUseStrict(statements) { var firstStatement = ts.firstOrUndefined(statements); return firstStatement !== undefined && ts.isPrologueDirective(firstStatement) && isUseStrictPrologue(firstStatement); } ts.startsWithUseStrict = startsWithUseStrict; /** * Ensures "use strict" directive is added * * @param statements An array of statements */ function ensureUseStrict(statements) { var foundUseStrict = false; for (var _i = 0, statements_3 = statements; _i < statements_3.length; _i++) { var statement = statements_3[_i]; if (ts.isPrologueDirective(statement)) { if (isUseStrictPrologue(statement)) { foundUseStrict = true; break; } } else { break; } } if (!foundUseStrict) { return ts.setTextRange(ts.createNodeArray([ startOnNewLine(ts.createStatement(ts.createLiteral("use strict"))) ].concat(statements)), statements); } return statements; } ts.ensureUseStrict = ensureUseStrict; /** * Wraps the operand to a BinaryExpression in parentheses if they are needed to preserve the intended * order of operations. * * @param binaryOperator The operator for the BinaryExpression. * @param operand The operand for the BinaryExpression. * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ function parenthesizeBinaryOperand(binaryOperator, operand, isLeftSideOfBinary, leftOperand) { var skipped = ts.skipPartiallyEmittedExpressions(operand); // If the resulting expression is already parenthesized, we do not need to do any further processing. if (skipped.kind === 186 /* ParenthesizedExpression */) { return operand; } return binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) ? ts.createParen(operand) : operand; } ts.parenthesizeBinaryOperand = parenthesizeBinaryOperand; /** * Determines whether the operand to a BinaryExpression needs to be parenthesized. * * @param binaryOperator The operator for the BinaryExpression. * @param operand The operand for the BinaryExpression. * @param isLeftSideOfBinary A value indicating whether the operand is the left side of the * BinaryExpression. */ function binaryOperandNeedsParentheses(binaryOperator, operand, isLeftSideOfBinary, leftOperand) { // If the operand has lower precedence, then it needs to be parenthesized to preserve the // intent of the expression. For example, if the operand is `a + b` and the operator is // `*`, then we need to parenthesize the operand to preserve the intended order of // operations: `(a + b) * x`. // // If the operand has higher precedence, then it does not need to be parenthesized. For // example, if the operand is `a * b` and the operator is `+`, then we do not need to // parenthesize to preserve the intended order of operations: `a * b + x`. // // If the operand has the same precedence, then we need to check the associativity of // the operator based on whether this is the left or right operand of the expression. // // For example, if `a / d` is on the right of operator `*`, we need to parenthesize // to preserve the intended order of operations: `x * (a / d)` // // If `a ** d` is on the left of operator `**`, we need to parenthesize to preserve // the intended order of operations: `(a ** b) ** c` var binaryOperatorPrecedence = ts.getOperatorPrecedence(195 /* BinaryExpression */, binaryOperator); var binaryOperatorAssociativity = ts.getOperatorAssociativity(195 /* BinaryExpression */, binaryOperator); var emittedOperand = ts.skipPartiallyEmittedExpressions(operand); var operandPrecedence = ts.getExpressionPrecedence(emittedOperand); switch (ts.compareValues(operandPrecedence, binaryOperatorPrecedence)) { case -1 /* LessThan */: // If the operand is the right side of a right-associative binary operation // and is a yield expression, then we do not need parentheses. if (!isLeftSideOfBinary && binaryOperatorAssociativity === 1 /* Right */ && operand.kind === 198 /* YieldExpression */) { return false; } return true; case 1 /* GreaterThan */: return false; case 0 /* EqualTo */: if (isLeftSideOfBinary) { // No need to parenthesize the left operand when the binary operator is // left associative: // (a*b)/x -> a*b/x // (a**b)/x -> a**b/x // // Parentheses are needed for the left operand when the binary operator is // right associative: // (a/b)**x -> (a/b)**x // (a**b)**x -> (a**b)**x return binaryOperatorAssociativity === 1 /* Right */; } else { if (ts.isBinaryExpression(emittedOperand) && emittedOperand.operatorToken.kind === binaryOperator) { // No need to parenthesize the right operand when the binary operator and // operand are the same and one of the following: // x*(a*b) => x*a*b // x|(a|b) => x|a|b // x&(a&b) => x&a&b // x^(a^b) => x^a^b if (operatorHasAssociativeProperty(binaryOperator)) { return false; } // No need to parenthesize the right operand when the binary operator // is plus (+) if both the left and right operands consist solely of either // literals of the same kind or binary plus (+) expressions for literals of // the same kind (recursively). // "a"+(1+2) => "a"+(1+2) // "a"+("b"+"c") => "a"+"b"+"c" if (binaryOperator === 37 /* PlusToken */) { var leftKind = leftOperand ? getLiteralKindOfBinaryPlusOperand(leftOperand) : 0 /* Unknown */; if (ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(emittedOperand)) { return false; } } } // No need to parenthesize the right operand when the operand is right // associative: // x/(a**b) -> x/a**b // x**(a**b) -> x**a**b // // Parentheses are needed for the right operand when the operand is left // associative: // x/(a*b) -> x/(a*b) // x**(a/b) -> x**(a/b) var operandAssociativity = ts.getExpressionAssociativity(emittedOperand); return operandAssociativity === 0 /* Left */; } } } /** * Determines whether a binary operator is mathematically associative. * * @param binaryOperator The binary operator. */ function operatorHasAssociativeProperty(binaryOperator) { // The following operators are associative in JavaScript: // (a*b)*c -> a*(b*c) -> a*b*c // (a|b)|c -> a|(b|c) -> a|b|c // (a&b)&c -> a&(b&c) -> a&b&c // (a^b)^c -> a^(b^c) -> a^b^c // // While addition is associative in mathematics, JavaScript's `+` is not // guaranteed to be associative as it is overloaded with string concatenation. return binaryOperator === 39 /* AsteriskToken */ || binaryOperator === 49 /* BarToken */ || binaryOperator === 48 /* AmpersandToken */ || binaryOperator === 50 /* CaretToken */; } /** * This function determines whether an expression consists of a homogeneous set of * literal expressions or binary plus expressions that all share the same literal kind. * It is used to determine whether the right-hand operand of a binary plus expression can be * emitted without parentheses. */ function getLiteralKindOfBinaryPlusOperand(node) { node = ts.skipPartiallyEmittedExpressions(node); if (ts.isLiteralKind(node.kind)) { return node.kind; } if (node.kind === 195 /* BinaryExpression */ && node.operatorToken.kind === 37 /* PlusToken */) { if (node.cachedLiteralKind !== undefined) { return node.cachedLiteralKind; } var leftKind = getLiteralKindOfBinaryPlusOperand(node.left); var literalKind = ts.isLiteralKind(leftKind) && leftKind === getLiteralKindOfBinaryPlusOperand(node.right) ? leftKind : 0 /* Unknown */; node.cachedLiteralKind = literalKind; return literalKind; } return 0 /* Unknown */; } function parenthesizeForConditionalHead(condition) { var conditionalPrecedence = ts.getOperatorPrecedence(196 /* ConditionalExpression */, 55 /* QuestionToken */); var emittedCondition = ts.skipPartiallyEmittedExpressions(condition); var conditionPrecedence = ts.getExpressionPrecedence(emittedCondition); if (ts.compareValues(conditionPrecedence, conditionalPrecedence) === -1 /* LessThan */) { return ts.createParen(condition); } return condition; } ts.parenthesizeForConditionalHead = parenthesizeForConditionalHead; function parenthesizeSubexpressionOfConditionalExpression(e) { // per ES grammar both 'whenTrue' and 'whenFalse' parts of conditional expression are assignment expressions // so in case when comma expression is introduced as a part of previous transformations // if should be wrapped in parens since comma operator has the lowest precedence return e.kind === 195 /* BinaryExpression */ && e.operatorToken.kind === 26 /* CommaToken */ ? ts.createParen(e) : e; } ts.parenthesizeSubexpressionOfConditionalExpression = parenthesizeSubexpressionOfConditionalExpression; /** * [Per the spec](https://tc39.github.io/ecma262/#prod-ExportDeclaration), `export default` accepts _AssigmentExpression_ but * has a lookahead restriction for `function`, `async function`, and `class`. * * Basically, that means we need to parenthesize in the following cases: * * - BinaryExpression of CommaToken * - CommaList (synthetic list of multiple comma expressions) * - FunctionExpression * - ClassExpression */ function parenthesizeDefaultExpression(e) { var check = ts.skipPartiallyEmittedExpressions(e); return (check.kind === 200 /* ClassExpression */ || check.kind === 187 /* FunctionExpression */ || check.kind === 293 /* CommaListExpression */ || ts.isBinaryExpression(check) && check.operatorToken.kind === 26 /* CommaToken */) ? ts.createParen(e) : e; } ts.parenthesizeDefaultExpression = parenthesizeDefaultExpression; /** * Wraps an expression in parentheses if it is needed in order to use the expression * as the expression of a NewExpression node. * * @param expression The Expression node. */ function parenthesizeForNew(expression) { var leftmostExpr = getLeftmostExpression(expression, /*stopAtCallExpressions*/ true); switch (leftmostExpr.kind) { case 182 /* CallExpression */: return ts.createParen(expression); case 183 /* NewExpression */: return !leftmostExpr.arguments ? ts.createParen(expression) : expression; } return parenthesizeForAccess(expression); } ts.parenthesizeForNew = parenthesizeForNew; /** * Wraps an expression in parentheses if it is needed in order to use the expression for * property or element access. * * @param expr The expression node. */ function parenthesizeForAccess(expression) { // isLeftHandSideExpression is almost the correct criterion for when it is not necessary // to parenthesize the expression before a dot. The known exception is: // // NewExpression: // new C.x -> not the same as (new C).x // var emittedExpression = ts.skipPartiallyEmittedExpressions(expression); if (ts.isLeftHandSideExpression(emittedExpression) && (emittedExpression.kind !== 183 /* NewExpression */ || emittedExpression.arguments)) { return expression; } return ts.setTextRange(ts.createParen(expression), expression); } ts.parenthesizeForAccess = parenthesizeForAccess; function parenthesizePostfixOperand(operand) { return ts.isLeftHandSideExpression(operand) ? operand : ts.setTextRange(ts.createParen(operand), operand); } ts.parenthesizePostfixOperand = parenthesizePostfixOperand; function parenthesizePrefixOperand(operand) { return ts.isUnaryExpression(operand) ? operand : ts.setTextRange(ts.createParen(operand), operand); } ts.parenthesizePrefixOperand = parenthesizePrefixOperand; function parenthesizeListElements(elements) { var result; for (var i = 0; i < elements.length; i++) { var element = parenthesizeExpressionForList(elements[i]); if (result !== undefined || element !== elements[i]) { if (result === undefined) { result = elements.slice(0, i); } result.push(element); } } if (result !== undefined) { return ts.setTextRange(ts.createNodeArray(result, elements.hasTrailingComma), elements); } return elements; } ts.parenthesizeListElements = parenthesizeListElements; function parenthesizeExpressionForList(expression) { var emittedExpression = ts.skipPartiallyEmittedExpressions(expression); var expressionPrecedence = ts.getExpressionPrecedence(emittedExpression); var commaPrecedence = ts.getOperatorPrecedence(195 /* BinaryExpression */, 26 /* CommaToken */); return expressionPrecedence > commaPrecedence ? expression : ts.setTextRange(ts.createParen(expression), expression); } ts.parenthesizeExpressionForList = parenthesizeExpressionForList; function parenthesizeExpressionForExpressionStatement(expression) { var emittedExpression = ts.skipPartiallyEmittedExpressions(expression); if (ts.isCallExpression(emittedExpression)) { var callee = emittedExpression.expression; var kind = ts.skipPartiallyEmittedExpressions(callee).kind; if (kind === 187 /* FunctionExpression */ || kind === 188 /* ArrowFunction */) { var mutableCall = ts.getMutableClone(emittedExpression); mutableCall.expression = ts.setTextRange(ts.createParen(callee), callee); return recreateOuterExpressions(expression, mutableCall, 4 /* PartiallyEmittedExpressions */); } } var leftmostExpressionKind = getLeftmostExpression(emittedExpression, /*stopAtCallExpressions*/ false).kind; if (leftmostExpressionKind === 179 /* ObjectLiteralExpression */ || leftmostExpressionKind === 187 /* FunctionExpression */) { return ts.setTextRange(ts.createParen(expression), expression); } return expression; } ts.parenthesizeExpressionForExpressionStatement = parenthesizeExpressionForExpressionStatement; function parenthesizeElementTypeMember(member) { switch (member.kind) { case 167 /* UnionType */: case 168 /* IntersectionType */: case 161 /* FunctionType */: case 162 /* ConstructorType */: return ts.createParenthesizedType(member); } return member; } ts.parenthesizeElementTypeMember = parenthesizeElementTypeMember; function parenthesizeArrayTypeMember(member) { switch (member.kind) { case 163 /* TypeQuery */: case 171 /* TypeOperator */: return ts.createParenthesizedType(member); } return parenthesizeElementTypeMember(member); } ts.parenthesizeArrayTypeMember = parenthesizeArrayTypeMember; function parenthesizeElementTypeMembers(members) { return ts.createNodeArray(ts.sameMap(members, parenthesizeElementTypeMember)); } ts.parenthesizeElementTypeMembers = parenthesizeElementTypeMembers; function parenthesizeTypeParameters(typeParameters) { if (ts.some(typeParameters)) { var params = []; for (var i = 0; i < typeParameters.length; ++i) { var entry = typeParameters[i]; params.push(i === 0 && ts.isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ? ts.createParenthesizedType(entry) : entry); } return ts.createNodeArray(params); } } ts.parenthesizeTypeParameters = parenthesizeTypeParameters; function getLeftmostExpression(node, stopAtCallExpressions) { while (true) { switch (node.kind) { case 194 /* PostfixUnaryExpression */: node = node.operand; continue; case 195 /* BinaryExpression */: node = node.left; continue; case 196 /* ConditionalExpression */: node = node.condition; continue; case 182 /* CallExpression */: if (stopAtCallExpressions) { return node; } // falls through case 181 /* ElementAccessExpression */: case 180 /* PropertyAccessExpression */: node = node.expression; continue; case 292 /* PartiallyEmittedExpression */: node = node.expression; continue; } return node; } } function parenthesizeConciseBody(body) { if (!ts.isBlock(body) && getLeftmostExpression(body, /*stopAtCallExpressions*/ false).kind === 179 /* ObjectLiteralExpression */) { return ts.setTextRange(ts.createParen(body), body); } return body; } ts.parenthesizeConciseBody = parenthesizeConciseBody; var OuterExpressionKinds; (function (OuterExpressionKinds) { OuterExpressionKinds[OuterExpressionKinds["Parentheses"] = 1] = "Parentheses"; OuterExpressionKinds[OuterExpressionKinds["Assertions"] = 2] = "Assertions"; OuterExpressionKinds[OuterExpressionKinds["PartiallyEmittedExpressions"] = 4] = "PartiallyEmittedExpressions"; OuterExpressionKinds[OuterExpressionKinds["All"] = 7] = "All"; })(OuterExpressionKinds = ts.OuterExpressionKinds || (ts.OuterExpressionKinds = {})); function isOuterExpression(node, kinds) { if (kinds === void 0) { kinds = 7 /* All */; } switch (node.kind) { case 186 /* ParenthesizedExpression */: return (kinds & 1 /* Parentheses */) !== 0; case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: case 204 /* NonNullExpression */: return (kinds & 2 /* Assertions */) !== 0; case 292 /* PartiallyEmittedExpression */: return (kinds & 4 /* PartiallyEmittedExpressions */) !== 0; } return false; } ts.isOuterExpression = isOuterExpression; function skipOuterExpressions(node, kinds) { if (kinds === void 0) { kinds = 7 /* All */; } var previousNode; do { previousNode = node; if (kinds & 1 /* Parentheses */) { node = skipParentheses(node); } if (kinds & 2 /* Assertions */) { node = skipAssertions(node); } if (kinds & 4 /* PartiallyEmittedExpressions */) { node = ts.skipPartiallyEmittedExpressions(node); } } while (previousNode !== node); return node; } ts.skipOuterExpressions = skipOuterExpressions; function skipParentheses(node) { while (node.kind === 186 /* ParenthesizedExpression */) { node = node.expression; } return node; } ts.skipParentheses = skipParentheses; function skipAssertions(node) { while (ts.isAssertionExpression(node) || node.kind === 204 /* NonNullExpression */) { node = node.expression; } return node; } ts.skipAssertions = skipAssertions; function updateOuterExpression(outerExpression, expression) { switch (outerExpression.kind) { case 186 /* ParenthesizedExpression */: return ts.updateParen(outerExpression, expression); case 185 /* TypeAssertionExpression */: return ts.updateTypeAssertion(outerExpression, outerExpression.type, expression); case 203 /* AsExpression */: return ts.updateAsExpression(outerExpression, expression, outerExpression.type); case 204 /* NonNullExpression */: return ts.updateNonNullExpression(outerExpression, expression); case 292 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(outerExpression, expression); } } /** * Determines whether a node is a parenthesized expression that can be ignored when recreating outer expressions. * * A parenthesized expression can be ignored when all of the following are true: * * - It's `pos` and `end` are not -1 * - It does not have a custom source map range * - It does not have a custom comment range * - It does not have synthetic leading or trailing comments * * If an outermost parenthesized expression is ignored, but the containing expression requires a parentheses around * the expression to maintain precedence, a new parenthesized expression should be created automatically when * the containing expression is created/updated. */ function isIgnorableParen(node) { return node.kind === 186 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node) && ts.nodeIsSynthesized(ts.getSourceMapRange(node)) && ts.nodeIsSynthesized(ts.getCommentRange(node)) && !ts.some(ts.getSyntheticLeadingComments(node)) && !ts.some(ts.getSyntheticTrailingComments(node)); } function recreateOuterExpressions(outerExpression, innerExpression, kinds) { if (kinds === void 0) { kinds = 7 /* All */; } if (outerExpression && isOuterExpression(outerExpression, kinds) && !isIgnorableParen(outerExpression)) { return updateOuterExpression(outerExpression, recreateOuterExpressions(outerExpression.expression, innerExpression)); } return innerExpression; } ts.recreateOuterExpressions = recreateOuterExpressions; function startOnNewLine(node) { return ts.setStartsOnNewLine(node, /*newLine*/ true); } ts.startOnNewLine = startOnNewLine; function getExternalHelpersModuleName(node) { var parseNode = ts.getOriginalNode(node, ts.isSourceFile); var emitNode = parseNode && parseNode.emitNode; return emitNode && emitNode.externalHelpersModuleName; } ts.getExternalHelpersModuleName = getExternalHelpersModuleName; function getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions, hasExportStarsToExportValues) { if (compilerOptions.importHelpers && ts.isEffectiveExternalModule(node, compilerOptions)) { var externalHelpersModuleName = getExternalHelpersModuleName(node); if (externalHelpersModuleName) { return externalHelpersModuleName; } var moduleKind = ts.getEmitModuleKind(compilerOptions); var create = hasExportStarsToExportValues && moduleKind !== ts.ModuleKind.System && moduleKind !== ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.ESNext; if (!create) { var helpers = ts.getEmitHelpers(node); if (helpers) { for (var _i = 0, helpers_2 = helpers; _i < helpers_2.length; _i++) { var helper = helpers_2[_i]; if (!helper.scoped) { create = true; break; } } } } if (create) { var parseNode = ts.getOriginalNode(node, ts.isSourceFile); var emitNode = ts.getOrCreateEmitNode(parseNode); return emitNode.externalHelpersModuleName || (emitNode.externalHelpersModuleName = ts.createUniqueName(ts.externalHelpersModuleNameText)); } } } ts.getOrCreateExternalHelpersModuleNameIfNeeded = getOrCreateExternalHelpersModuleNameIfNeeded; /** * Get the name of that target module from an import or export declaration */ function getLocalNameForExternalImport(node, sourceFile) { var namespaceDeclaration = ts.getNamespaceDeclarationNode(node); if (namespaceDeclaration && !ts.isDefaultImport(node)) { var name = namespaceDeclaration.name; return ts.isGeneratedIdentifier(name) ? name : ts.createIdentifier(ts.getSourceTextOfNodeFromSourceFile(sourceFile, name) || ts.idText(name)); } if (node.kind === 239 /* ImportDeclaration */ && node.importClause) { return ts.getGeneratedNameForNode(node); } if (node.kind === 245 /* ExportDeclaration */ && node.moduleSpecifier) { return ts.getGeneratedNameForNode(node); } return undefined; } ts.getLocalNameForExternalImport = getLocalNameForExternalImport; /** * Get the name of a target module from an import/export declaration as should be written in the emitted output. * The emitted output name can be different from the input if: * 1. The module has a /// * 2. --out or --outFile is used, making the name relative to the rootDir * 3- The containing SourceFile has an entry in renamedDependencies for the import as requested by some module loaders (e.g. System). * Otherwise, a new StringLiteral node representing the module name will be returned. */ function getExternalModuleNameLiteral(importNode, sourceFile, host, resolver, compilerOptions) { var moduleName = ts.getExternalModuleName(importNode); if (moduleName.kind === 9 /* StringLiteral */) { return tryGetModuleNameFromDeclaration(importNode, host, resolver, compilerOptions) || tryRenameExternalModule(moduleName, sourceFile) || ts.getSynthesizedClone(moduleName); } return undefined; } ts.getExternalModuleNameLiteral = getExternalModuleNameLiteral; /** * Some bundlers (SystemJS builder) sometimes want to rename dependencies. * Here we check if alternative name was provided for a given moduleName and return it if possible. */ function tryRenameExternalModule(moduleName, sourceFile) { var rename = sourceFile.renamedDependencies && sourceFile.renamedDependencies.get(moduleName.text); return rename && ts.createLiteral(rename); } /** * Get the name of a module as should be written in the emitted output. * The emitted output name can be different from the input if: * 1. The module has a /// * 2. --out or --outFile is used, making the name relative to the rootDir * Otherwise, a new StringLiteral node representing the module name will be returned. */ function tryGetModuleNameFromFile(file, host, options) { if (!file) { return undefined; } if (file.moduleName) { return ts.createLiteral(file.moduleName); } if (!file.isDeclarationFile && (options.out || options.outFile)) { return ts.createLiteral(ts.getExternalModuleNameFromPath(host, file.fileName)); } return undefined; } ts.tryGetModuleNameFromFile = tryGetModuleNameFromFile; function tryGetModuleNameFromDeclaration(declaration, host, resolver, compilerOptions) { return tryGetModuleNameFromFile(resolver.getExternalModuleFileFromDeclaration(declaration), host, compilerOptions); } /** * Gets the initializer of an BindingOrAssignmentElement. */ function getInitializerOfBindingOrAssignmentElement(bindingElement) { if (ts.isDeclarationBindingElement(bindingElement)) { // `1` in `let { a = 1 } = ...` // `1` in `let { a: b = 1 } = ...` // `1` in `let { a: {b} = 1 } = ...` // `1` in `let { a: [b] = 1 } = ...` // `1` in `let [a = 1] = ...` // `1` in `let [{a} = 1] = ...` // `1` in `let [[a] = 1] = ...` return bindingElement.initializer; } if (ts.isPropertyAssignment(bindingElement)) { // `1` in `({ a: b = 1 } = ...)` // `1` in `({ a: {b} = 1 } = ...)` // `1` in `({ a: [b] = 1 } = ...)` return ts.isAssignmentExpression(bindingElement.initializer, /*excludeCompoundAssignment*/ true) ? bindingElement.initializer.right : undefined; } if (ts.isShorthandPropertyAssignment(bindingElement)) { // `1` in `({ a = 1 } = ...)` return bindingElement.objectAssignmentInitializer; } if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { // `1` in `[a = 1] = ...` // `1` in `[{a} = 1] = ...` // `1` in `[[a] = 1] = ...` return bindingElement.right; } if (ts.isSpreadElement(bindingElement)) { // Recovery consistent with existing emit. return getInitializerOfBindingOrAssignmentElement(bindingElement.expression); } } ts.getInitializerOfBindingOrAssignmentElement = getInitializerOfBindingOrAssignmentElement; /** * Gets the name of an BindingOrAssignmentElement. */ function getTargetOfBindingOrAssignmentElement(bindingElement) { if (ts.isDeclarationBindingElement(bindingElement)) { // `a` in `let { a } = ...` // `a` in `let { a = 1 } = ...` // `b` in `let { a: b } = ...` // `b` in `let { a: b = 1 } = ...` // `a` in `let { ...a } = ...` // `{b}` in `let { a: {b} } = ...` // `{b}` in `let { a: {b} = 1 } = ...` // `[b]` in `let { a: [b] } = ...` // `[b]` in `let { a: [b] = 1 } = ...` // `a` in `let [a] = ...` // `a` in `let [a = 1] = ...` // `a` in `let [...a] = ...` // `{a}` in `let [{a}] = ...` // `{a}` in `let [{a} = 1] = ...` // `[a]` in `let [[a]] = ...` // `[a]` in `let [[a] = 1] = ...` return bindingElement.name; } if (ts.isObjectLiteralElementLike(bindingElement)) { switch (bindingElement.kind) { case 265 /* PropertyAssignment */: // `b` in `({ a: b } = ...)` // `b` in `({ a: b = 1 } = ...)` // `{b}` in `({ a: {b} } = ...)` // `{b}` in `({ a: {b} = 1 } = ...)` // `[b]` in `({ a: [b] } = ...)` // `[b]` in `({ a: [b] = 1 } = ...)` // `b.c` in `({ a: b.c } = ...)` // `b.c` in `({ a: b.c = 1 } = ...)` // `b[0]` in `({ a: b[0] } = ...)` // `b[0]` in `({ a: b[0] = 1 } = ...)` return getTargetOfBindingOrAssignmentElement(bindingElement.initializer); case 266 /* ShorthandPropertyAssignment */: // `a` in `({ a } = ...)` // `a` in `({ a = 1 } = ...)` return bindingElement.name; case 267 /* SpreadAssignment */: // `a` in `({ ...a } = ...)` return getTargetOfBindingOrAssignmentElement(bindingElement.expression); } // no target return undefined; } if (ts.isAssignmentExpression(bindingElement, /*excludeCompoundAssignment*/ true)) { // `a` in `[a = 1] = ...` // `{a}` in `[{a} = 1] = ...` // `[a]` in `[[a] = 1] = ...` // `a.b` in `[a.b = 1] = ...` // `a[0]` in `[a[0] = 1] = ...` return getTargetOfBindingOrAssignmentElement(bindingElement.left); } if (ts.isSpreadElement(bindingElement)) { // `a` in `[...a] = ...` return getTargetOfBindingOrAssignmentElement(bindingElement.expression); } // `a` in `[a] = ...` // `{a}` in `[{a}] = ...` // `[a]` in `[[a]] = ...` // `a.b` in `[a.b] = ...` // `a[0]` in `[a[0]] = ...` return bindingElement; } ts.getTargetOfBindingOrAssignmentElement = getTargetOfBindingOrAssignmentElement; /** * Determines whether an BindingOrAssignmentElement is a rest element. */ function getRestIndicatorOfBindingOrAssignmentElement(bindingElement) { switch (bindingElement.kind) { case 147 /* Parameter */: case 177 /* BindingElement */: // `...` in `let [...a] = ...` return bindingElement.dotDotDotToken; case 199 /* SpreadElement */: case 267 /* SpreadAssignment */: // `...` in `[...a] = ...` return bindingElement; } return undefined; } ts.getRestIndicatorOfBindingOrAssignmentElement = getRestIndicatorOfBindingOrAssignmentElement; /** * Gets the property name of a BindingOrAssignmentElement */ function getPropertyNameOfBindingOrAssignmentElement(bindingElement) { switch (bindingElement.kind) { case 177 /* BindingElement */: // `a` in `let { a: b } = ...` // `[a]` in `let { [a]: b } = ...` // `"a"` in `let { "a": b } = ...` // `1` in `let { 1: b } = ...` if (bindingElement.propertyName) { var propertyName = bindingElement.propertyName; return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; } break; case 265 /* PropertyAssignment */: // `a` in `({ a: b } = ...)` // `[a]` in `({ [a]: b } = ...)` // `"a"` in `({ "a": b } = ...)` // `1` in `({ 1: b } = ...)` if (bindingElement.name) { var propertyName = bindingElement.name; return ts.isComputedPropertyName(propertyName) && ts.isStringOrNumericLiteral(propertyName.expression) ? propertyName.expression : propertyName; } break; case 267 /* SpreadAssignment */: // `a` in `({ ...a } = ...)` return bindingElement.name; } var target = getTargetOfBindingOrAssignmentElement(bindingElement); if (target && ts.isPropertyName(target)) { return ts.isComputedPropertyName(target) && ts.isStringOrNumericLiteral(target.expression) ? target.expression : target; } ts.Debug.fail("Invalid property name for binding element."); } ts.getPropertyNameOfBindingOrAssignmentElement = getPropertyNameOfBindingOrAssignmentElement; /** * Gets the elements of a BindingOrAssignmentPattern */ function getElementsOfBindingOrAssignmentPattern(name) { switch (name.kind) { case 175 /* ObjectBindingPattern */: case 176 /* ArrayBindingPattern */: case 178 /* ArrayLiteralExpression */: // `a` in `{a}` // `a` in `[a]` return name.elements; case 179 /* ObjectLiteralExpression */: // `a` in `{a}` return name.properties; } } ts.getElementsOfBindingOrAssignmentPattern = getElementsOfBindingOrAssignmentPattern; function convertToArrayAssignmentElement(element) { if (ts.isBindingElement(element)) { if (element.dotDotDotToken) { ts.Debug.assertNode(element.name, ts.isIdentifier); return ts.setOriginalNode(ts.setTextRange(ts.createSpread(element.name), element), element); } var expression = convertToAssignmentElementTarget(element.name); return element.initializer ? ts.setOriginalNode(ts.setTextRange(ts.createAssignment(expression, element.initializer), element), element) : expression; } ts.Debug.assertNode(element, ts.isExpression); return element; } ts.convertToArrayAssignmentElement = convertToArrayAssignmentElement; function convertToObjectAssignmentElement(element) { if (ts.isBindingElement(element)) { if (element.dotDotDotToken) { ts.Debug.assertNode(element.name, ts.isIdentifier); return ts.setOriginalNode(ts.setTextRange(ts.createSpreadAssignment(element.name), element), element); } if (element.propertyName) { var expression = convertToAssignmentElementTarget(element.name); return ts.setOriginalNode(ts.setTextRange(ts.createPropertyAssignment(element.propertyName, element.initializer ? ts.createAssignment(expression, element.initializer) : expression), element), element); } ts.Debug.assertNode(element.name, ts.isIdentifier); return ts.setOriginalNode(ts.setTextRange(ts.createShorthandPropertyAssignment(element.name, element.initializer), element), element); } ts.Debug.assertNode(element, ts.isObjectLiteralElementLike); return element; } ts.convertToObjectAssignmentElement = convertToObjectAssignmentElement; function convertToAssignmentPattern(node) { switch (node.kind) { case 176 /* ArrayBindingPattern */: case 178 /* ArrayLiteralExpression */: return convertToArrayAssignmentPattern(node); case 175 /* ObjectBindingPattern */: case 179 /* ObjectLiteralExpression */: return convertToObjectAssignmentPattern(node); } } ts.convertToAssignmentPattern = convertToAssignmentPattern; function convertToObjectAssignmentPattern(node) { if (ts.isObjectBindingPattern(node)) { return ts.setOriginalNode(ts.setTextRange(ts.createObjectLiteral(ts.map(node.elements, convertToObjectAssignmentElement)), node), node); } ts.Debug.assertNode(node, ts.isObjectLiteralExpression); return node; } ts.convertToObjectAssignmentPattern = convertToObjectAssignmentPattern; function convertToArrayAssignmentPattern(node) { if (ts.isArrayBindingPattern(node)) { return ts.setOriginalNode(ts.setTextRange(ts.createArrayLiteral(ts.map(node.elements, convertToArrayAssignmentElement)), node), node); } ts.Debug.assertNode(node, ts.isArrayLiteralExpression); return node; } ts.convertToArrayAssignmentPattern = convertToArrayAssignmentPattern; function convertToAssignmentElementTarget(node) { if (ts.isBindingPattern(node)) { return convertToAssignmentPattern(node); } ts.Debug.assertNode(node, ts.isExpression); return node; } ts.convertToAssignmentElementTarget = convertToAssignmentElementTarget; })(ts || (ts = {})); /// /// /// var ts; (function (ts) { function visitNode(node, visitor, test, lift) { if (node === undefined || visitor === undefined) { return node; } ts.aggregateTransformFlags(node); var visited = visitor(node); if (visited === node) { return node; } var visitedNode; if (visited === undefined) { return undefined; } else if (ts.isArray(visited)) { visitedNode = (lift || extractSingleNode)(visited); } else { visitedNode = visited; } ts.Debug.assertNode(visitedNode, test); ts.aggregateTransformFlags(visitedNode); return visitedNode; } ts.visitNode = visitNode; /** * Visits a NodeArray using the supplied visitor, possibly returning a new NodeArray in its place. * * @param nodes The NodeArray to visit. * @param visitor The callback used to visit a Node. * @param test A node test to execute for each node. * @param start An optional value indicating the starting offset at which to start visiting. * @param count An optional value indicating the maximum number of nodes to visit. */ function visitNodes(nodes, visitor, test, start, count) { if (nodes === undefined || visitor === undefined) { return nodes; } var updated; // Ensure start and count have valid values var length = nodes.length; if (start === undefined || start < 0) { start = 0; } if (count === undefined || count > length - start) { count = length - start; } if (start > 0 || count < length) { // If we are not visiting all of the original nodes, we must always create a new array. // Since this is a fragment of a node array, we do not copy over the previous location // and will only copy over `hasTrailingComma` if we are including the last element. updated = ts.createNodeArray([], /*hasTrailingComma*/ nodes.hasTrailingComma && start + count === length); } // Visit each original node. for (var i = 0; i < count; i++) { var node = nodes[i + start]; ts.aggregateTransformFlags(node); var visited = node !== undefined ? visitor(node) : undefined; if (updated !== undefined || visited === undefined || visited !== node) { if (updated === undefined) { // Ensure we have a copy of `nodes`, up to the current index. updated = ts.createNodeArray(nodes.slice(0, i), nodes.hasTrailingComma); ts.setTextRange(updated, nodes); } if (visited) { if (ts.isArray(visited)) { for (var _i = 0, visited_1 = visited; _i < visited_1.length; _i++) { var visitedNode = visited_1[_i]; ts.Debug.assertNode(visitedNode, test); ts.aggregateTransformFlags(visitedNode); updated.push(visitedNode); } } else { ts.Debug.assertNode(visited, test); ts.aggregateTransformFlags(visited); updated.push(visited); } } } } return updated || nodes; } ts.visitNodes = visitNodes; /** * Starts a new lexical environment and visits a statement list, ending the lexical environment * and merging hoisted declarations upon completion. */ function visitLexicalEnvironment(statements, visitor, context, start, ensureUseStrict) { context.startLexicalEnvironment(); statements = visitNodes(statements, visitor, ts.isStatement, start); if (ensureUseStrict && !ts.startsWithUseStrict(statements)) { statements = ts.setTextRange(ts.createNodeArray([ts.createStatement(ts.createLiteral("use strict"))].concat(statements)), statements); } var declarations = context.endLexicalEnvironment(); return ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements); } ts.visitLexicalEnvironment = visitLexicalEnvironment; /** * Starts a new lexical environment and visits a parameter list, suspending the lexical * environment upon completion. */ function visitParameterList(nodes, visitor, context, nodesVisitor) { if (nodesVisitor === void 0) { nodesVisitor = visitNodes; } context.startLexicalEnvironment(); var updated = nodesVisitor(nodes, visitor, ts.isParameterDeclaration); context.suspendLexicalEnvironment(); return updated; } ts.visitParameterList = visitParameterList; function visitFunctionBody(node, visitor, context) { context.resumeLexicalEnvironment(); var updated = visitNode(node, visitor, ts.isConciseBody); var declarations = context.endLexicalEnvironment(); if (ts.some(declarations)) { var block = ts.convertToFunctionBody(updated); var statements = ts.mergeLexicalEnvironment(block.statements, declarations); return ts.updateBlock(block, statements); } return updated; } ts.visitFunctionBody = visitFunctionBody; function visitEachChild(node, visitor, context, nodesVisitor, tokenVisitor) { if (nodesVisitor === void 0) { nodesVisitor = visitNodes; } if (node === undefined) { return undefined; } var kind = node.kind; // No need to visit nodes with no children. if ((kind > 0 /* FirstToken */ && kind <= 143 /* LastToken */) || kind === 170 /* ThisType */) { return node; } switch (kind) { // Names case 71 /* Identifier */: return ts.updateIdentifier(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode)); case 144 /* QualifiedName */: return ts.updateQualifiedName(node, visitNode(node.left, visitor, ts.isEntityName), visitNode(node.right, visitor, ts.isIdentifier)); case 145 /* ComputedPropertyName */: return ts.updateComputedPropertyName(node, visitNode(node.expression, visitor, ts.isExpression)); // Signature elements case 146 /* TypeParameter */: return ts.updateTypeParameterDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.constraint, visitor, ts.isTypeNode), visitNode(node.default, visitor, ts.isTypeNode)); case 147 /* Parameter */: return ts.updateParameter(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression)); case 148 /* Decorator */: return ts.updateDecorator(node, visitNode(node.expression, visitor, ts.isExpression)); // Type elements case 149 /* PropertySignature */: return ts.updatePropertySignature(node, nodesVisitor(node.modifiers, visitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression)); case 150 /* PropertyDeclaration */: return ts.updateProperty(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression)); case 151 /* MethodSignature */: return ts.updateMethodSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken)); case 152 /* MethodDeclaration */: return ts.updateMethod(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.questionToken, tokenVisitor, ts.isToken), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 153 /* Constructor */: return ts.updateConstructor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context)); case 154 /* GetAccessor */: return ts.updateGetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 155 /* SetAccessor */: return ts.updateSetAccessor(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isPropertyName), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitFunctionBody(node.body, visitor, context)); case 156 /* CallSignature */: return ts.updateCallSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); case 157 /* ConstructSignature */: return ts.updateConstructSignature(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); case 158 /* IndexSignature */: return ts.updateIndexSignature(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); // Types case 159 /* TypePredicate */: return ts.updateTypePredicateNode(node, visitNode(node.parameterName, visitor), visitNode(node.type, visitor, ts.isTypeNode)); case 160 /* TypeReference */: return ts.updateTypeReferenceNode(node, visitNode(node.typeName, visitor, ts.isEntityName), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode)); case 161 /* FunctionType */: return ts.updateFunctionTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); case 162 /* ConstructorType */: return ts.updateConstructorTypeNode(node, nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.parameters, visitor, ts.isParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); case 163 /* TypeQuery */: return ts.updateTypeQueryNode(node, visitNode(node.exprName, visitor, ts.isEntityName)); case 164 /* TypeLiteral */: return ts.updateTypeLiteralNode(node, nodesVisitor(node.members, visitor, ts.isTypeElement)); case 165 /* ArrayType */: return ts.updateArrayTypeNode(node, visitNode(node.elementType, visitor, ts.isTypeNode)); case 166 /* TupleType */: return ts.updateTypleTypeNode(node, nodesVisitor(node.elementTypes, visitor, ts.isTypeNode)); case 167 /* UnionType */: return ts.updateUnionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode)); case 168 /* IntersectionType */: return ts.updateIntersectionTypeNode(node, nodesVisitor(node.types, visitor, ts.isTypeNode)); case 169 /* ParenthesizedType */: return ts.updateParenthesizedType(node, visitNode(node.type, visitor, ts.isTypeNode)); case 171 /* TypeOperator */: return ts.updateTypeOperatorNode(node, visitNode(node.type, visitor, ts.isTypeNode)); case 172 /* IndexedAccessType */: return ts.updateIndexedAccessTypeNode(node, visitNode(node.objectType, visitor, ts.isTypeNode), visitNode(node.indexType, visitor, ts.isTypeNode)); case 173 /* MappedType */: return ts.updateMappedTypeNode(node, visitNode(node.readonlyToken, tokenVisitor, ts.isToken), visitNode(node.typeParameter, visitor, ts.isTypeParameterDeclaration), visitNode(node.questionToken, tokenVisitor, ts.isToken), visitNode(node.type, visitor, ts.isTypeNode)); case 174 /* LiteralType */: return ts.updateLiteralTypeNode(node, visitNode(node.literal, visitor, ts.isExpression)); // Binding patterns case 175 /* ObjectBindingPattern */: return ts.updateObjectBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isBindingElement)); case 176 /* ArrayBindingPattern */: return ts.updateArrayBindingPattern(node, nodesVisitor(node.elements, visitor, ts.isArrayBindingElement)); case 177 /* BindingElement */: return ts.updateBindingElement(node, visitNode(node.dotDotDotToken, tokenVisitor, ts.isToken), visitNode(node.propertyName, visitor, ts.isPropertyName), visitNode(node.name, visitor, ts.isBindingName), visitNode(node.initializer, visitor, ts.isExpression)); // Expression case 178 /* ArrayLiteralExpression */: return ts.updateArrayLiteral(node, nodesVisitor(node.elements, visitor, ts.isExpression)); case 179 /* ObjectLiteralExpression */: return ts.updateObjectLiteral(node, nodesVisitor(node.properties, visitor, ts.isObjectLiteralElementLike)); case 180 /* PropertyAccessExpression */: return ts.updatePropertyAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.name, visitor, ts.isIdentifier)); case 181 /* ElementAccessExpression */: return ts.updateElementAccess(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.argumentExpression, visitor, ts.isExpression)); case 182 /* CallExpression */: return ts.updateCall(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression)); case 183 /* NewExpression */: return ts.updateNew(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), nodesVisitor(node.arguments, visitor, ts.isExpression)); case 184 /* TaggedTemplateExpression */: return ts.updateTaggedTemplate(node, visitNode(node.tag, visitor, ts.isExpression), visitNode(node.template, visitor, ts.isTemplateLiteral)); case 185 /* TypeAssertionExpression */: return ts.updateTypeAssertion(node, visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression)); case 186 /* ParenthesizedExpression */: return ts.updateParen(node, visitNode(node.expression, visitor, ts.isExpression)); case 187 /* FunctionExpression */: return ts.updateFunctionExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 188 /* ArrowFunction */: return ts.updateArrowFunction(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.equalsGreaterThanToken, visitor, ts.isToken), visitFunctionBody(node.body, visitor, context)); case 189 /* DeleteExpression */: return ts.updateDelete(node, visitNode(node.expression, visitor, ts.isExpression)); case 190 /* TypeOfExpression */: return ts.updateTypeOf(node, visitNode(node.expression, visitor, ts.isExpression)); case 191 /* VoidExpression */: return ts.updateVoid(node, visitNode(node.expression, visitor, ts.isExpression)); case 192 /* AwaitExpression */: return ts.updateAwait(node, visitNode(node.expression, visitor, ts.isExpression)); case 193 /* PrefixUnaryExpression */: return ts.updatePrefix(node, visitNode(node.operand, visitor, ts.isExpression)); case 194 /* PostfixUnaryExpression */: return ts.updatePostfix(node, visitNode(node.operand, visitor, ts.isExpression)); case 195 /* BinaryExpression */: return ts.updateBinary(node, visitNode(node.left, visitor, ts.isExpression), visitNode(node.right, visitor, ts.isExpression), visitNode(node.operatorToken, visitor, ts.isToken)); case 196 /* ConditionalExpression */: return ts.updateConditional(node, visitNode(node.condition, visitor, ts.isExpression), visitNode(node.questionToken, visitor, ts.isToken), visitNode(node.whenTrue, visitor, ts.isExpression), visitNode(node.colonToken, visitor, ts.isToken), visitNode(node.whenFalse, visitor, ts.isExpression)); case 197 /* TemplateExpression */: return ts.updateTemplateExpression(node, visitNode(node.head, visitor, ts.isTemplateHead), nodesVisitor(node.templateSpans, visitor, ts.isTemplateSpan)); case 198 /* YieldExpression */: return ts.updateYield(node, visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.expression, visitor, ts.isExpression)); case 199 /* SpreadElement */: return ts.updateSpread(node, visitNode(node.expression, visitor, ts.isExpression)); case 200 /* ClassExpression */: return ts.updateClassExpression(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement)); case 202 /* ExpressionWithTypeArguments */: return ts.updateExpressionWithTypeArguments(node, nodesVisitor(node.typeArguments, visitor, ts.isTypeNode), visitNode(node.expression, visitor, ts.isExpression)); case 203 /* AsExpression */: return ts.updateAsExpression(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.type, visitor, ts.isTypeNode)); case 204 /* NonNullExpression */: return ts.updateNonNullExpression(node, visitNode(node.expression, visitor, ts.isExpression)); case 205 /* MetaProperty */: return ts.updateMetaProperty(node, visitNode(node.name, visitor, ts.isIdentifier)); // Misc case 206 /* TemplateSpan */: return ts.updateTemplateSpan(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.literal, visitor, ts.isTemplateMiddleOrTemplateTail)); // Element case 208 /* Block */: return ts.updateBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement)); case 209 /* VariableStatement */: return ts.updateVariableStatement(node, nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.declarationList, visitor, ts.isVariableDeclarationList)); case 211 /* ExpressionStatement */: return ts.updateStatement(node, visitNode(node.expression, visitor, ts.isExpression)); case 212 /* IfStatement */: return ts.updateIf(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.thenStatement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.elseStatement, visitor, ts.isStatement, ts.liftToBlock)); case 213 /* DoStatement */: return ts.updateDo(node, visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock), visitNode(node.expression, visitor, ts.isExpression)); case 214 /* WhileStatement */: return ts.updateWhile(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 215 /* ForStatement */: return ts.updateFor(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.condition, visitor, ts.isExpression), visitNode(node.incrementor, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 216 /* ForInStatement */: return ts.updateForIn(node, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 217 /* ForOfStatement */: return ts.updateForOf(node, node.awaitModifier, visitNode(node.initializer, visitor, ts.isForInitializer), visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 218 /* ContinueStatement */: return ts.updateContinue(node, visitNode(node.label, visitor, ts.isIdentifier)); case 219 /* BreakStatement */: return ts.updateBreak(node, visitNode(node.label, visitor, ts.isIdentifier)); case 220 /* ReturnStatement */: return ts.updateReturn(node, visitNode(node.expression, visitor, ts.isExpression)); case 221 /* WithStatement */: return ts.updateWith(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 222 /* SwitchStatement */: return ts.updateSwitch(node, visitNode(node.expression, visitor, ts.isExpression), visitNode(node.caseBlock, visitor, ts.isCaseBlock)); case 223 /* LabeledStatement */: return ts.updateLabel(node, visitNode(node.label, visitor, ts.isIdentifier), visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); case 224 /* ThrowStatement */: return ts.updateThrow(node, visitNode(node.expression, visitor, ts.isExpression)); case 225 /* TryStatement */: return ts.updateTry(node, visitNode(node.tryBlock, visitor, ts.isBlock), visitNode(node.catchClause, visitor, ts.isCatchClause), visitNode(node.finallyBlock, visitor, ts.isBlock)); case 227 /* VariableDeclaration */: return ts.updateVariableDeclaration(node, visitNode(node.name, visitor, ts.isBindingName), visitNode(node.type, visitor, ts.isTypeNode), visitNode(node.initializer, visitor, ts.isExpression)); case 228 /* VariableDeclarationList */: return ts.updateVariableDeclarationList(node, nodesVisitor(node.declarations, visitor, ts.isVariableDeclaration)); case 229 /* FunctionDeclaration */: return ts.updateFunctionDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.asteriskToken, tokenVisitor, ts.isToken), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitParameterList(node.parameters, visitor, context, nodesVisitor), visitNode(node.type, visitor, ts.isTypeNode), visitFunctionBody(node.body, visitor, context)); case 230 /* ClassDeclaration */: return ts.updateClassDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isClassElement)); case 231 /* InterfaceDeclaration */: return ts.updateInterfaceDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), nodesVisitor(node.heritageClauses, visitor, ts.isHeritageClause), nodesVisitor(node.members, visitor, ts.isTypeElement)); case 232 /* TypeAliasDeclaration */: return ts.updateTypeAliasDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.typeParameters, visitor, ts.isTypeParameterDeclaration), visitNode(node.type, visitor, ts.isTypeNode)); case 233 /* EnumDeclaration */: return ts.updateEnumDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), nodesVisitor(node.members, visitor, ts.isEnumMember)); case 234 /* ModuleDeclaration */: return ts.updateModuleDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.body, visitor, ts.isModuleBody)); case 235 /* ModuleBlock */: return ts.updateModuleBlock(node, nodesVisitor(node.statements, visitor, ts.isStatement)); case 236 /* CaseBlock */: return ts.updateCaseBlock(node, nodesVisitor(node.clauses, visitor, ts.isCaseOrDefaultClause)); case 237 /* NamespaceExportDeclaration */: return ts.updateNamespaceExportDeclaration(node, visitNode(node.name, visitor, ts.isIdentifier)); case 238 /* ImportEqualsDeclaration */: return ts.updateImportEqualsDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.moduleReference, visitor, ts.isModuleReference)); case 239 /* ImportDeclaration */: return ts.updateImportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.importClause, visitor, ts.isImportClause), visitNode(node.moduleSpecifier, visitor, ts.isExpression)); case 240 /* ImportClause */: return ts.updateImportClause(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.namedBindings, visitor, ts.isNamedImportBindings)); case 241 /* NamespaceImport */: return ts.updateNamespaceImport(node, visitNode(node.name, visitor, ts.isIdentifier)); case 242 /* NamedImports */: return ts.updateNamedImports(node, nodesVisitor(node.elements, visitor, ts.isImportSpecifier)); case 243 /* ImportSpecifier */: return ts.updateImportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier)); case 244 /* ExportAssignment */: return ts.updateExportAssignment(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.expression, visitor, ts.isExpression)); case 245 /* ExportDeclaration */: return ts.updateExportDeclaration(node, nodesVisitor(node.decorators, visitor, ts.isDecorator), nodesVisitor(node.modifiers, visitor, ts.isModifier), visitNode(node.exportClause, visitor, ts.isNamedExports), visitNode(node.moduleSpecifier, visitor, ts.isExpression)); case 246 /* NamedExports */: return ts.updateNamedExports(node, nodesVisitor(node.elements, visitor, ts.isExportSpecifier)); case 247 /* ExportSpecifier */: return ts.updateExportSpecifier(node, visitNode(node.propertyName, visitor, ts.isIdentifier), visitNode(node.name, visitor, ts.isIdentifier)); // Module references case 249 /* ExternalModuleReference */: return ts.updateExternalModuleReference(node, visitNode(node.expression, visitor, ts.isExpression)); // JSX case 250 /* JsxElement */: return ts.updateJsxElement(node, visitNode(node.openingElement, visitor, ts.isJsxOpeningElement), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingElement, visitor, ts.isJsxClosingElement)); case 251 /* JsxSelfClosingElement */: return ts.updateJsxSelfClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes)); case 252 /* JsxOpeningElement */: return ts.updateJsxOpeningElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression), visitNode(node.attributes, visitor, ts.isJsxAttributes)); case 253 /* JsxClosingElement */: return ts.updateJsxClosingElement(node, visitNode(node.tagName, visitor, ts.isJsxTagNameExpression)); case 254 /* JsxFragment */: return ts.updateJsxFragment(node, visitNode(node.openingFragment, visitor, ts.isJsxOpeningFragment), nodesVisitor(node.children, visitor, ts.isJsxChild), visitNode(node.closingFragment, visitor, ts.isJsxClosingFragment)); case 257 /* JsxAttribute */: return ts.updateJsxAttribute(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.initializer, visitor, ts.isStringLiteralOrJsxExpression)); case 258 /* JsxAttributes */: return ts.updateJsxAttributes(node, nodesVisitor(node.properties, visitor, ts.isJsxAttributeLike)); case 259 /* JsxSpreadAttribute */: return ts.updateJsxSpreadAttribute(node, visitNode(node.expression, visitor, ts.isExpression)); case 260 /* JsxExpression */: return ts.updateJsxExpression(node, visitNode(node.expression, visitor, ts.isExpression)); // Clauses case 261 /* CaseClause */: return ts.updateCaseClause(node, visitNode(node.expression, visitor, ts.isExpression), nodesVisitor(node.statements, visitor, ts.isStatement)); case 262 /* DefaultClause */: return ts.updateDefaultClause(node, nodesVisitor(node.statements, visitor, ts.isStatement)); case 263 /* HeritageClause */: return ts.updateHeritageClause(node, nodesVisitor(node.types, visitor, ts.isExpressionWithTypeArguments)); case 264 /* CatchClause */: return ts.updateCatchClause(node, visitNode(node.variableDeclaration, visitor, ts.isVariableDeclaration), visitNode(node.block, visitor, ts.isBlock)); // Property assignments case 265 /* PropertyAssignment */: return ts.updatePropertyAssignment(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression)); case 266 /* ShorthandPropertyAssignment */: return ts.updateShorthandPropertyAssignment(node, visitNode(node.name, visitor, ts.isIdentifier), visitNode(node.objectAssignmentInitializer, visitor, ts.isExpression)); case 267 /* SpreadAssignment */: return ts.updateSpreadAssignment(node, visitNode(node.expression, visitor, ts.isExpression)); // Enum case 268 /* EnumMember */: return ts.updateEnumMember(node, visitNode(node.name, visitor, ts.isPropertyName), visitNode(node.initializer, visitor, ts.isExpression)); // Top-level nodes case 269 /* SourceFile */: return ts.updateSourceFileNode(node, visitLexicalEnvironment(node.statements, visitor, context)); // Transformation nodes case 292 /* PartiallyEmittedExpression */: return ts.updatePartiallyEmittedExpression(node, visitNode(node.expression, visitor, ts.isExpression)); case 293 /* CommaListExpression */: return ts.updateCommaList(node, nodesVisitor(node.elements, visitor, ts.isExpression)); default: // No need to visit nodes with no children. return node; } } ts.visitEachChild = visitEachChild; /** * Extracts the single node from a NodeArray. * * @param nodes The NodeArray. */ function extractSingleNode(nodes) { ts.Debug.assert(nodes.length <= 1, "Too many nodes written to output."); return ts.singleOrUndefined(nodes); } })(ts || (ts = {})); /* @internal */ (function (ts) { function reduceNode(node, f, initial) { return node ? f(initial, node) : initial; } function reduceNodeArray(nodes, f, initial) { return nodes ? f(initial, nodes) : initial; } /** * Similar to `reduceLeft`, performs a reduction against each child of a node. * NOTE: Unlike `forEachChild`, this does *not* visit every node. * * @param node The node containing the children to reduce. * @param initial The initial value to supply to the reduction. * @param f The callback function */ function reduceEachChild(node, initial, cbNode, cbNodeArray) { if (node === undefined) { return initial; } var reduceNodes = cbNodeArray ? reduceNodeArray : ts.reduceLeft; var cbNodes = cbNodeArray || cbNode; var kind = node.kind; // No need to visit nodes with no children. if ((kind > 0 /* FirstToken */ && kind <= 143 /* LastToken */)) { return initial; } // We do not yet support types. if ((kind >= 159 /* TypePredicate */ && kind <= 174 /* LiteralType */)) { return initial; } var result = initial; switch (node.kind) { // Leaf nodes case 207 /* SemicolonClassElement */: case 210 /* EmptyStatement */: case 201 /* OmittedExpression */: case 226 /* DebuggerStatement */: case 291 /* NotEmittedStatement */: // No need to visit nodes with no children. break; // Names case 144 /* QualifiedName */: result = reduceNode(node.left, cbNode, result); result = reduceNode(node.right, cbNode, result); break; case 145 /* ComputedPropertyName */: result = reduceNode(node.expression, cbNode, result); break; // Signature elements case 147 /* Parameter */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 148 /* Decorator */: result = reduceNode(node.expression, cbNode, result); break; // Type member case 149 /* PropertySignature */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.questionToken, cbNode, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 150 /* PropertyDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 152 /* MethodDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 153 /* Constructor */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.body, cbNode, result); break; case 154 /* GetAccessor */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 155 /* SetAccessor */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.body, cbNode, result); break; // Binding patterns case 175 /* ObjectBindingPattern */: case 176 /* ArrayBindingPattern */: result = reduceNodes(node.elements, cbNodes, result); break; case 177 /* BindingElement */: result = reduceNode(node.propertyName, cbNode, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; // Expression case 178 /* ArrayLiteralExpression */: result = reduceNodes(node.elements, cbNodes, result); break; case 179 /* ObjectLiteralExpression */: result = reduceNodes(node.properties, cbNodes, result); break; case 180 /* PropertyAccessExpression */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.name, cbNode, result); break; case 181 /* ElementAccessExpression */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.argumentExpression, cbNode, result); break; case 182 /* CallExpression */: result = reduceNode(node.expression, cbNode, result); result = reduceNodes(node.typeArguments, cbNodes, result); result = reduceNodes(node.arguments, cbNodes, result); break; case 183 /* NewExpression */: result = reduceNode(node.expression, cbNode, result); result = reduceNodes(node.typeArguments, cbNodes, result); result = reduceNodes(node.arguments, cbNodes, result); break; case 184 /* TaggedTemplateExpression */: result = reduceNode(node.tag, cbNode, result); result = reduceNode(node.template, cbNode, result); break; case 185 /* TypeAssertionExpression */: result = reduceNode(node.type, cbNode, result); result = reduceNode(node.expression, cbNode, result); break; case 187 /* FunctionExpression */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 188 /* ArrowFunction */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 186 /* ParenthesizedExpression */: case 189 /* DeleteExpression */: case 190 /* TypeOfExpression */: case 191 /* VoidExpression */: case 192 /* AwaitExpression */: case 198 /* YieldExpression */: case 199 /* SpreadElement */: case 204 /* NonNullExpression */: result = reduceNode(node.expression, cbNode, result); break; case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: result = reduceNode(node.operand, cbNode, result); break; case 195 /* BinaryExpression */: result = reduceNode(node.left, cbNode, result); result = reduceNode(node.right, cbNode, result); break; case 196 /* ConditionalExpression */: result = reduceNode(node.condition, cbNode, result); result = reduceNode(node.whenTrue, cbNode, result); result = reduceNode(node.whenFalse, cbNode, result); break; case 197 /* TemplateExpression */: result = reduceNode(node.head, cbNode, result); result = reduceNodes(node.templateSpans, cbNodes, result); break; case 200 /* ClassExpression */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.heritageClauses, cbNodes, result); result = reduceNodes(node.members, cbNodes, result); break; case 202 /* ExpressionWithTypeArguments */: result = reduceNode(node.expression, cbNode, result); result = reduceNodes(node.typeArguments, cbNodes, result); break; case 203 /* AsExpression */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.type, cbNode, result); break; // Misc case 206 /* TemplateSpan */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.literal, cbNode, result); break; // Element case 208 /* Block */: result = reduceNodes(node.statements, cbNodes, result); break; case 209 /* VariableStatement */: result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.declarationList, cbNode, result); break; case 211 /* ExpressionStatement */: result = reduceNode(node.expression, cbNode, result); break; case 212 /* IfStatement */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.thenStatement, cbNode, result); result = reduceNode(node.elseStatement, cbNode, result); break; case 213 /* DoStatement */: result = reduceNode(node.statement, cbNode, result); result = reduceNode(node.expression, cbNode, result); break; case 214 /* WhileStatement */: case 221 /* WithStatement */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.statement, cbNode, result); break; case 215 /* ForStatement */: result = reduceNode(node.initializer, cbNode, result); result = reduceNode(node.condition, cbNode, result); result = reduceNode(node.incrementor, cbNode, result); result = reduceNode(node.statement, cbNode, result); break; case 216 /* ForInStatement */: case 217 /* ForOfStatement */: result = reduceNode(node.initializer, cbNode, result); result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.statement, cbNode, result); break; case 220 /* ReturnStatement */: case 224 /* ThrowStatement */: result = reduceNode(node.expression, cbNode, result); break; case 222 /* SwitchStatement */: result = reduceNode(node.expression, cbNode, result); result = reduceNode(node.caseBlock, cbNode, result); break; case 223 /* LabeledStatement */: result = reduceNode(node.label, cbNode, result); result = reduceNode(node.statement, cbNode, result); break; case 225 /* TryStatement */: result = reduceNode(node.tryBlock, cbNode, result); result = reduceNode(node.catchClause, cbNode, result); result = reduceNode(node.finallyBlock, cbNode, result); break; case 227 /* VariableDeclaration */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 228 /* VariableDeclarationList */: result = reduceNodes(node.declarations, cbNodes, result); break; case 229 /* FunctionDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.parameters, cbNodes, result); result = reduceNode(node.type, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 230 /* ClassDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.typeParameters, cbNodes, result); result = reduceNodes(node.heritageClauses, cbNodes, result); result = reduceNodes(node.members, cbNodes, result); break; case 233 /* EnumDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNodes(node.members, cbNodes, result); break; case 234 /* ModuleDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.body, cbNode, result); break; case 235 /* ModuleBlock */: result = reduceNodes(node.statements, cbNodes, result); break; case 236 /* CaseBlock */: result = reduceNodes(node.clauses, cbNodes, result); break; case 238 /* ImportEqualsDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.name, cbNode, result); result = reduceNode(node.moduleReference, cbNode, result); break; case 239 /* ImportDeclaration */: result = reduceNodes(node.decorators, cbNodes, result); result = reduceNodes(node.modifiers, cbNodes, result); result = reduceNode(node.importClause, cbNode, result); result = reduceNode(node.moduleSpecifier, cbNode, result); break; case 240 /* ImportClause */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.namedBindings, cbNode, result); break; case 241 /* NamespaceImport */: result = reduceNode(node.name, cbNode, result); break; case 242 /* NamedImports */: case 246 /* NamedExports */: result = reduceNodes(node.elements, cbNodes, result); break; case 243 /* ImportSpecifier */: case 247 /* ExportSpecifier */: result = reduceNode(node.propertyName, cbNode, result); result = reduceNode(node.name, cbNode, result); break; case 244 /* ExportAssignment */: result = ts.reduceLeft(node.decorators, cbNode, result); result = ts.reduceLeft(node.modifiers, cbNode, result); result = reduceNode(node.expression, cbNode, result); break; case 245 /* ExportDeclaration */: result = ts.reduceLeft(node.decorators, cbNode, result); result = ts.reduceLeft(node.modifiers, cbNode, result); result = reduceNode(node.exportClause, cbNode, result); result = reduceNode(node.moduleSpecifier, cbNode, result); break; // Module references case 249 /* ExternalModuleReference */: result = reduceNode(node.expression, cbNode, result); break; // JSX case 250 /* JsxElement */: result = reduceNode(node.openingElement, cbNode, result); result = ts.reduceLeft(node.children, cbNode, result); result = reduceNode(node.closingElement, cbNode, result); break; case 254 /* JsxFragment */: result = reduceNode(node.openingFragment, cbNode, result); result = ts.reduceLeft(node.children, cbNode, result); result = reduceNode(node.closingFragment, cbNode, result); break; case 251 /* JsxSelfClosingElement */: case 252 /* JsxOpeningElement */: result = reduceNode(node.tagName, cbNode, result); result = reduceNode(node.attributes, cbNode, result); break; case 258 /* JsxAttributes */: result = reduceNodes(node.properties, cbNodes, result); break; case 253 /* JsxClosingElement */: result = reduceNode(node.tagName, cbNode, result); break; case 257 /* JsxAttribute */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 259 /* JsxSpreadAttribute */: result = reduceNode(node.expression, cbNode, result); break; case 260 /* JsxExpression */: result = reduceNode(node.expression, cbNode, result); break; // Clauses case 261 /* CaseClause */: result = reduceNode(node.expression, cbNode, result); // falls through case 262 /* DefaultClause */: result = reduceNodes(node.statements, cbNodes, result); break; case 263 /* HeritageClause */: result = reduceNodes(node.types, cbNodes, result); break; case 264 /* CatchClause */: result = reduceNode(node.variableDeclaration, cbNode, result); result = reduceNode(node.block, cbNode, result); break; // Property assignments case 265 /* PropertyAssignment */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; case 266 /* ShorthandPropertyAssignment */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.objectAssignmentInitializer, cbNode, result); break; case 267 /* SpreadAssignment */: result = reduceNode(node.expression, cbNode, result); break; // Enum case 268 /* EnumMember */: result = reduceNode(node.name, cbNode, result); result = reduceNode(node.initializer, cbNode, result); break; // Top-level nodes case 269 /* SourceFile */: result = reduceNodes(node.statements, cbNodes, result); break; // Transformation nodes case 292 /* PartiallyEmittedExpression */: result = reduceNode(node.expression, cbNode, result); break; case 293 /* CommaListExpression */: result = reduceNodes(node.elements, cbNodes, result); break; default: break; } return result; } ts.reduceEachChild = reduceEachChild; function mergeLexicalEnvironment(statements, declarations) { if (!ts.some(declarations)) { return statements; } return ts.isNodeArray(statements) ? ts.setTextRange(ts.createNodeArray(ts.concatenate(statements, declarations)), statements) : ts.addRange(statements, declarations); } ts.mergeLexicalEnvironment = mergeLexicalEnvironment; /** * Lifts a NodeArray containing only Statement nodes to a block. * * @param nodes The NodeArray. */ function liftToBlock(nodes) { Debug.assert(ts.every(nodes, ts.isStatement), "Cannot lift nodes to a Block."); return ts.singleOrUndefined(nodes) || ts.createBlock(nodes); } ts.liftToBlock = liftToBlock; /** * Aggregates the TransformFlags for a Node and its subtree. */ function aggregateTransformFlags(node) { aggregateTransformFlagsForNode(node); return node; } ts.aggregateTransformFlags = aggregateTransformFlags; /** * Aggregates the TransformFlags for a Node and its subtree. The flags for the subtree are * computed first, then the transform flags for the current node are computed from the subtree * flags and the state of the current node. Finally, the transform flags of the node are * returned, excluding any flags that should not be included in its parent node's subtree * flags. */ function aggregateTransformFlagsForNode(node) { if (node === undefined) { return 0 /* None */; } if (node.transformFlags & 536870912 /* HasComputedFlags */) { return node.transformFlags & ~ts.getTransformFlagsSubtreeExclusions(node.kind); } var subtreeFlags = aggregateTransformFlagsForSubtree(node); return ts.computeTransformFlagsForNode(node, subtreeFlags); } function aggregateTransformFlagsForNodeArray(nodes) { if (nodes === undefined) { return 0 /* None */; } var subtreeFlags = 0 /* None */; var nodeArrayFlags = 0 /* None */; for (var _i = 0, nodes_3 = nodes; _i < nodes_3.length; _i++) { var node = nodes_3[_i]; subtreeFlags |= aggregateTransformFlagsForNode(node); nodeArrayFlags |= node.transformFlags & ~536870912 /* HasComputedFlags */; } nodes.transformFlags = nodeArrayFlags | 536870912 /* HasComputedFlags */; return subtreeFlags; } /** * Aggregates the transform flags for the subtree of a node. */ function aggregateTransformFlagsForSubtree(node) { // We do not transform ambient declarations or types, so there is no need to // recursively aggregate transform flags. if (ts.hasModifier(node, 2 /* Ambient */) || (ts.isTypeNode(node) && node.kind !== 202 /* ExpressionWithTypeArguments */)) { return 0 /* None */; } // Aggregate the transform flags of each child. return reduceEachChild(node, 0 /* None */, aggregateTransformFlagsForChildNode, aggregateTransformFlagsForChildNodes); } /** * Aggregates the TransformFlags of a child node with the TransformFlags of its * siblings. */ function aggregateTransformFlagsForChildNode(transformFlags, node) { return transformFlags | aggregateTransformFlagsForNode(node); } function aggregateTransformFlagsForChildNodes(transformFlags, nodes) { return transformFlags | aggregateTransformFlagsForNodeArray(nodes); } var Debug; (function (Debug) { var isDebugInfoEnabled = false; Debug.failBadSyntaxKind = Debug.shouldAssert(1 /* Normal */) ? function (node, message) { return Debug.fail((message || "Unexpected node.") + "\r\nNode " + ts.formatSyntaxKind(node.kind) + " was unexpected.", Debug.failBadSyntaxKind); } : ts.noop; Debug.assertEachNode = Debug.shouldAssert(1 /* Normal */) ? function (nodes, test, message) { return Debug.assert(test === undefined || ts.every(nodes, test), message || "Unexpected node.", function () { return "Node array did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertEachNode); } : ts.noop; Debug.assertNode = Debug.shouldAssert(1 /* Normal */) ? function (node, test, message) { return Debug.assert(test === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertNode); } : ts.noop; Debug.assertOptionalNode = Debug.shouldAssert(1 /* Normal */) ? function (node, test, message) { return Debug.assert(test === undefined || node === undefined || test(node), message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " did not pass test '" + Debug.getFunctionName(test) + "'."; }, Debug.assertOptionalNode); } : ts.noop; Debug.assertOptionalToken = Debug.shouldAssert(1 /* Normal */) ? function (node, kind, message) { return Debug.assert(kind === undefined || node === undefined || node.kind === kind, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was not a '" + ts.formatSyntaxKind(kind) + "' token."; }, Debug.assertOptionalToken); } : ts.noop; Debug.assertMissingNode = Debug.shouldAssert(1 /* Normal */) ? function (node, message) { return Debug.assert(node === undefined, message || "Unexpected node.", function () { return "Node " + ts.formatSyntaxKind(node.kind) + " was unexpected'."; }, Debug.assertMissingNode); } : ts.noop; /** * Injects debug information into frequently used types. */ function enableDebugInfo() { if (isDebugInfoEnabled) return; // Add additional properties in debug mode to assist with debugging. Object.defineProperties(ts.objectAllocator.getSymbolConstructor().prototype, { __debugFlags: { get: function () { return ts.formatSymbolFlags(this.flags); } } }); Object.defineProperties(ts.objectAllocator.getTypeConstructor().prototype, { __debugFlags: { get: function () { return ts.formatTypeFlags(this.flags); } }, __debugObjectFlags: { get: function () { return this.flags & 65536 /* Object */ ? ts.formatObjectFlags(this.objectFlags) : ""; } }, __debugTypeToString: { value: function () { return this.checker.typeToString(this); } }, }); var nodeConstructors = [ ts.objectAllocator.getNodeConstructor(), ts.objectAllocator.getIdentifierConstructor(), ts.objectAllocator.getTokenConstructor(), ts.objectAllocator.getSourceFileConstructor() ]; for (var _i = 0, nodeConstructors_1 = nodeConstructors; _i < nodeConstructors_1.length; _i++) { var ctor = nodeConstructors_1[_i]; if (!ctor.prototype.hasOwnProperty("__debugKind")) { Object.defineProperties(ctor.prototype, { __debugKind: { get: function () { return ts.formatSyntaxKind(this.kind); } }, __debugModifierFlags: { get: function () { return ts.formatModifierFlags(ts.getModifierFlagsNoCache(this)); } }, __debugTransformFlags: { get: function () { return ts.formatTransformFlags(this.transformFlags); } }, __debugEmitFlags: { get: function () { return ts.formatEmitFlags(ts.getEmitFlags(this)); } }, __debugGetText: { value: function (includeTrivia) { if (ts.nodeIsSynthesized(this)) return ""; var parseNode = ts.getParseTreeNode(this); var sourceFile = parseNode && ts.getSourceFileOfNode(parseNode); return sourceFile ? ts.getSourceTextOfNodeFromSourceFile(sourceFile, parseNode, includeTrivia) : ""; } } }); } } isDebugInfoEnabled = true; } Debug.enableDebugInfo = enableDebugInfo; })(Debug = ts.Debug || (ts.Debug = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { function getOriginalNodeId(node) { node = ts.getOriginalNode(node); return node ? ts.getNodeId(node) : 0; } ts.getOriginalNodeId = getOriginalNodeId; function collectExternalModuleInfo(sourceFile, resolver, compilerOptions) { var externalImports = []; var exportSpecifiers = ts.createMultiMap(); var exportedBindings = []; var uniqueExports = ts.createMap(); var exportedNames; var hasExportDefault = false; var exportEquals = undefined; var hasExportStarsToExportValues = false; for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) { var node = _a[_i]; switch (node.kind) { case 239 /* ImportDeclaration */: // import "mod" // import x from "mod" // import * as x from "mod" // import { x, y } from "mod" externalImports.push(node); break; case 238 /* ImportEqualsDeclaration */: if (node.moduleReference.kind === 249 /* ExternalModuleReference */) { // import x = require("mod") externalImports.push(node); } break; case 245 /* ExportDeclaration */: if (node.moduleSpecifier) { if (!node.exportClause) { // export * from "mod" externalImports.push(node); hasExportStarsToExportValues = true; } else { // export { x, y } from "mod" externalImports.push(node); } } else { // export { x, y } for (var _b = 0, _c = node.exportClause.elements; _b < _c.length; _b++) { var specifier = _c[_b]; if (!uniqueExports.get(ts.idText(specifier.name))) { var name = specifier.propertyName || specifier.name; exportSpecifiers.add(ts.idText(name), specifier); var decl = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name); if (decl) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(decl), specifier.name); } uniqueExports.set(ts.idText(specifier.name), true); exportedNames = ts.append(exportedNames, specifier.name); } } } break; case 244 /* ExportAssignment */: if (node.isExportEquals && !exportEquals) { // export = x exportEquals = node; } break; case 209 /* VariableStatement */: if (ts.hasModifier(node, 1 /* Export */)) { for (var _d = 0, _e = node.declarationList.declarations; _d < _e.length; _d++) { var decl = _e[_d]; exportedNames = collectExportedVariableInfo(decl, uniqueExports, exportedNames); } } break; case 229 /* FunctionDeclaration */: if (ts.hasModifier(node, 1 /* Export */)) { if (ts.hasModifier(node, 512 /* Default */)) { // export default function() { } if (!hasExportDefault) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node)); hasExportDefault = true; } } else { // export function x() { } var name = node.name; if (!uniqueExports.get(ts.idText(name))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.idText(name), true); exportedNames = ts.append(exportedNames, name); } } } break; case 230 /* ClassDeclaration */: if (ts.hasModifier(node, 1 /* Export */)) { if (ts.hasModifier(node, 512 /* Default */)) { // export default class { } if (!hasExportDefault) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), ts.getDeclarationName(node)); hasExportDefault = true; } } else { // export class x { } var name = node.name; if (name && !uniqueExports.get(ts.idText(name))) { multiMapSparseArrayAdd(exportedBindings, getOriginalNodeId(node), name); uniqueExports.set(ts.idText(name), true); exportedNames = ts.append(exportedNames, name); } } } break; } } var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(sourceFile, compilerOptions, hasExportStarsToExportValues); var externalHelpersImportDeclaration = externalHelpersModuleName && ts.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText)); if (externalHelpersImportDeclaration) { externalImports.unshift(externalHelpersImportDeclaration); } return { externalImports: externalImports, exportSpecifiers: exportSpecifiers, exportEquals: exportEquals, hasExportStarsToExportValues: hasExportStarsToExportValues, exportedBindings: exportedBindings, exportedNames: exportedNames, externalHelpersImportDeclaration: externalHelpersImportDeclaration }; } ts.collectExternalModuleInfo = collectExternalModuleInfo; function collectExportedVariableInfo(decl, uniqueExports, exportedNames) { if (ts.isBindingPattern(decl.name)) { for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { exportedNames = collectExportedVariableInfo(element, uniqueExports, exportedNames); } } } else if (!ts.isGeneratedIdentifier(decl.name)) { var text = ts.idText(decl.name); if (!uniqueExports.get(text)) { uniqueExports.set(text, true); exportedNames = ts.append(exportedNames, decl.name); } } return exportedNames; } /** Use a sparse array as a multi-map. */ function multiMapSparseArrayAdd(map, key, value) { var values = map[key]; if (values) { values.push(value); } else { map[key] = values = [value]; } return values; } /** * Used in the module transformer to check if an expression is reasonably without sideeffect, * and thus better to copy into multiple places rather than to cache in a temporary variable * - this is mostly subjective beyond the requirement that the expression not be sideeffecting */ function isSimpleCopiableExpression(expression) { return expression.kind === 9 /* StringLiteral */ || expression.kind === 8 /* NumericLiteral */ || expression.kind === 13 /* NoSubstitutionTemplateLiteral */ || ts.isKeyword(expression.kind) || ts.isIdentifier(expression); } ts.isSimpleCopiableExpression = isSimpleCopiableExpression; })(ts || (ts = {})); /// /// /*@internal*/ var ts; (function (ts) { var FlattenLevel; (function (FlattenLevel) { FlattenLevel[FlattenLevel["All"] = 0] = "All"; FlattenLevel[FlattenLevel["ObjectRest"] = 1] = "ObjectRest"; })(FlattenLevel = ts.FlattenLevel || (ts.FlattenLevel = {})); /** * Flattens a DestructuringAssignment or a VariableDeclaration to an expression. * * @param node The node to flatten. * @param visitor An optional visitor used to visit initializers. * @param context The transformation context. * @param level Indicates the extent to which flattening should occur. * @param needsValue An optional value indicating whether the value from the right-hand-side of * the destructuring assignment is needed as part of a larger expression. * @param createAssignmentCallback An optional callback used to create the assignment expression. */ function flattenDestructuringAssignment(node, visitor, context, level, needsValue, createAssignmentCallback) { var location = node; var value; if (ts.isDestructuringAssignment(node)) { value = node.right; while (ts.isEmptyArrayLiteral(node.left) || ts.isEmptyObjectLiteral(node.left)) { if (ts.isDestructuringAssignment(value)) { location = node = value; value = node.right; } else { return value; } } } var expressions; var flattenContext = { context: context, level: level, downlevelIteration: context.getCompilerOptions().downlevelIteration, hoistTempVariables: true, emitExpression: emitExpression, emitBindingOrAssignment: emitBindingOrAssignment, createArrayBindingOrAssignmentPattern: makeArrayAssignmentPattern, createObjectBindingOrAssignmentPattern: makeObjectAssignmentPattern, createArrayBindingOrAssignmentElement: makeAssignmentElement, visitor: visitor }; if (value) { value = ts.visitNode(value, visitor, ts.isExpression); if (needsValue) { // If the right-hand value of the destructuring assignment needs to be preserved (as // is the case when the destructuring assignment is part of a larger expression), // then we need to cache the right-hand value. // // The source map location for the assignment should point to the entire binary // expression. value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); } else if (ts.nodeIsSynthesized(node)) { // Generally, the source map location for a destructuring assignment is the root // expression. // // However, if the root expression is synthesized (as in the case // of the initializer when transforming a ForOfStatement), then the source map // location should point to the right-hand value of the expression. location = value; } } flattenBindingOrAssignmentElement(flattenContext, node, value, location, /*skipInitializer*/ ts.isDestructuringAssignment(node)); if (value && needsValue) { if (!ts.some(expressions)) { return value; } expressions.push(value); } return ts.aggregateTransformFlags(ts.inlineExpressions(expressions)) || ts.createOmittedExpression(); function emitExpression(expression) { // NOTE: this completely disables source maps, but aligns with the behavior of // `emitAssignment` in the old emitter. ts.setEmitFlags(expression, 64 /* NoNestedSourceMaps */); ts.aggregateTransformFlags(expression); expressions = ts.append(expressions, expression); } function emitBindingOrAssignment(target, value, location, original) { ts.Debug.assertNode(target, createAssignmentCallback ? ts.isIdentifier : ts.isExpression); var expression = createAssignmentCallback ? createAssignmentCallback(target, value, location) : ts.setTextRange(ts.createAssignment(ts.visitNode(target, visitor, ts.isExpression), value), location); expression.original = original; emitExpression(expression); } } ts.flattenDestructuringAssignment = flattenDestructuringAssignment; /** * Flattens a VariableDeclaration or ParameterDeclaration to one or more variable declarations. * * @param node The node to flatten. * @param visitor An optional visitor used to visit initializers. * @param context The transformation context. * @param boundValue The value bound to the declaration. * @param skipInitializer A value indicating whether to ignore the initializer of `node`. * @param hoistTempVariables Indicates whether temporary variables should not be recorded in-line. * @param level Indicates the extent to which flattening should occur. */ function flattenDestructuringBinding(node, visitor, context, level, rval, hoistTempVariables, skipInitializer) { var pendingExpressions; var pendingDeclarations = []; var declarations = []; var flattenContext = { context: context, level: level, downlevelIteration: context.getCompilerOptions().downlevelIteration, hoistTempVariables: hoistTempVariables, emitExpression: emitExpression, emitBindingOrAssignment: emitBindingOrAssignment, createArrayBindingOrAssignmentPattern: makeArrayBindingPattern, createObjectBindingOrAssignmentPattern: makeObjectBindingPattern, createArrayBindingOrAssignmentElement: makeBindingElement, visitor: visitor }; flattenBindingOrAssignmentElement(flattenContext, node, rval, node, skipInitializer); if (pendingExpressions) { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); if (hoistTempVariables) { var value = ts.inlineExpressions(pendingExpressions); pendingExpressions = undefined; emitBindingOrAssignment(temp, value, /*location*/ undefined, /*original*/ undefined); } else { context.hoistVariableDeclaration(temp); var pendingDeclaration = ts.lastOrUndefined(pendingDeclarations); pendingDeclaration.pendingExpressions = ts.append(pendingDeclaration.pendingExpressions, ts.createAssignment(temp, pendingDeclaration.value)); ts.addRange(pendingDeclaration.pendingExpressions, pendingExpressions); pendingDeclaration.value = temp; } } for (var _i = 0, pendingDeclarations_1 = pendingDeclarations; _i < pendingDeclarations_1.length; _i++) { var _a = pendingDeclarations_1[_i], pendingExpressions_1 = _a.pendingExpressions, name = _a.name, value = _a.value, location = _a.location, original = _a.original; var variable = ts.createVariableDeclaration(name, /*type*/ undefined, pendingExpressions_1 ? ts.inlineExpressions(ts.append(pendingExpressions_1, value)) : value); variable.original = original; ts.setTextRange(variable, location); if (ts.isIdentifier(name)) { ts.setEmitFlags(variable, 64 /* NoNestedSourceMaps */); } ts.aggregateTransformFlags(variable); declarations.push(variable); } return declarations; function emitExpression(value) { pendingExpressions = ts.append(pendingExpressions, value); } function emitBindingOrAssignment(target, value, location, original) { ts.Debug.assertNode(target, ts.isBindingName); if (pendingExpressions) { value = ts.inlineExpressions(ts.append(pendingExpressions, value)); pendingExpressions = undefined; } pendingDeclarations.push({ pendingExpressions: pendingExpressions, name: target, value: value, location: location, original: original }); } } ts.flattenDestructuringBinding = flattenDestructuringBinding; /** * Flattens a BindingOrAssignmentElement into zero or more bindings or assignments. * * @param flattenContext Options used to control flattening. * @param element The element to flatten. * @param value The current RHS value to assign to the element. * @param location The location to use for source maps and comments. * @param skipInitializer An optional value indicating whether to include the initializer * for the element. */ function flattenBindingOrAssignmentElement(flattenContext, element, value, location, skipInitializer) { if (!skipInitializer) { var initializer = ts.visitNode(ts.getInitializerOfBindingOrAssignmentElement(element), flattenContext.visitor, ts.isExpression); if (initializer) { // Combine value and initializer value = value ? createDefaultValueCheck(flattenContext, value, initializer, location) : initializer; } else if (!value) { // Use 'void 0' in absence of value and initializer value = ts.createVoidZero(); } } var bindingTarget = ts.getTargetOfBindingOrAssignmentElement(element); if (ts.isObjectBindingOrAssignmentPattern(bindingTarget)) { flattenObjectBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location); } else if (ts.isArrayBindingOrAssignmentPattern(bindingTarget)) { flattenArrayBindingOrAssignmentPattern(flattenContext, element, bindingTarget, value, location); } else { flattenContext.emitBindingOrAssignment(bindingTarget, value, location, /*original*/ element); } } /** * Flattens an ObjectBindingOrAssignmentPattern into zero or more bindings or assignments. * * @param flattenContext Options used to control flattening. * @param parent The parent element of the pattern. * @param pattern The ObjectBindingOrAssignmentPattern to flatten. * @param value The current RHS value to assign to the element. * @param location The location to use for source maps and comments. */ function flattenObjectBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) { var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern); var numElements = elements.length; if (numElements !== 1) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } var bindingElements; var computedTempVariables; for (var i = 0; i < numElements; i++) { var element = elements[i]; if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) { var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(element); if (flattenContext.level >= 1 /* ObjectRest */ && !(element.transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */)) && !(ts.getTargetOfBindingOrAssignmentElement(element).transformFlags & (524288 /* ContainsRest */ | 1048576 /* ContainsObjectRest */)) && !ts.isComputedPropertyName(propertyName)) { bindingElements = ts.append(bindingElements, element); } else { if (bindingElements) { flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern); bindingElements = undefined; } var rhsValue = createDestructuringPropertyAccess(flattenContext, value, propertyName); if (ts.isComputedPropertyName(propertyName)) { computedTempVariables = ts.append(computedTempVariables, rhsValue.argumentExpression); } flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } } else if (i === numElements - 1) { if (bindingElements) { flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern); bindingElements = undefined; } var rhsValue = createRestCall(flattenContext.context, value, elements, computedTempVariables, pattern); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, element); } } if (bindingElements) { flattenContext.emitBindingOrAssignment(flattenContext.createObjectBindingOrAssignmentPattern(bindingElements), value, location, pattern); } } /** * Flattens an ArrayBindingOrAssignmentPattern into zero or more bindings or assignments. * * @param flattenContext Options used to control flattening. * @param parent The parent element of the pattern. * @param pattern The ArrayBindingOrAssignmentPattern to flatten. * @param value The current RHS value to assign to the element. * @param location The location to use for source maps and comments. */ function flattenArrayBindingOrAssignmentPattern(flattenContext, parent, pattern, value, location) { var elements = ts.getElementsOfBindingOrAssignmentPattern(pattern); var numElements = elements.length; if (flattenContext.level < 1 /* ObjectRest */ && flattenContext.downlevelIteration) { // Read the elements of the iterable into an array value = ensureIdentifier(flattenContext, ts.createReadHelper(flattenContext.context, value, numElements > 0 && ts.getRestIndicatorOfBindingOrAssignmentElement(elements[numElements - 1]) ? undefined : numElements, location), /*reuseIdentifierExpressions*/ false, location); } else if (numElements !== 1 && (flattenContext.level < 1 /* ObjectRest */ || numElements === 0) || ts.every(elements, ts.isOmittedExpression)) { // For anything other than a single-element destructuring we need to generate a temporary // to ensure value is evaluated exactly once. Additionally, if we have zero elements // we need to emit *something* to ensure that in case a 'var' keyword was already emitted, // so in that case, we'll intentionally create that temporary. // Or all the elements of the binding pattern are omitted expression such as "var [,] = [1,2]", // then we will create temporary variable. var reuseIdentifierExpressions = !ts.isDeclarationBindingElement(parent) || numElements !== 0; value = ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location); } var bindingElements; var restContainingElements; for (var i = 0; i < numElements; i++) { var element = elements[i]; if (flattenContext.level >= 1 /* ObjectRest */) { // If an array pattern contains an ObjectRest, we must cache the result so that we // can perform the ObjectRest destructuring in a different declaration if (element.transformFlags & 1048576 /* ContainsObjectRest */) { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); } restContainingElements = ts.append(restContainingElements, [temp, element]); bindingElements = ts.append(bindingElements, flattenContext.createArrayBindingOrAssignmentElement(temp)); } else { bindingElements = ts.append(bindingElements, element); } } else if (ts.isOmittedExpression(element)) { continue; } else if (!ts.getRestIndicatorOfBindingOrAssignmentElement(element)) { var rhsValue = ts.createElementAccess(value, i); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } else if (i === numElements - 1) { var rhsValue = ts.createArraySlice(value, i); flattenBindingOrAssignmentElement(flattenContext, element, rhsValue, /*location*/ element); } } if (bindingElements) { flattenContext.emitBindingOrAssignment(flattenContext.createArrayBindingOrAssignmentPattern(bindingElements), value, location, pattern); } if (restContainingElements) { for (var _i = 0, restContainingElements_1 = restContainingElements; _i < restContainingElements_1.length; _i++) { var _a = restContainingElements_1[_i], id = _a[0], element = _a[1]; flattenBindingOrAssignmentElement(flattenContext, element, id, element); } } } /** * Creates an expression used to provide a default value if a value is `undefined` at runtime. * * @param flattenContext Options used to control flattening. * @param value The RHS value to test. * @param defaultValue The default value to use if `value` is `undefined` at runtime. * @param location The location to use for source maps and comments. */ function createDefaultValueCheck(flattenContext, value, defaultValue, location) { value = ensureIdentifier(flattenContext, value, /*reuseIdentifierExpressions*/ true, location); return ts.createConditional(ts.createTypeCheck(value, "undefined"), defaultValue, value); } /** * Creates either a PropertyAccessExpression or an ElementAccessExpression for the * right-hand side of a transformed destructuring assignment. * * @link https://tc39.github.io/ecma262/#sec-runtime-semantics-keyeddestructuringassignmentevaluation * * @param flattenContext Options used to control flattening. * @param value The RHS value that is the source of the property. * @param propertyName The destructuring property name. */ function createDestructuringPropertyAccess(flattenContext, value, propertyName) { if (ts.isComputedPropertyName(propertyName)) { var argumentExpression = ensureIdentifier(flattenContext, ts.visitNode(propertyName.expression, flattenContext.visitor), /*reuseIdentifierExpressions*/ false, /*location*/ propertyName); return ts.createElementAccess(value, argumentExpression); } else if (ts.isStringOrNumericLiteral(propertyName)) { var argumentExpression = ts.getSynthesizedClone(propertyName); argumentExpression.text = argumentExpression.text; return ts.createElementAccess(value, argumentExpression); } else { var name = ts.createIdentifier(ts.idText(propertyName)); return ts.createPropertyAccess(value, name); } } /** * Ensures that there exists a declared identifier whose value holds the given expression. * This function is useful to ensure that the expression's value can be read from in subsequent expressions. * Unless 'reuseIdentifierExpressions' is false, 'value' will be returned if it is just an identifier. * * @param flattenContext Options used to control flattening. * @param value the expression whose value needs to be bound. * @param reuseIdentifierExpressions true if identifier expressions can simply be returned; * false if it is necessary to always emit an identifier. * @param location The location to use for source maps and comments. */ function ensureIdentifier(flattenContext, value, reuseIdentifierExpressions, location) { if (ts.isIdentifier(value) && reuseIdentifierExpressions) { return value; } else { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); if (flattenContext.hoistTempVariables) { flattenContext.context.hoistVariableDeclaration(temp); flattenContext.emitExpression(ts.setTextRange(ts.createAssignment(temp, value), location)); } else { flattenContext.emitBindingOrAssignment(temp, value, location, /*original*/ undefined); } return temp; } } function makeArrayBindingPattern(elements) { ts.Debug.assertEachNode(elements, ts.isArrayBindingElement); return ts.createArrayBindingPattern(elements); } function makeArrayAssignmentPattern(elements) { return ts.createArrayLiteral(ts.map(elements, ts.convertToArrayAssignmentElement)); } function makeObjectBindingPattern(elements) { ts.Debug.assertEachNode(elements, ts.isBindingElement); return ts.createObjectBindingPattern(elements); } function makeObjectAssignmentPattern(elements) { return ts.createObjectLiteral(ts.map(elements, ts.convertToObjectAssignmentElement)); } function makeBindingElement(name) { return ts.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, name); } function makeAssignmentElement(name) { return name; } var restHelper = { name: "typescript:rest", scoped: false, text: "\n var __rest = (this && this.__rest) || function (s, e) {\n var t = {};\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\n t[p] = s[p];\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)\n t[p[i]] = s[p[i]];\n return t;\n };" }; /** Given value: o, propName: p, pattern: { a, b, ...p } from the original statement * `{ a, b, ...p } = o`, create `p = __rest(o, ["a", "b"]);` */ function createRestCall(context, value, elements, computedTempVariables, location) { context.requestEmitHelper(restHelper); var propertyNames = []; var computedTempVariableOffset = 0; for (var i = 0; i < elements.length - 1; i++) { var propertyName = ts.getPropertyNameOfBindingOrAssignmentElement(elements[i]); if (propertyName) { if (ts.isComputedPropertyName(propertyName)) { var temp = computedTempVariables[computedTempVariableOffset]; computedTempVariableOffset++; // typeof _tmp === "symbol" ? _tmp : _tmp + "" propertyNames.push(ts.createConditional(ts.createTypeCheck(temp, "symbol"), temp, ts.createAdd(temp, ts.createLiteral("")))); } else { propertyNames.push(ts.createLiteral(propertyName)); } } } return ts.createCall(ts.getHelperName("__rest"), /*typeArguments*/ undefined, [ value, ts.setTextRange(ts.createArrayLiteral(propertyNames), location) ]); } })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { /** * Indicates whether to emit type metadata in the new format. */ var USE_NEW_TYPE_METADATA_FORMAT = false; var TypeScriptSubstitutionFlags; (function (TypeScriptSubstitutionFlags) { /** Enables substitutions for decorated classes. */ TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["ClassAliases"] = 1] = "ClassAliases"; /** Enables substitutions for namespace exports. */ TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NamespaceExports"] = 2] = "NamespaceExports"; /* Enables substitutions for unqualified enum members */ TypeScriptSubstitutionFlags[TypeScriptSubstitutionFlags["NonQualifiedEnumMembers"] = 8] = "NonQualifiedEnumMembers"; })(TypeScriptSubstitutionFlags || (TypeScriptSubstitutionFlags = {})); var ClassFacts; (function (ClassFacts) { ClassFacts[ClassFacts["None"] = 0] = "None"; ClassFacts[ClassFacts["HasStaticInitializedProperties"] = 1] = "HasStaticInitializedProperties"; ClassFacts[ClassFacts["HasConstructorDecorators"] = 2] = "HasConstructorDecorators"; ClassFacts[ClassFacts["HasMemberDecorators"] = 4] = "HasMemberDecorators"; ClassFacts[ClassFacts["IsExportOfNamespace"] = 8] = "IsExportOfNamespace"; ClassFacts[ClassFacts["IsNamedExternalExport"] = 16] = "IsNamedExternalExport"; ClassFacts[ClassFacts["IsDefaultExternalExport"] = 32] = "IsDefaultExternalExport"; ClassFacts[ClassFacts["IsDerivedClass"] = 64] = "IsDerivedClass"; ClassFacts[ClassFacts["UseImmediatelyInvokedFunctionExpression"] = 128] = "UseImmediatelyInvokedFunctionExpression"; ClassFacts[ClassFacts["HasAnyDecorators"] = 6] = "HasAnyDecorators"; ClassFacts[ClassFacts["NeedsName"] = 5] = "NeedsName"; ClassFacts[ClassFacts["MayNeedImmediatelyInvokedFunctionExpression"] = 7] = "MayNeedImmediatelyInvokedFunctionExpression"; ClassFacts[ClassFacts["IsExported"] = 56] = "IsExported"; })(ClassFacts || (ClassFacts = {})); function transformTypeScript(context) { var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration; var resolver = context.getEmitResolver(); var compilerOptions = context.getCompilerOptions(); var strictNullChecks = ts.getStrictOptionValue(compilerOptions, "strictNullChecks"); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); // Save the previous transformation hooks. var previousOnEmitNode = context.onEmitNode; var previousOnSubstituteNode = context.onSubstituteNode; // Set new transformation hooks. context.onEmitNode = onEmitNode; context.onSubstituteNode = onSubstituteNode; // Enable substitution for property/element access to emit const enum values. context.enableSubstitution(180 /* PropertyAccessExpression */); context.enableSubstitution(181 /* ElementAccessExpression */); // These variables contain state that changes as we descend into the tree. var currentSourceFile; var currentNamespace; var currentNamespaceContainerName; var currentScope; var currentScopeFirstDeclarationsOfName; /** * Keeps track of whether expression substitution has been enabled for specific edge cases. * They are persisted between each SourceFile transformation and should not be reset. */ var enabledSubstitutions; /** * A map that keeps track of aliases created for classes with decorators to avoid issues * with the double-binding behavior of classes. */ var classAliases; /** * Keeps track of whether we are within any containing namespaces when performing * just-in-time substitution while printing an expression identifier. */ var applicableSubstitutions; /** * Tracks what computed name expressions originating from elided names must be inlined * at the next execution site, in document order */ var pendingExpressions; return transformSourceFile; /** * Transform TypeScript-specific syntax in a SourceFile. * * @param node A SourceFile node. */ function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } currentSourceFile = node; var visited = saveStateAndInvoke(node, visitSourceFile); ts.addEmitHelpers(visited, context.readEmitHelpers()); currentSourceFile = undefined; return visited; } /** * Visits a node, saving and restoring state variables on the stack. * * @param node The node to visit. */ function saveStateAndInvoke(node, f) { // Save state var savedCurrentScope = currentScope; var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName; // Handle state changes before visiting a node. onBeforeVisitNode(node); var visited = f(node); // Restore state if (currentScope !== savedCurrentScope) { currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; } currentScope = savedCurrentScope; return visited; } /** * Performs actions that should always occur immediately before visiting a node. * * @param node The node to visit. */ function onBeforeVisitNode(node) { switch (node.kind) { case 269 /* SourceFile */: case 236 /* CaseBlock */: case 235 /* ModuleBlock */: case 208 /* Block */: currentScope = node; currentScopeFirstDeclarationsOfName = undefined; break; case 230 /* ClassDeclaration */: case 229 /* FunctionDeclaration */: if (ts.hasModifier(node, 2 /* Ambient */)) { break; } // Record these declarations provided that they have a name. if (node.name) { recordEmittedDeclarationInScope(node); } else { // These nodes should always have names unless they are default-exports; // however, class declaration parsing allows for undefined names, so syntactically invalid // programs may also have an undefined name. ts.Debug.assert(node.kind === 230 /* ClassDeclaration */ || ts.hasModifier(node, 512 /* Default */)); } break; } } /** * General-purpose node visitor. * * @param node The node to visit. */ function visitor(node) { return saveStateAndInvoke(node, visitorWorker); } /** * Visits and possibly transforms any node. * * @param node The node to visit. */ function visitorWorker(node) { if (node.transformFlags & 1 /* TypeScript */) { // This node is explicitly marked as TypeScript, so we should transform the node. return visitTypeScript(node); } else if (node.transformFlags & 2 /* ContainsTypeScript */) { // This node contains TypeScript, so we should visit its children. return ts.visitEachChild(node, visitor, context); } return node; } /** * Specialized visitor that visits the immediate children of a SourceFile. * * @param node The node to visit. */ function sourceElementVisitor(node) { return saveStateAndInvoke(node, sourceElementVisitorWorker); } /** * Specialized visitor that visits the immediate children of a SourceFile. * * @param node The node to visit. */ function sourceElementVisitorWorker(node) { switch (node.kind) { case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: case 244 /* ExportAssignment */: case 245 /* ExportDeclaration */: return visitEllidableStatement(node); default: return visitorWorker(node); } } function visitEllidableStatement(node) { var parsed = ts.getParseTreeNode(node); if (parsed !== node) { // If the node has been transformed by a `before` transformer, perform no ellision on it // As the type information we would attempt to lookup to perform ellision is potentially unavailable for the synthesized nodes // We do not reuse `visitorWorker`, as the ellidable statement syntax kinds are technically unrecognized by the switch-case in `visitTypeScript`, // and will trigger debug failures when debug verbosity is turned up if (node.transformFlags & 2 /* ContainsTypeScript */) { // This node contains TypeScript, so we should visit its children. return ts.visitEachChild(node, visitor, context); } // Otherwise, we can just return the node return node; } switch (node.kind) { case 239 /* ImportDeclaration */: return visitImportDeclaration(node); case 238 /* ImportEqualsDeclaration */: return visitImportEqualsDeclaration(node); case 244 /* ExportAssignment */: return visitExportAssignment(node); case 245 /* ExportDeclaration */: return visitExportDeclaration(node); default: ts.Debug.fail("Unhandled ellided statement"); } } /** * Specialized visitor that visits the immediate children of a namespace. * * @param node The node to visit. */ function namespaceElementVisitor(node) { return saveStateAndInvoke(node, namespaceElementVisitorWorker); } /** * Specialized visitor that visits the immediate children of a namespace. * * @param node The node to visit. */ function namespaceElementVisitorWorker(node) { if (node.kind === 245 /* ExportDeclaration */ || node.kind === 239 /* ImportDeclaration */ || node.kind === 240 /* ImportClause */ || (node.kind === 238 /* ImportEqualsDeclaration */ && node.moduleReference.kind === 249 /* ExternalModuleReference */)) { // do not emit ES6 imports and exports since they are illegal inside a namespace return undefined; } else if (node.transformFlags & 1 /* TypeScript */ || ts.hasModifier(node, 1 /* Export */)) { // This node is explicitly marked as TypeScript, or is exported at the namespace // level, so we should transform the node. return visitTypeScript(node); } else if (node.transformFlags & 2 /* ContainsTypeScript */) { // This node contains TypeScript, so we should visit its children. return ts.visitEachChild(node, visitor, context); } return node; } /** * Specialized visitor that visits the immediate children of a class with TypeScript syntax. * * @param node The node to visit. */ function classElementVisitor(node) { return saveStateAndInvoke(node, classElementVisitorWorker); } /** * Specialized visitor that visits the immediate children of a class with TypeScript syntax. * * @param node The node to visit. */ function classElementVisitorWorker(node) { switch (node.kind) { case 153 /* Constructor */: // TypeScript constructors are transformed in `visitClassDeclaration`. // We elide them here as `visitorWorker` checks transform flags, which could // erronously include an ES6 constructor without TypeScript syntax. return undefined; case 150 /* PropertyDeclaration */: case 158 /* IndexSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 152 /* MethodDeclaration */: // Fallback to the default visit behavior. return visitorWorker(node); case 207 /* SemicolonClassElement */: return node; default: ts.Debug.failBadSyntaxKind(node); return undefined; } } function modifierVisitor(node) { if (ts.modifierToFlag(node.kind) & 2270 /* TypeScriptModifier */) { return undefined; } else if (currentNamespace && node.kind === 84 /* ExportKeyword */) { return undefined; } return node; } /** * Branching visitor, visits a TypeScript syntax node. * * @param node The node to visit. */ function visitTypeScript(node) { if (ts.hasModifier(node, 2 /* Ambient */) && ts.isStatement(node)) { // TypeScript ambient declarations are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. return ts.createNotEmittedStatement(node); } switch (node.kind) { case 84 /* ExportKeyword */: case 79 /* DefaultKeyword */: // ES6 export and default modifiers are elided when inside a namespace. return currentNamespace ? undefined : node; case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 117 /* AbstractKeyword */: case 76 /* ConstKeyword */: case 124 /* DeclareKeyword */: case 131 /* ReadonlyKeyword */: // TypeScript accessibility and readonly modifiers are elided. case 165 /* ArrayType */: case 166 /* TupleType */: case 164 /* TypeLiteral */: case 159 /* TypePredicate */: case 146 /* TypeParameter */: case 119 /* AnyKeyword */: case 122 /* BooleanKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 130 /* NeverKeyword */: case 105 /* VoidKeyword */: case 137 /* SymbolKeyword */: case 162 /* ConstructorType */: case 161 /* FunctionType */: case 163 /* TypeQuery */: case 160 /* TypeReference */: case 167 /* UnionType */: case 168 /* IntersectionType */: case 169 /* ParenthesizedType */: case 170 /* ThisType */: case 171 /* TypeOperator */: case 172 /* IndexedAccessType */: case 173 /* MappedType */: case 174 /* LiteralType */: // TypeScript type nodes are elided. case 158 /* IndexSignature */: // TypeScript index signatures are elided. case 148 /* Decorator */: // TypeScript decorators are elided. They will be emitted as part of visitClassDeclaration. case 232 /* TypeAliasDeclaration */: // TypeScript type-only declarations are elided. return undefined; case 150 /* PropertyDeclaration */: // TypeScript property declarations are elided. However their names are still visited, and can potentially be retained if they could have sideeffects return visitPropertyDeclaration(node); case 237 /* NamespaceExportDeclaration */: // TypeScript namespace export declarations are elided. return undefined; case 153 /* Constructor */: return visitConstructor(node); case 231 /* InterfaceDeclaration */: // TypeScript interfaces are elided, but some comments may be preserved. // See the implementation of `getLeadingComments` in comments.ts for more details. return ts.createNotEmittedStatement(node); case 230 /* ClassDeclaration */: // This is a class declaration with TypeScript syntax extensions. // // TypeScript class syntax extensions include: // - decorators // - optional `implements` heritage clause // - parameter property assignments in the constructor // - property declarations // - index signatures // - method overload signatures return visitClassDeclaration(node); case 200 /* ClassExpression */: // This is a class expression with TypeScript syntax extensions. // // TypeScript class syntax extensions include: // - decorators // - optional `implements` heritage clause // - parameter property assignments in the constructor // - property declarations // - index signatures // - method overload signatures return visitClassExpression(node); case 263 /* HeritageClause */: // This is a heritage clause with TypeScript syntax extensions. // // TypeScript heritage clause extensions include: // - `implements` clause return visitHeritageClause(node); case 202 /* ExpressionWithTypeArguments */: // TypeScript supports type arguments on an expression in an `extends` heritage clause. return visitExpressionWithTypeArguments(node); case 152 /* MethodDeclaration */: // TypeScript method declarations may have decorators, modifiers // or type annotations. return visitMethodDeclaration(node); case 154 /* GetAccessor */: // Get Accessors can have TypeScript modifiers, decorators, and type annotations. return visitGetAccessor(node); case 155 /* SetAccessor */: // Set Accessors can have TypeScript modifiers and type annotations. return visitSetAccessor(node); case 229 /* FunctionDeclaration */: // Typescript function declarations can have modifiers, decorators, and type annotations. return visitFunctionDeclaration(node); case 187 /* FunctionExpression */: // TypeScript function expressions can have modifiers and type annotations. return visitFunctionExpression(node); case 188 /* ArrowFunction */: // TypeScript arrow functions can have modifiers and type annotations. return visitArrowFunction(node); case 147 /* Parameter */: // This is a parameter declaration with TypeScript syntax extensions. // // TypeScript parameter declaration syntax extensions include: // - decorators // - accessibility modifiers // - the question mark (?) token for optional parameters // - type annotations // - this parameters return visitParameter(node); case 186 /* ParenthesizedExpression */: // ParenthesizedExpressions are TypeScript if their expression is a // TypeAssertion or AsExpression return visitParenthesizedExpression(node); case 185 /* TypeAssertionExpression */: case 203 /* AsExpression */: // TypeScript type assertions are removed, but their subtrees are preserved. return visitAssertionExpression(node); case 182 /* CallExpression */: return visitCallExpression(node); case 183 /* NewExpression */: return visitNewExpression(node); case 204 /* NonNullExpression */: // TypeScript non-null expressions are removed, but their subtrees are preserved. return visitNonNullExpression(node); case 233 /* EnumDeclaration */: // TypeScript enum declarations do not exist in ES6 and must be rewritten. return visitEnumDeclaration(node); case 209 /* VariableStatement */: // TypeScript namespace exports for variable statements must be transformed. return visitVariableStatement(node); case 227 /* VariableDeclaration */: return visitVariableDeclaration(node); case 234 /* ModuleDeclaration */: // TypeScript namespace declarations must be transformed. return visitModuleDeclaration(node); case 238 /* ImportEqualsDeclaration */: // TypeScript namespace or external module import. return visitImportEqualsDeclaration(node); default: ts.Debug.failBadSyntaxKind(node); return ts.visitEachChild(node, visitor, context); } } function visitSourceFile(node) { var alwaysStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") && !(ts.isExternalModule(node) && moduleKind >= ts.ModuleKind.ES2015); return ts.updateSourceFileNode(node, ts.visitLexicalEnvironment(node.statements, sourceElementVisitor, context, /*start*/ 0, alwaysStrict)); } /** * Tests whether we should emit a __decorate call for a class declaration. */ function shouldEmitDecorateCallForClass(node) { if (node.decorators && node.decorators.length > 0) { return true; } var constructor = ts.getFirstConstructorWithBody(node); if (constructor) { return ts.forEach(constructor.parameters, shouldEmitDecorateCallForParameter); } return false; } /** * Tests whether we should emit a __decorate call for a parameter declaration. */ function shouldEmitDecorateCallForParameter(parameter) { return parameter.decorators !== undefined && parameter.decorators.length > 0; } function getClassFacts(node, staticProperties) { var facts = 0 /* None */; if (ts.some(staticProperties)) facts |= 1 /* HasStaticInitializedProperties */; var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node); if (extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */) facts |= 64 /* IsDerivedClass */; if (shouldEmitDecorateCallForClass(node)) facts |= 2 /* HasConstructorDecorators */; if (ts.childIsDecorated(node)) facts |= 4 /* HasMemberDecorators */; if (isExportOfNamespace(node)) facts |= 8 /* IsExportOfNamespace */; else if (isDefaultExternalModuleExport(node)) facts |= 32 /* IsDefaultExternalExport */; else if (isNamedExternalModuleExport(node)) facts |= 16 /* IsNamedExternalExport */; if (languageVersion <= 1 /* ES5 */ && (facts & 7 /* MayNeedImmediatelyInvokedFunctionExpression */)) facts |= 128 /* UseImmediatelyInvokedFunctionExpression */; return facts; } /** * Transforms a class declaration with TypeScript syntax into compatible ES6. * * This function will only be called when one of the following conditions are met: * - The class has decorators. * - The class has property declarations with initializers. * - The class contains a constructor that contains parameters with accessibility modifiers. * - The class is an export in a TypeScript namespace. * * @param node The node to transform. */ function visitClassDeclaration(node) { var savedPendingExpressions = pendingExpressions; pendingExpressions = undefined; var staticProperties = getInitializedProperties(node, /*isStatic*/ true); var facts = getClassFacts(node, staticProperties); if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) { context.startLexicalEnvironment(); } var name = node.name || (facts & 5 /* NeedsName */ ? ts.getGeneratedNameForNode(node) : undefined); var classStatement = facts & 2 /* HasConstructorDecorators */ ? createClassDeclarationHeadWithDecorators(node, name, facts) : createClassDeclarationHeadWithoutDecorators(node, name, facts); var statements = [classStatement]; // Write any pending expressions from elided or moved computed property names if (ts.some(pendingExpressions)) { statements.push(ts.createStatement(ts.inlineExpressions(pendingExpressions))); } pendingExpressions = savedPendingExpressions; // Emit static property assignment. Because classDeclaration is lexically evaluated, // it is safe to emit static property assignment after classDeclaration // From ES6 specification: // HasLexicalDeclaration (N) : Determines if the argument identifier has a binding in this environment record that was created using // a lexical declaration such as a LexicalDeclaration or a ClassDeclaration. if (facts & 1 /* HasStaticInitializedProperties */) { addInitializedPropertyStatements(statements, staticProperties, facts & 128 /* UseImmediatelyInvokedFunctionExpression */ ? ts.getInternalName(node) : ts.getLocalName(node)); } // Write any decorators of the node. addClassElementDecorationStatements(statements, node, /*isStatic*/ false); addClassElementDecorationStatements(statements, node, /*isStatic*/ true); addConstructorDecorationStatement(statements, node); if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */) { // When we emit a TypeScript class down to ES5, we must wrap it in an IIFE so that the // 'es2015' transformer can properly nest static initializers and decorators. The result // looks something like: // // var C = function () { // class C { // } // C.static_prop = 1; // return C; // }(); // var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentSourceFile.text, node.members.end), 18 /* CloseBraceToken */); var localName = ts.getInternalName(node); // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. var outer = ts.createPartiallyEmittedExpression(localName); outer.end = closingBraceLocation.end; ts.setEmitFlags(outer, 1536 /* NoComments */); var statement = ts.createReturn(outer); statement.pos = closingBraceLocation.pos; ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */); statements.push(statement); ts.addRange(statements, context.endLexicalEnvironment()); var iife = ts.createImmediatelyInvokedArrowFunction(statements); ts.setEmitFlags(iife, 33554432 /* TypeScriptClassWrapper */); var varStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ false), /*type*/ undefined, iife) ])); ts.setOriginalNode(varStatement, node); ts.setCommentRange(varStatement, node); ts.setSourceMapRange(varStatement, ts.moveRangePastDecorators(node)); ts.startOnNewLine(varStatement); statements = [varStatement]; } // If the class is exported as part of a TypeScript namespace, emit the namespace export. // Otherwise, if the class was exported at the top level and was decorated, emit an export // declaration or export default for the class. if (facts & 8 /* IsExportOfNamespace */) { addExportMemberAssignment(statements, node); } else if (facts & 128 /* UseImmediatelyInvokedFunctionExpression */ || facts & 2 /* HasConstructorDecorators */) { if (facts & 32 /* IsDefaultExternalExport */) { statements.push(ts.createExportDefault(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); } else if (facts & 16 /* IsNamedExternalExport */) { statements.push(ts.createExternalModuleExport(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true))); } } if (statements.length > 1) { // Add a DeclarationMarker as a marker for the end of the declaration statements.push(ts.createEndOfDeclarationMarker(node)); ts.setEmitFlags(classStatement, ts.getEmitFlags(classStatement) | 4194304 /* HasEndOfDeclarationMarker */); } return ts.singleOrMany(statements); } /** * Transforms a non-decorated class declaration and appends the resulting statements. * * @param node A ClassDeclaration node. * @param name The name of the class. * @param facts Precomputed facts about the class. */ function createClassDeclarationHeadWithoutDecorators(node, name, facts) { // ${modifiers} class ${name} ${heritageClauses} { // ${members} // } // we do not emit modifiers on the declaration if we are emitting an IIFE var modifiers = !(facts & 128 /* UseImmediatelyInvokedFunctionExpression */) ? ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier) : undefined; var classDeclaration = ts.createClassDeclaration( /*decorators*/ undefined, modifiers, name, /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause), transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0)); // To better align with the old emitter, we should not emit a trailing source map // entry if the class has static properties. var emitFlags = ts.getEmitFlags(node); if (facts & 1 /* HasStaticInitializedProperties */) { emitFlags |= 32 /* NoTrailingSourceMap */; } ts.setTextRange(classDeclaration, node); ts.setOriginalNode(classDeclaration, node); ts.setEmitFlags(classDeclaration, emitFlags); return classDeclaration; } /** * Transforms a decorated class declaration and appends the resulting statements. If * the class requires an alias to avoid issues with double-binding, the alias is returned. */ function createClassDeclarationHeadWithDecorators(node, name, facts) { // When we emit an ES6 class that has a class decorator, we must tailor the // emit to certain specific cases. // // In the simplest case, we emit the class declaration as a let declaration, and // evaluate decorators after the close of the class body: // // [Example 1] // --------------------------------------------------------------------- // TypeScript | Javascript // --------------------------------------------------------------------- // @dec | let C = class C { // class C { | } // } | C = __decorate([dec], C); // --------------------------------------------------------------------- // @dec | let C = class C { // export class C { | } // } | C = __decorate([dec], C); // | export { C }; // --------------------------------------------------------------------- // // If a class declaration contains a reference to itself *inside* of the class body, // this introduces two bindings to the class: One outside of the class body, and one // inside of the class body. If we apply decorators as in [Example 1] above, there // is the possibility that the decorator `dec` will return a new value for the // constructor, which would result in the binding inside of the class no longer // pointing to the same reference as the binding outside of the class. // // As a result, we must instead rewrite all references to the class *inside* of the // class body to instead point to a local temporary alias for the class: // // [Example 2] // --------------------------------------------------------------------- // TypeScript | Javascript // --------------------------------------------------------------------- // @dec | let C = C_1 = class C { // class C { | static x() { return C_1.y; } // static x() { return C.y; } | } // static y = 1; | C.y = 1; // } | C = C_1 = __decorate([dec], C); // | var C_1; // --------------------------------------------------------------------- // @dec | let C = class C { // export class C { | static x() { return C_1.y; } // static x() { return C.y; } | } // static y = 1; | C.y = 1; // } | C = C_1 = __decorate([dec], C); // | export { C }; // | var C_1; // --------------------------------------------------------------------- // // If a class declaration is the default export of a module, we instead emit // the export after the decorated declaration: // // [Example 3] // --------------------------------------------------------------------- // TypeScript | Javascript // --------------------------------------------------------------------- // @dec | let default_1 = class { // export default class { | } // } | default_1 = __decorate([dec], default_1); // | export default default_1; // --------------------------------------------------------------------- // @dec | let C = class C { // export default class C { | } // } | C = __decorate([dec], C); // | export default C; // --------------------------------------------------------------------- // // If the class declaration is the default export and a reference to itself // inside of the class body, we must emit both an alias for the class *and* // move the export after the declaration: // // [Example 4] // --------------------------------------------------------------------- // TypeScript | Javascript // --------------------------------------------------------------------- // @dec | let C = class C { // export default class C { | static x() { return C_1.y; } // static x() { return C.y; } | } // static y = 1; | C.y = 1; // } | C = C_1 = __decorate([dec], C); // | export default C; // | var C_1; // --------------------------------------------------------------------- // var location = ts.moveRangePastDecorators(node); var classAlias = getClassAliasIfNeeded(node); var declName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // ... = class ${name} ${heritageClauses} { // ${members} // } var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause); var members = transformClassMembers(node, (facts & 64 /* IsDerivedClass */) !== 0); var classExpression = ts.createClassExpression(/*modifiers*/ undefined, name, /*typeParameters*/ undefined, heritageClauses, members); ts.setOriginalNode(classExpression, node); ts.setTextRange(classExpression, location); // let ${name} = ${classExpression} where name is either declaredName if the class doesn't contain self-reference // or decoratedClassAlias if the class contain self-reference. var statement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(declName, /*type*/ undefined, classAlias ? ts.createAssignment(classAlias, classExpression) : classExpression) ], 1 /* Let */)); ts.setOriginalNode(statement, node); ts.setTextRange(statement, location); ts.setCommentRange(statement, node); return statement; } /** * Transforms a class expression with TypeScript syntax into compatible ES6. * * This function will only be called when one of the following conditions are met: * - The class has property declarations with initializers. * - The class contains a constructor that contains parameters with accessibility modifiers. * * @param node The node to transform. */ function visitClassExpression(node) { var savedPendingExpressions = pendingExpressions; pendingExpressions = undefined; var staticProperties = getInitializedProperties(node, /*isStatic*/ true); var heritageClauses = ts.visitNodes(node.heritageClauses, visitor, ts.isHeritageClause); var members = transformClassMembers(node, ts.some(heritageClauses, function (c) { return c.token === 85 /* ExtendsKeyword */; })); var classExpression = ts.createClassExpression( /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, heritageClauses, members); ts.setOriginalNode(classExpression, node); ts.setTextRange(classExpression, node); if (ts.some(staticProperties) || ts.some(pendingExpressions)) { var expressions = []; var temp = ts.createTempVariable(hoistVariableDeclaration); if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) { // record an alias as the class name is not in scope for statics. enableSubstitutionForClassAliases(); classAliases[ts.getOriginalNodeId(node)] = ts.getSynthesizedClone(temp); } // To preserve the behavior of the old emitter, we explicitly indent // the body of a class with static initializers. ts.setEmitFlags(classExpression, 65536 /* Indented */ | ts.getEmitFlags(classExpression)); expressions.push(ts.startOnNewLine(ts.createAssignment(temp, classExpression))); // Add any pending expressions leftover from elided or relocated computed property names ts.addRange(expressions, ts.map(pendingExpressions, ts.startOnNewLine)); pendingExpressions = savedPendingExpressions; ts.addRange(expressions, generateInitializedPropertyExpressions(staticProperties, temp)); expressions.push(ts.startOnNewLine(temp)); return ts.inlineExpressions(expressions); } pendingExpressions = savedPendingExpressions; return classExpression; } /** * Transforms the members of a class. * * @param node The current class. * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ function transformClassMembers(node, isDerivedClass) { var members = []; var constructor = transformConstructor(node, isDerivedClass); if (constructor) { members.push(constructor); } ts.addRange(members, ts.visitNodes(node.members, classElementVisitor, ts.isClassElement)); return ts.setTextRange(ts.createNodeArray(members), /*location*/ node.members); } /** * Transforms (or creates) a constructor for a class. * * @param node The current class. * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ function transformConstructor(node, isDerivedClass) { // Check if we have property assignment inside class declaration. // If there is a property assignment, we need to emit constructor whether users define it or not // If there is no property assignment, we can omit constructor if users do not define it var hasInstancePropertyWithInitializer = ts.forEach(node.members, isInstanceInitializedProperty); var hasParameterPropertyAssignments = node.transformFlags & 262144 /* ContainsParameterPropertyAssignments */; var constructor = ts.getFirstConstructorWithBody(node); // If the class does not contain nodes that require a synthesized constructor, // accept the current constructor if it exists. if (!hasInstancePropertyWithInitializer && !hasParameterPropertyAssignments) { return ts.visitEachChild(constructor, visitor, context); } var parameters = transformConstructorParameters(constructor); var body = transformConstructorBody(node, constructor, isDerivedClass); // constructor(${parameters}) { // ${body} // } return ts.startOnNewLine(ts.setOriginalNode(ts.setTextRange(ts.createConstructor( /*decorators*/ undefined, /*modifiers*/ undefined, parameters, body), constructor || node), constructor)); } /** * Transforms (or creates) the parameters for the constructor of a class with * parameter property assignments or instance property initializers. * * @param constructor The constructor declaration. */ function transformConstructorParameters(constructor) { // The ES2015 spec specifies in 14.5.14. Runtime Semantics: ClassDefinitionEvaluation: // If constructor is empty, then // If ClassHeritag_eopt is present and protoParent is not null, then // Let constructor be the result of parsing the source text // constructor(...args) { super (...args);} // using the syntactic grammar with the goal symbol MethodDefinition[~Yield]. // Else, // Let constructor be the result of parsing the source text // constructor( ){ } // using the syntactic grammar with the goal symbol MethodDefinition[~Yield]. // // While we could emit the '...args' rest parameter, certain later tools in the pipeline might // downlevel the '...args' portion less efficiently by naively copying the contents of 'arguments' to an array. // Instead, we'll avoid using a rest parameter and spread into the super call as // 'super(...arguments)' instead of 'super(...args)', as you can see in "transformConstructorBody". return ts.visitParameterList(constructor && constructor.parameters, visitor, context) || []; } /** * Transforms (or creates) a constructor body for a class with parameter property * assignments or instance property initializers. * * @param node The current class. * @param constructor The current class constructor. * @param isDerivedClass A value indicating whether the class has an extends clause that does not extend 'null'. */ function transformConstructorBody(node, constructor, isDerivedClass) { var statements = []; var indexOfFirstStatement = 0; resumeLexicalEnvironment(); if (constructor) { indexOfFirstStatement = addPrologueDirectivesAndInitialSuperCall(constructor, statements); // Add parameters with property assignments. Transforms this: // // constructor (public x, public y) { // } // // Into this: // // constructor (x, y) { // this.x = x; // this.y = y; // } // var propertyAssignments = getParametersWithPropertyAssignments(constructor); ts.addRange(statements, ts.map(propertyAssignments, transformParameterWithPropertyAssignment)); } else if (isDerivedClass) { // Add a synthetic `super` call: // // super(...arguments); // statements.push(ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, [ts.createSpread(ts.createIdentifier("arguments"))]))); } // Add the property initializers. Transforms this: // // public x = 1; // // Into this: // // constructor() { // this.x = 1; // } // var properties = getInitializedProperties(node, /*isStatic*/ false); addInitializedPropertyStatements(statements, properties, ts.createThis()); if (constructor) { // The class already had a constructor, so we should add the existing statements, skipping the initial super call. ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, indexOfFirstStatement)); } // End the lexical environment. statements = ts.mergeLexicalEnvironment(statements, endLexicalEnvironment()); return ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ constructor ? constructor.body.statements : node.members), /*multiLine*/ true), /*location*/ constructor ? constructor.body : undefined); } /** * Adds super call and preceding prologue directives into the list of statements. * * @param ctor The constructor node. * @returns index of the statement that follows super call */ function addPrologueDirectivesAndInitialSuperCall(ctor, result) { if (ctor.body) { var statements = ctor.body.statements; // add prologue directives to the list (if any) var index = ts.addPrologue(result, statements, /*ensureUseStrict*/ false, visitor); if (index === statements.length) { // list contains nothing but prologue directives (or empty) - exit return index; } var statement = statements[index]; if (statement.kind === 211 /* ExpressionStatement */ && ts.isSuperCall(statement.expression)) { result.push(ts.visitNode(statement, visitor, ts.isStatement)); return index + 1; } return index; } return 0; } /** * Gets all parameters of a constructor that should be transformed into property assignments. * * @param node The constructor node. */ function getParametersWithPropertyAssignments(node) { return ts.filter(node.parameters, isParameterWithPropertyAssignment); } /** * Determines whether a parameter should be transformed into a property assignment. * * @param parameter The parameter node. */ function isParameterWithPropertyAssignment(parameter) { return ts.hasModifier(parameter, 92 /* ParameterPropertyModifier */) && ts.isIdentifier(parameter.name); } /** * Transforms a parameter into a property assignment statement. * * @param node The parameter declaration. */ function transformParameterWithPropertyAssignment(node) { ts.Debug.assert(ts.isIdentifier(node.name)); var name = node.name; var propertyName = ts.getMutableClone(name); ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 48 /* NoSourceMap */); var localName = ts.getMutableClone(name); ts.setEmitFlags(localName, 1536 /* NoComments */); return ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createThis(), propertyName), node.name), localName)), ts.moveRangePos(node, -1))); } /** * Gets all property declarations with initializers on either the static or instance side of a class. * * @param node The class node. * @param isStatic A value indicating whether to get properties from the static or instance side of the class. */ function getInitializedProperties(node, isStatic) { return ts.filter(node.members, isStatic ? isStaticInitializedProperty : isInstanceInitializedProperty); } /** * Gets a value indicating whether a class element is a static property declaration with an initializer. * * @param member The class element node. */ function isStaticInitializedProperty(member) { return isInitializedProperty(member, /*isStatic*/ true); } /** * Gets a value indicating whether a class element is an instance property declaration with an initializer. * * @param member The class element node. */ function isInstanceInitializedProperty(member) { return isInitializedProperty(member, /*isStatic*/ false); } /** * Gets a value indicating whether a class element is either a static or an instance property declaration with an initializer. * * @param member The class element node. * @param isStatic A value indicating whether the member should be a static or instance member. */ function isInitializedProperty(member, isStatic) { return member.kind === 150 /* PropertyDeclaration */ && isStatic === ts.hasModifier(member, 32 /* Static */) && member.initializer !== undefined; } /** * Generates assignment statements for property initializers. * * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ function addInitializedPropertyStatements(statements, properties, receiver) { for (var _i = 0, properties_10 = properties; _i < properties_10.length; _i++) { var property = properties_10[_i]; var statement = ts.createStatement(transformInitializedProperty(property, receiver)); ts.setSourceMapRange(statement, ts.moveRangePastModifiers(property)); ts.setCommentRange(statement, property); statements.push(statement); } } /** * Generates assignment expressions for property initializers. * * @param properties An array of property declarations to transform. * @param receiver The receiver on which each property should be assigned. */ function generateInitializedPropertyExpressions(properties, receiver) { var expressions = []; for (var _i = 0, properties_11 = properties; _i < properties_11.length; _i++) { var property = properties_11[_i]; var expression = transformInitializedProperty(property, receiver); ts.startOnNewLine(expression); ts.setSourceMapRange(expression, ts.moveRangePastModifiers(property)); ts.setCommentRange(expression, property); expressions.push(expression); } return expressions; } /** * Transforms a property initializer into an assignment statement. * * @param property The property declaration. * @param receiver The object receiving the property assignment. */ function transformInitializedProperty(property, receiver) { // We generate a name here in order to reuse the value cached by the relocated computed name expression (which uses the same generated name) var propertyName = ts.isComputedPropertyName(property.name) && !isSimpleInlineableExpression(property.name.expression) ? ts.updateComputedPropertyName(property.name, ts.getGeneratedNameForNode(property.name, !ts.hasModifier(property, 32 /* Static */))) : property.name; var initializer = ts.visitNode(property.initializer, visitor, ts.isExpression); var memberAccess = ts.createMemberAccessForPropertyName(receiver, propertyName, /*location*/ propertyName); return ts.createAssignment(memberAccess, initializer); } /** * Gets either the static or instance members of a class that are decorated, or have * parameters that are decorated. * * @param node The class containing the member. * @param isStatic A value indicating whether to retrieve static or instance members of * the class. */ function getDecoratedClassElements(node, isStatic) { return ts.filter(node.members, isStatic ? function (m) { return isStaticDecoratedClassElement(m, node); } : function (m) { return isInstanceDecoratedClassElement(m, node); }); } /** * Determines whether a class member is a static member of a class that is decorated, or * has parameters that are decorated. * * @param member The class member. */ function isStaticDecoratedClassElement(member, parent) { return isDecoratedClassElement(member, /*isStatic*/ true, parent); } /** * Determines whether a class member is an instance member of a class that is decorated, * or has parameters that are decorated. * * @param member The class member. */ function isInstanceDecoratedClassElement(member, parent) { return isDecoratedClassElement(member, /*isStatic*/ false, parent); } /** * Determines whether a class member is either a static or an instance member of a class * that is decorated, or has parameters that are decorated. * * @param member The class member. */ function isDecoratedClassElement(member, isStatic, parent) { return ts.nodeOrChildIsDecorated(member, parent) && isStatic === ts.hasModifier(member, 32 /* Static */); } /** * Gets an array of arrays of decorators for the parameters of a function-like node. * The offset into the result array should correspond to the offset of the parameter. * * @param node The function-like node. */ function getDecoratorsOfParameters(node) { var decorators; if (node) { var parameters = node.parameters; for (var i = 0; i < parameters.length; i++) { var parameter = parameters[i]; if (decorators || parameter.decorators) { if (!decorators) { decorators = new Array(parameters.length); } decorators[i] = parameter.decorators; } } } return decorators; } /** * Gets an AllDecorators object containing the decorators for the class and the decorators for the * parameters of the constructor of the class. * * @param node The class node. */ function getAllDecoratorsOfConstructor(node) { var decorators = node.decorators; var parameters = getDecoratorsOfParameters(ts.getFirstConstructorWithBody(node)); if (!decorators && !parameters) { return undefined; } return { decorators: decorators, parameters: parameters }; } /** * Gets an AllDecorators object containing the decorators for the member and its parameters. * * @param node The class node that contains the member. * @param member The class member. */ function getAllDecoratorsOfClassElement(node, member) { switch (member.kind) { case 154 /* GetAccessor */: case 155 /* SetAccessor */: return getAllDecoratorsOfAccessors(node, member); case 152 /* MethodDeclaration */: return getAllDecoratorsOfMethod(member); case 150 /* PropertyDeclaration */: return getAllDecoratorsOfProperty(member); default: return undefined; } } /** * Gets an AllDecorators object containing the decorators for the accessor and its parameters. * * @param node The class node that contains the accessor. * @param accessor The class accessor member. */ function getAllDecoratorsOfAccessors(node, accessor) { if (!accessor.body) { return undefined; } var _a = ts.getAllAccessorDeclarations(node.members, accessor), firstAccessor = _a.firstAccessor, secondAccessor = _a.secondAccessor, setAccessor = _a.setAccessor; var firstAccessorWithDecorators = firstAccessor.decorators ? firstAccessor : secondAccessor && secondAccessor.decorators ? secondAccessor : undefined; if (!firstAccessorWithDecorators || accessor !== firstAccessorWithDecorators) { return undefined; } var decorators = firstAccessorWithDecorators.decorators; var parameters = getDecoratorsOfParameters(setAccessor); if (!decorators && !parameters) { return undefined; } return { decorators: decorators, parameters: parameters }; } /** * Gets an AllDecorators object containing the decorators for the method and its parameters. * * @param method The class method member. */ function getAllDecoratorsOfMethod(method) { if (!method.body) { return undefined; } var decorators = method.decorators; var parameters = getDecoratorsOfParameters(method); if (!decorators && !parameters) { return undefined; } return { decorators: decorators, parameters: parameters }; } /** * Gets an AllDecorators object containing the decorators for the property. * * @param property The class property member. */ function getAllDecoratorsOfProperty(property) { var decorators = property.decorators; if (!decorators) { return undefined; } return { decorators: decorators }; } /** * Transforms all of the decorators for a declaration into an array of expressions. * * @param node The declaration node. * @param allDecorators An object containing all of the decorators for the declaration. */ function transformAllDecoratorsOfDeclaration(node, container, allDecorators) { if (!allDecorators) { return undefined; } var decoratorExpressions = []; ts.addRange(decoratorExpressions, ts.map(allDecorators.decorators, transformDecorator)); ts.addRange(decoratorExpressions, ts.flatMap(allDecorators.parameters, transformDecoratorsOfParameter)); addTypeMetadata(node, container, decoratorExpressions); return decoratorExpressions; } /** * Generates statements used to apply decorators to either the static or instance members * of a class. * * @param node The class node. * @param isStatic A value indicating whether to generate statements for static or * instance members. */ function addClassElementDecorationStatements(statements, node, isStatic) { ts.addRange(statements, ts.map(generateClassElementDecorationExpressions(node, isStatic), expressionToStatement)); } /** * Generates expressions used to apply decorators to either the static or instance members * of a class. * * @param node The class node. * @param isStatic A value indicating whether to generate expressions for static or * instance members. */ function generateClassElementDecorationExpressions(node, isStatic) { var members = getDecoratedClassElements(node, isStatic); var expressions; for (var _i = 0, members_4 = members; _i < members_4.length; _i++) { var member = members_4[_i]; var expression = generateClassElementDecorationExpression(node, member); if (expression) { if (!expressions) { expressions = [expression]; } else { expressions.push(expression); } } } return expressions; } /** * Generates an expression used to evaluate class element decorators at runtime. * * @param node The class node that contains the member. * @param member The class member. */ function generateClassElementDecorationExpression(node, member) { var allDecorators = getAllDecoratorsOfClassElement(node, member); var decoratorExpressions = transformAllDecoratorsOfDeclaration(member, node, allDecorators); if (!decoratorExpressions) { return undefined; } // Emit the call to __decorate. Given the following: // // class C { // @dec method(@dec2 x) {} // @dec get accessor() {} // @dec prop; // } // // The emit for a method is: // // __decorate([ // dec, // __param(0, dec2), // __metadata("design:type", Function), // __metadata("design:paramtypes", [Object]), // __metadata("design:returntype", void 0) // ], C.prototype, "method", null); // // The emit for an accessor is: // // __decorate([ // dec // ], C.prototype, "accessor", null); // // The emit for a property is: // // __decorate([ // dec // ], C.prototype, "prop"); // var prefix = getClassMemberPrefix(node, member); var memberName = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ true); var descriptor = languageVersion > 0 /* ES3 */ ? member.kind === 150 /* PropertyDeclaration */ // We emit `void 0` here to indicate to `__decorate` that it can invoke `Object.defineProperty` directly, but that it // should not invoke `Object.getOwnPropertyDescriptor`. ? ts.createVoidZero() // We emit `null` here to indicate to `__decorate` that it can invoke `Object.getOwnPropertyDescriptor` directly. // We have this extra argument here so that we can inject an explicit property descriptor at a later date. : ts.createNull() : undefined; var helper = createDecorateHelper(context, decoratorExpressions, prefix, memberName, descriptor, ts.moveRangePastDecorators(member)); ts.setEmitFlags(helper, 1536 /* NoComments */); return helper; } /** * Generates a __decorate helper call for a class constructor. * * @param node The class node. */ function addConstructorDecorationStatement(statements, node) { var expression = generateConstructorDecorationExpression(node); if (expression) { statements.push(ts.setOriginalNode(ts.createStatement(expression), node)); } } /** * Generates a __decorate helper call for a class constructor. * * @param node The class node. */ function generateConstructorDecorationExpression(node) { var allDecorators = getAllDecoratorsOfConstructor(node); var decoratorExpressions = transformAllDecoratorsOfDeclaration(node, node, allDecorators); if (!decoratorExpressions) { return undefined; } var classAlias = classAliases && classAliases[ts.getOriginalNodeId(node)]; var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); var decorate = createDecorateHelper(context, decoratorExpressions, localName); var expression = ts.createAssignment(localName, classAlias ? ts.createAssignment(classAlias, decorate) : decorate); ts.setEmitFlags(expression, 1536 /* NoComments */); ts.setSourceMapRange(expression, ts.moveRangePastDecorators(node)); return expression; } /** * Transforms a decorator into an expression. * * @param decorator The decorator node. */ function transformDecorator(decorator) { return ts.visitNode(decorator.expression, visitor, ts.isExpression); } /** * Transforms the decorators of a parameter. * * @param decorators The decorators for the parameter at the provided offset. * @param parameterOffset The offset of the parameter. */ function transformDecoratorsOfParameter(decorators, parameterOffset) { var expressions; if (decorators) { expressions = []; for (var _i = 0, decorators_1 = decorators; _i < decorators_1.length; _i++) { var decorator = decorators_1[_i]; var helper = createParamHelper(context, transformDecorator(decorator), parameterOffset, /*location*/ decorator.expression); ts.setEmitFlags(helper, 1536 /* NoComments */); expressions.push(helper); } } return expressions; } /** * Adds optional type metadata for a declaration. * * @param node The declaration node. * @param decoratorExpressions The destination array to which to add new decorator expressions. */ function addTypeMetadata(node, container, decoratorExpressions) { if (USE_NEW_TYPE_METADATA_FORMAT) { addNewTypeMetadata(node, container, decoratorExpressions); } else { addOldTypeMetadata(node, container, decoratorExpressions); } } function addOldTypeMetadata(node, container, decoratorExpressions) { if (compilerOptions.emitDecoratorMetadata) { if (shouldAddTypeMetadata(node)) { decoratorExpressions.push(createMetadataHelper(context, "design:type", serializeTypeOfNode(node))); } if (shouldAddParamTypesMetadata(node)) { decoratorExpressions.push(createMetadataHelper(context, "design:paramtypes", serializeParameterTypesOfNode(node, container))); } if (shouldAddReturnTypeMetadata(node)) { decoratorExpressions.push(createMetadataHelper(context, "design:returntype", serializeReturnTypeOfNode(node))); } } } function addNewTypeMetadata(node, container, decoratorExpressions) { if (compilerOptions.emitDecoratorMetadata) { var properties = void 0; if (shouldAddTypeMetadata(node)) { (properties || (properties = [])).push(ts.createPropertyAssignment("type", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeTypeOfNode(node)))); } if (shouldAddParamTypesMetadata(node)) { (properties || (properties = [])).push(ts.createPropertyAssignment("paramTypes", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeParameterTypesOfNode(node, container)))); } if (shouldAddReturnTypeMetadata(node)) { (properties || (properties = [])).push(ts.createPropertyAssignment("returnType", ts.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, ts.createToken(36 /* EqualsGreaterThanToken */), serializeReturnTypeOfNode(node)))); } if (properties) { decoratorExpressions.push(createMetadataHelper(context, "design:typeinfo", ts.createObjectLiteral(properties, /*multiLine*/ true))); } } } /** * Determines whether to emit the "design:type" metadata based on the node's kind. * The caller should have already tested whether the node has decorators and whether the * emitDecoratorMetadata compiler option is set. * * @param node The node to test. */ function shouldAddTypeMetadata(node) { var kind = node.kind; return kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */ || kind === 150 /* PropertyDeclaration */; } /** * Determines whether to emit the "design:returntype" metadata based on the node's kind. * The caller should have already tested whether the node has decorators and whether the * emitDecoratorMetadata compiler option is set. * * @param node The node to test. */ function shouldAddReturnTypeMetadata(node) { return node.kind === 152 /* MethodDeclaration */; } /** * Determines whether to emit the "design:paramtypes" metadata based on the node's kind. * The caller should have already tested whether the node has decorators and whether the * emitDecoratorMetadata compiler option is set. * * @param node The node to test. */ function shouldAddParamTypesMetadata(node) { switch (node.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return ts.getFirstConstructorWithBody(node) !== undefined; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return true; } return false; } /** * Serializes the type of a node for use with decorator type metadata. * * @param node The node that should have its type serialized. */ function serializeTypeOfNode(node) { switch (node.kind) { case 150 /* PropertyDeclaration */: case 147 /* Parameter */: case 154 /* GetAccessor */: return serializeTypeNode(node.type); case 155 /* SetAccessor */: return serializeTypeNode(ts.getSetAccessorTypeAnnotationNode(node)); case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 152 /* MethodDeclaration */: return ts.createIdentifier("Function"); default: return ts.createVoidZero(); } } /** * Serializes the types of the parameters of a node for use with decorator type metadata. * * @param node The node that should have its parameter types serialized. */ function serializeParameterTypesOfNode(node, container) { var valueDeclaration = ts.isClassLike(node) ? ts.getFirstConstructorWithBody(node) : ts.isFunctionLike(node) && ts.nodeIsPresent(node.body) ? node : undefined; var expressions = []; if (valueDeclaration) { var parameters = getParametersOfDecoratedDeclaration(valueDeclaration, container); var numParameters = parameters.length; for (var i = 0; i < numParameters; i++) { var parameter = parameters[i]; if (i === 0 && ts.isIdentifier(parameter.name) && parameter.name.escapedText === "this") { continue; } if (parameter.dotDotDotToken) { expressions.push(serializeTypeNode(ts.getRestParameterElementType(parameter.type))); } else { expressions.push(serializeTypeOfNode(parameter)); } } } return ts.createArrayLiteral(expressions); } function getParametersOfDecoratedDeclaration(node, container) { if (container && node.kind === 154 /* GetAccessor */) { var setAccessor = ts.getAllAccessorDeclarations(container.members, node).setAccessor; if (setAccessor) { return setAccessor.parameters; } } return node.parameters; } /** * Serializes the return type of a node for use with decorator type metadata. * * @param node The node that should have its return type serialized. */ function serializeReturnTypeOfNode(node) { if (ts.isFunctionLike(node) && node.type) { return serializeTypeNode(node.type); } else if (ts.isAsyncFunction(node)) { return ts.createIdentifier("Promise"); } return ts.createVoidZero(); } /** * Serializes a type node for use with decorator type metadata. * * Types are serialized in the following fashion: * - Void types point to "undefined" (e.g. "void 0") * - Function and Constructor types point to the global "Function" constructor. * - Interface types with a call or construct signature types point to the global * "Function" constructor. * - Array and Tuple types point to the global "Array" constructor. * - Type predicates and booleans point to the global "Boolean" constructor. * - String literal types and strings point to the global "String" constructor. * - Enum and number types point to the global "Number" constructor. * - Symbol types point to the global "Symbol" constructor. * - Type references to classes (or class-like variables) point to the constructor for the class. * - Anything else points to the global "Object" constructor. * * @param node The type node to serialize. */ function serializeTypeNode(node) { if (node === undefined) { return ts.createIdentifier("Object"); } switch (node.kind) { case 105 /* VoidKeyword */: case 139 /* UndefinedKeyword */: case 95 /* NullKeyword */: case 130 /* NeverKeyword */: return ts.createVoidZero(); case 169 /* ParenthesizedType */: return serializeTypeNode(node.type); case 161 /* FunctionType */: case 162 /* ConstructorType */: return ts.createIdentifier("Function"); case 165 /* ArrayType */: case 166 /* TupleType */: return ts.createIdentifier("Array"); case 159 /* TypePredicate */: case 122 /* BooleanKeyword */: return ts.createIdentifier("Boolean"); case 136 /* StringKeyword */: return ts.createIdentifier("String"); case 134 /* ObjectKeyword */: return ts.createIdentifier("Object"); case 174 /* LiteralType */: switch (node.literal.kind) { case 9 /* StringLiteral */: return ts.createIdentifier("String"); case 8 /* NumericLiteral */: return ts.createIdentifier("Number"); case 101 /* TrueKeyword */: case 86 /* FalseKeyword */: return ts.createIdentifier("Boolean"); default: ts.Debug.failBadSyntaxKind(node.literal); break; } break; case 133 /* NumberKeyword */: return ts.createIdentifier("Number"); case 137 /* SymbolKeyword */: return languageVersion < 2 /* ES2015 */ ? getGlobalSymbolNameWithFallback() : ts.createIdentifier("Symbol"); case 160 /* TypeReference */: return serializeTypeReferenceNode(node); case 168 /* IntersectionType */: case 167 /* UnionType */: return serializeUnionOrIntersectionType(node); case 163 /* TypeQuery */: case 171 /* TypeOperator */: case 172 /* IndexedAccessType */: case 173 /* MappedType */: case 164 /* TypeLiteral */: case 119 /* AnyKeyword */: case 170 /* ThisType */: break; default: ts.Debug.failBadSyntaxKind(node); break; } return ts.createIdentifier("Object"); } function serializeUnionOrIntersectionType(node) { // Note when updating logic here also update getEntityNameForDecoratorMetadata // so that aliases can be marked as referenced var serializedUnion; for (var _i = 0, _a = node.types; _i < _a.length; _i++) { var typeNode = _a[_i]; while (typeNode.kind === 169 /* ParenthesizedType */) { typeNode = typeNode.type; // Skip parens if need be } if (typeNode.kind === 130 /* NeverKeyword */) { continue; // Always elide `never` from the union/intersection if possible } if (!strictNullChecks && (typeNode.kind === 95 /* NullKeyword */ || typeNode.kind === 139 /* UndefinedKeyword */)) { continue; // Elide null and undefined from unions for metadata, just like what we did prior to the implementation of strict null checks } var serializedIndividual = serializeTypeNode(typeNode); if (ts.isIdentifier(serializedIndividual) && serializedIndividual.escapedText === "Object") { // One of the individual is global object, return immediately return serializedIndividual; } else if (serializedUnion) { // Different types if (!ts.isIdentifier(serializedUnion) || !ts.isIdentifier(serializedIndividual) || serializedUnion.escapedText !== serializedIndividual.escapedText) { return ts.createIdentifier("Object"); } } else { // Initialize the union type serializedUnion = serializedIndividual; } } // If we were able to find common type, use it return serializedUnion || ts.createVoidZero(); // Fallback is only hit if all union constituients are null/undefined/never } /** * Serializes a TypeReferenceNode to an appropriate JS constructor value for use with * decorator type metadata. * * @param node The type reference node. */ function serializeTypeReferenceNode(node) { switch (resolver.getTypeReferenceSerializationKind(node.typeName, currentScope)) { case ts.TypeReferenceSerializationKind.Unknown: var serialized = serializeEntityNameAsExpression(node.typeName, /*useFallback*/ true); var temp = ts.createTempVariable(hoistVariableDeclaration); return ts.createLogicalOr(ts.createLogicalAnd(ts.createTypeCheck(ts.createAssignment(temp, serialized), "function"), temp), ts.createIdentifier("Object")); case ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue: return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false); case ts.TypeReferenceSerializationKind.VoidNullableOrNeverType: return ts.createVoidZero(); case ts.TypeReferenceSerializationKind.BooleanType: return ts.createIdentifier("Boolean"); case ts.TypeReferenceSerializationKind.NumberLikeType: return ts.createIdentifier("Number"); case ts.TypeReferenceSerializationKind.StringLikeType: return ts.createIdentifier("String"); case ts.TypeReferenceSerializationKind.ArrayLikeType: return ts.createIdentifier("Array"); case ts.TypeReferenceSerializationKind.ESSymbolType: return languageVersion < 2 /* ES2015 */ ? getGlobalSymbolNameWithFallback() : ts.createIdentifier("Symbol"); case ts.TypeReferenceSerializationKind.TypeWithCallSignature: return ts.createIdentifier("Function"); case ts.TypeReferenceSerializationKind.Promise: return ts.createIdentifier("Promise"); case ts.TypeReferenceSerializationKind.ObjectType: default: return ts.createIdentifier("Object"); } } /** * Serializes an entity name as an expression for decorator type metadata. * * @param node The entity name to serialize. * @param useFallback A value indicating whether to use logical operators to test for the * entity name at runtime. */ function serializeEntityNameAsExpression(node, useFallback) { switch (node.kind) { case 71 /* Identifier */: // Create a clone of the name with a new parent, and treat it as if it were // a source tree node for the purposes of the checker. var name = ts.getMutableClone(node); name.flags &= ~8 /* Synthesized */; name.original = undefined; name.parent = ts.getParseTreeNode(currentScope); // ensure the parent is set to a parse tree node. if (useFallback) { return ts.createLogicalAnd(ts.createStrictInequality(ts.createTypeOf(name), ts.createLiteral("undefined")), name); } return name; case 144 /* QualifiedName */: return serializeQualifiedNameAsExpression(node, useFallback); } } /** * Serializes an qualified name as an expression for decorator type metadata. * * @param node The qualified name to serialize. * @param useFallback A value indicating whether to use logical operators to test for the * qualified name at runtime. */ function serializeQualifiedNameAsExpression(node, useFallback) { var left; if (node.left.kind === 71 /* Identifier */) { left = serializeEntityNameAsExpression(node.left, useFallback); } else if (useFallback) { var temp = ts.createTempVariable(hoistVariableDeclaration); left = ts.createLogicalAnd(ts.createAssignment(temp, serializeEntityNameAsExpression(node.left, /*useFallback*/ true)), temp); } else { left = serializeEntityNameAsExpression(node.left, /*useFallback*/ false); } return ts.createPropertyAccess(left, node.right); } /** * Gets an expression that points to the global "Symbol" constructor at runtime if it is * available. */ function getGlobalSymbolNameWithFallback() { return ts.createConditional(ts.createTypeCheck(ts.createIdentifier("Symbol"), "function"), ts.createIdentifier("Symbol"), ts.createIdentifier("Object")); } /** * A simple inlinable expression is an expression which can be copied into multiple locations * without risk of repeating any sideeffects and whose value could not possibly change between * any such locations */ function isSimpleInlineableExpression(expression) { return !ts.isIdentifier(expression) && ts.isSimpleCopiableExpression(expression) || ts.isWellKnownSymbolSyntactically(expression); } /** * Gets an expression that represents a property name. For a computed property, a * name is generated for the node. * * @param member The member whose name should be converted into an expression. */ function getExpressionForPropertyName(member, generateNameForComputedPropertyName) { var name = member.name; if (ts.isComputedPropertyName(name)) { return generateNameForComputedPropertyName && !isSimpleInlineableExpression(name.expression) ? ts.getGeneratedNameForNode(name) : name.expression; } else if (ts.isIdentifier(name)) { return ts.createLiteral(ts.idText(name)); } else { return ts.getSynthesizedClone(name); } } /** * If the name is a computed property, this function transforms it, then either returns an expression which caches the * value of the result or the expression itself if the value is either unused or safe to inline into multiple locations * @param shouldHoist Does the expression need to be reused? (ie, for an initializer or a decorator) * @param omitSimple Should expressions with no observable side-effects be elided? (ie, the expression is not hoisted for a decorator or initializer and is a literal) */ function getPropertyNameExpressionIfNeeded(name, shouldHoist, omitSimple) { if (ts.isComputedPropertyName(name)) { var expression = ts.visitNode(name.expression, visitor, ts.isExpression); var innerExpression = ts.skipPartiallyEmittedExpressions(expression); var inlinable = isSimpleInlineableExpression(innerExpression); if (!inlinable && shouldHoist) { var generatedName = ts.getGeneratedNameForNode(name); hoistVariableDeclaration(generatedName); return ts.createAssignment(generatedName, expression); } return (omitSimple && (inlinable || ts.isIdentifier(innerExpression))) ? undefined : expression; } } /** * Visits the property name of a class element, for use when emitting property * initializers. For a computed property on a node with decorators, a temporary * value is stored for later use. * * @param member The member whose name should be visited. */ function visitPropertyNameOfClassElement(member) { var name = member.name; var expr = getPropertyNameExpressionIfNeeded(name, ts.some(member.decorators), /*omitSimple*/ false); if (expr) { // Inline any pending expressions from previous elided or relocated computed property name expressions in order to preserve execution order if (ts.some(pendingExpressions)) { expr = ts.inlineExpressions(pendingExpressions.concat([expr])); pendingExpressions.length = 0; } return ts.updateComputedPropertyName(name, expr); } else { return name; } } /** * Transforms a HeritageClause with TypeScript syntax. * * This function will only be called when one of the following conditions are met: * - The node is a non-`extends` heritage clause that should be elided. * - The node is an `extends` heritage clause that should be visited, but only allow a single type. * * @param node The HeritageClause to transform. */ function visitHeritageClause(node) { if (node.token === 85 /* ExtendsKeyword */) { var types = ts.visitNodes(node.types, visitor, ts.isExpressionWithTypeArguments, 0, 1); return ts.setTextRange(ts.createHeritageClause(85 /* ExtendsKeyword */, types), node); } return undefined; } /** * Transforms an ExpressionWithTypeArguments with TypeScript syntax. * * This function will only be called when one of the following conditions are met: * - The node contains type arguments that should be elided. * * @param node The ExpressionWithTypeArguments to transform. */ function visitExpressionWithTypeArguments(node) { return ts.updateExpressionWithTypeArguments(node, /*typeArguments*/ undefined, ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression)); } /** * Determines whether to emit a function-like declaration. We should not emit the * declaration if it does not have a body. * * @param node The declaration node. */ function shouldEmitFunctionLikeDeclaration(node) { return !ts.nodeIsMissing(node.body); } function visitPropertyDeclaration(node) { var expr = getPropertyNameExpressionIfNeeded(node.name, ts.some(node.decorators) || !!node.initializer, /*omitSimple*/ true); if (expr && !isSimpleInlineableExpression(expr)) { (pendingExpressions || (pendingExpressions = [])).push(expr); } return undefined; } function visitConstructor(node) { if (!shouldEmitFunctionLikeDeclaration(node)) { return undefined; } return ts.updateConstructor(node, ts.visitNodes(node.decorators, visitor, ts.isDecorator), ts.visitNodes(node.modifiers, visitor, ts.isModifier), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context)); } /** * Visits a method declaration of a class. * * This function will be called when one of the following conditions are met: * - The node is an overload * - The node is marked as abstract, public, private, protected, or readonly * - The node has a computed property name * * @param node The method node. */ function visitMethodDeclaration(node) { if (!shouldEmitFunctionLikeDeclaration(node)) { return undefined; } var updated = ts.updateMethod(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, visitPropertyNameOfClassElement(node), /*questionToken*/ undefined, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context)); if (updated !== node) { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. ts.setCommentRange(updated, node); ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node)); } return updated; } /** * Determines whether to emit an accessor declaration. We should not emit the * declaration if it does not have a body and is abstract. * * @param node The declaration node. */ function shouldEmitAccessorDeclaration(node) { return !(ts.nodeIsMissing(node.body) && ts.hasModifier(node, 128 /* Abstract */)); } /** * Visits a get accessor declaration of a class. * * This function will be called when one of the following conditions are met: * - The node is marked as abstract, public, private, or protected * - The node has a computed property name * * @param node The get accessor node. */ function visitGetAccessor(node) { if (!shouldEmitAccessorDeclaration(node)) { return undefined; } var updated = ts.updateGetAccessor(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([])); if (updated !== node) { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. ts.setCommentRange(updated, node); ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node)); } return updated; } /** * Visits a set accessor declaration of a class. * * This function will be called when one of the following conditions are met: * - The node is marked as abstract, public, private, or protected * - The node has a computed property name * * @param node The set accessor node. */ function visitSetAccessor(node) { if (!shouldEmitAccessorDeclaration(node)) { return undefined; } var updated = ts.updateSetAccessor(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), visitPropertyNameOfClassElement(node), ts.visitParameterList(node.parameters, visitor, context), ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([])); if (updated !== node) { // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. ts.setCommentRange(updated, node); ts.setSourceMapRange(updated, ts.moveRangePastDecorators(node)); } return updated; } /** * Visits a function declaration. * * This function will be called when one of the following conditions are met: * - The node is an overload * - The node is exported from a TypeScript namespace * - The node has decorators * * @param node The function node. */ function visitFunctionDeclaration(node) { if (!shouldEmitFunctionLikeDeclaration(node)) { return ts.createNotEmittedStatement(node); } var updated = ts.updateFunctionDeclaration(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([])); if (isExportOfNamespace(node)) { var statements = [updated]; addExportMemberAssignment(statements, node); return statements; } return updated; } /** * Visits a function expression node. * * This function will be called when one of the following conditions are met: * - The node has type annotations * * @param node The function expression node. */ function visitFunctionExpression(node) { if (!shouldEmitFunctionLikeDeclaration(node)) { return ts.createOmittedExpression(); } var updated = ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.visitFunctionBody(node.body, visitor, context) || ts.createBlock([])); return updated; } /** * @remarks * This function will be called when one of the following conditions are met: * - The node has type annotations */ function visitArrowFunction(node) { var updated = ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, node.equalsGreaterThanToken, ts.visitFunctionBody(node.body, visitor, context)); return updated; } /** * Visits a parameter declaration node. * * This function will be called when one of the following conditions are met: * - The node has an accessibility modifier. * - The node has a questionToken. * - The node's kind is ThisKeyword. * * @param node The parameter declaration node. */ function visitParameter(node) { if (ts.parameterIsThisKeyword(node)) { return undefined; } var parameter = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, node.dotDotDotToken, ts.visitNode(node.name, visitor, ts.isBindingName), /*questionToken*/ undefined, /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression)); // While we emit the source map for the node after skipping decorators and modifiers, // we need to emit the comments for the original range. ts.setOriginalNode(parameter, node); ts.setTextRange(parameter, ts.moveRangePastModifiers(node)); ts.setCommentRange(parameter, node); ts.setSourceMapRange(parameter, ts.moveRangePastModifiers(node)); ts.setEmitFlags(parameter.name, 32 /* NoTrailingSourceMap */); return parameter; } /** * Visits a variable statement in a namespace. * * This function will be called when one of the following conditions are met: * - The node is exported from a TypeScript namespace. */ function visitVariableStatement(node) { if (isExportOfNamespace(node)) { var variables = ts.getInitializedVariables(node.declarationList); if (variables.length === 0) { // elide statement if there are no initialized variables. return undefined; } return ts.setTextRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node); } else { return ts.visitEachChild(node, visitor, context); } } function transformInitializedVariable(node) { var name = node.name; if (ts.isBindingPattern(name)) { return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, /*needsValue*/ false, createNamespaceExportExpression); } else { return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(name), ts.visitNode(node.initializer, visitor, ts.isExpression)), /*location*/ node); } } function visitVariableDeclaration(node) { return ts.updateVariableDeclaration(node, ts.visitNode(node.name, visitor, ts.isBindingName), /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression)); } /** * Visits a parenthesized expression that contains either a type assertion or an `as` * expression. * * @param node The parenthesized expression node. */ function visitParenthesizedExpression(node) { var innerExpression = ts.skipOuterExpressions(node.expression, ~2 /* Assertions */); if (ts.isAssertionExpression(innerExpression)) { // Make sure we consider all nested cast expressions, e.g.: // (-A).x; var expression = ts.visitNode(node.expression, visitor, ts.isExpression); // We have an expression of the form: (SubExpr). Emitting this as (SubExpr) // is really not desirable. We would like to emit the subexpression as-is. Omitting // the parentheses, however, could cause change in the semantics of the generated // code if the casted expression has a lower precedence than the rest of the // expression. // // To preserve comments, we return a "PartiallyEmittedExpression" here which will // preserve the position information of the original expression. // // Due to the auto-parenthesization rules used by the visitor and factory functions // we can safely elide the parentheses here, as a new synthetic // ParenthesizedExpression will be inserted if we remove parentheses too // aggressively. return ts.createPartiallyEmittedExpression(expression, node); } return ts.visitEachChild(node, visitor, context); } function visitAssertionExpression(node) { var expression = ts.visitNode(node.expression, visitor, ts.isExpression); return ts.createPartiallyEmittedExpression(expression, node); } function visitNonNullExpression(node) { var expression = ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression); return ts.createPartiallyEmittedExpression(expression, node); } function visitCallExpression(node) { return ts.updateCall(node, ts.visitNode(node.expression, visitor, ts.isExpression), /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } function visitNewExpression(node) { return ts.updateNew(node, ts.visitNode(node.expression, visitor, ts.isExpression), /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } /** * Determines whether to emit an enum declaration. * * @param node The enum declaration node. */ function shouldEmitEnumDeclaration(node) { return !ts.isConst(node) || compilerOptions.preserveConstEnums || compilerOptions.isolatedModules; } /** * Visits an enum declaration. * * This function will be called any time a TypeScript enum is encountered. * * @param node The enum declaration node. */ function visitEnumDeclaration(node) { if (!shouldEmitEnumDeclaration(node)) { return undefined; } var statements = []; // We request to be advised when the printer is about to print this node. This allows // us to set up the correct state for later substitutions. var emitFlags = 2 /* AdviseOnEmitNode */; // If needed, we should emit a variable declaration for the enum. If we emit // a leading variable declaration, we should not emit leading comments for the // enum body. if (addVarForEnumOrModuleDeclaration(statements, node)) { // We should still emit the comments if we are emitting a system module. if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) { emitFlags |= 512 /* NoLeadingComments */; } } // `parameterName` is the declaration name used inside of the enum. var parameterName = getNamespaceParameterName(node); // `containerName` is the expression used inside of the enum for assignments. var containerName = getNamespaceContainerName(node); // `exportName` is the expression used within this node's container for any exported references. var exportName = ts.hasModifier(node, 1 /* Export */) ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x || (x = {}) // exports.x || (exports.x = {}) var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral())); if (hasNamespaceQualifiedExportName(node)) { // `localName` is the expression used within this node's containing scope for any local references. var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x = (exports.x || (exports.x = {})) moduleArg = ts.createAssignment(localName, moduleArg); } // (function (x) { // x[x["y"] = 0] = "y"; // ... // })(x || (x = {})); var enumStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, transformEnumBody(node, containerName)), /*typeArguments*/ undefined, [moduleArg])); ts.setOriginalNode(enumStatement, node); ts.setTextRange(enumStatement, node); ts.setEmitFlags(enumStatement, emitFlags); statements.push(enumStatement); // Add a DeclarationMarker for the enum to preserve trailing comments and mark // the end of the declaration. statements.push(ts.createEndOfDeclarationMarker(node)); return statements; } /** * Transforms the body of an enum declaration. * * @param node The enum declaration node. */ function transformEnumBody(node, localName) { var savedCurrentNamespaceLocalName = currentNamespaceContainerName; currentNamespaceContainerName = localName; var statements = []; startLexicalEnvironment(); ts.addRange(statements, ts.map(node.members, transformEnumMember)); ts.addRange(statements, endLexicalEnvironment()); currentNamespaceContainerName = savedCurrentNamespaceLocalName; return ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true); } /** * Transforms an enum member into a statement. * * @param member The enum member node. */ function transformEnumMember(member) { // enums don't support computed properties // we pass false as 'generateNameForComputedPropertyName' for a backward compatibility purposes // old emitter always generate 'expression' part of the name as-is. var name = getExpressionForPropertyName(member, /*generateNameForComputedPropertyName*/ false); var valueExpression = transformEnumMemberDeclarationValue(member); var innerAssignment = ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, name), valueExpression); var outerAssignment = valueExpression.kind === 9 /* StringLiteral */ ? innerAssignment : ts.createAssignment(ts.createElementAccess(currentNamespaceContainerName, innerAssignment), name); return ts.setTextRange(ts.createStatement(ts.setTextRange(outerAssignment, member)), member); } /** * Transforms the value of an enum member. * * @param member The enum member node. */ function transformEnumMemberDeclarationValue(member) { var value = resolver.getConstantValue(member); if (value !== undefined) { return ts.createLiteral(value); } else { enableSubstitutionForNonQualifiedEnumMembers(); if (member.initializer) { return ts.visitNode(member.initializer, visitor, ts.isExpression); } else { return ts.createVoidZero(); } } } /** * Determines whether to elide a module declaration. * * @param node The module declaration node. */ function shouldEmitModuleDeclaration(node) { return ts.isInstantiatedModule(node, compilerOptions.preserveConstEnums || compilerOptions.isolatedModules); } /** * Determines whether an exported declaration will have a qualified export name (e.g. `f.x` * or `exports.x`). */ function hasNamespaceQualifiedExportName(node) { return isExportOfNamespace(node) || (isExternalModuleExport(node) && moduleKind !== ts.ModuleKind.ES2015 && moduleKind !== ts.ModuleKind.ESNext && moduleKind !== ts.ModuleKind.System); } /** * Records that a declaration was emitted in the current scope, if it was the first * declaration for the provided symbol. */ function recordEmittedDeclarationInScope(node) { if (!currentScopeFirstDeclarationsOfName) { currentScopeFirstDeclarationsOfName = ts.createUnderscoreEscapedMap(); } var name = declaredNameInScope(node); if (!currentScopeFirstDeclarationsOfName.has(name)) { currentScopeFirstDeclarationsOfName.set(name, node); } } /** * Determines whether a declaration is the first declaration with * the same name emitted in the current scope. */ function isFirstEmittedDeclarationInScope(node) { if (currentScopeFirstDeclarationsOfName) { var name = declaredNameInScope(node); return currentScopeFirstDeclarationsOfName.get(name) === node; } return true; } function declaredNameInScope(node) { ts.Debug.assertNode(node.name, ts.isIdentifier); return node.name.escapedText; } /** * Adds a leading VariableStatement for a enum or module declaration. */ function addVarForEnumOrModuleDeclaration(statements, node) { // Emit a variable statement for the module. We emit top-level enums as a `var` // declaration to avoid static errors in global scripts scripts due to redeclaration. // enums in any other scope are emitted as a `let` declaration. var statement = ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([ ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true)) ], currentScope.kind === 269 /* SourceFile */ ? 0 /* None */ : 1 /* Let */)); ts.setOriginalNode(statement, node); recordEmittedDeclarationInScope(node); if (isFirstEmittedDeclarationInScope(node)) { // Adjust the source map emit to match the old emitter. if (node.kind === 233 /* EnumDeclaration */) { ts.setSourceMapRange(statement.declarationList, node); } else { ts.setSourceMapRange(statement, node); } // Trailing comments for module declaration should be emitted after the function closure // instead of the variable statement: // // /** Module comment*/ // module m1 { // function foo4Export() { // } // } // trailing comment module // // Should emit: // // /** Module comment*/ // var m1; // (function (m1) { // function foo4Export() { // } // })(m1 || (m1 = {})); // trailing comment module // ts.setCommentRange(statement, node); ts.setEmitFlags(statement, 1024 /* NoTrailingComments */ | 4194304 /* HasEndOfDeclarationMarker */); statements.push(statement); return true; } else { // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding // declaration we do not emit a leading variable declaration. To preserve the // begin/end semantics of the declararation and to properly handle exports // we wrap the leading variable declaration in a `MergeDeclarationMarker`. var mergeMarker = ts.createMergeDeclarationMarker(statement); ts.setEmitFlags(mergeMarker, 1536 /* NoComments */ | 4194304 /* HasEndOfDeclarationMarker */); statements.push(mergeMarker); return false; } } /** * Visits a module declaration node. * * This function will be called any time a TypeScript namespace (ModuleDeclaration) is encountered. * * @param node The module declaration node. */ function visitModuleDeclaration(node) { if (!shouldEmitModuleDeclaration(node)) { return ts.createNotEmittedStatement(node); } ts.Debug.assertNode(node.name, ts.isIdentifier, "A TypeScript namespace should have an Identifier name."); enableSubstitutionForNamespaceExports(); var statements = []; // We request to be advised when the printer is about to print this node. This allows // us to set up the correct state for later substitutions. var emitFlags = 2 /* AdviseOnEmitNode */; // If needed, we should emit a variable declaration for the module. If we emit // a leading variable declaration, we should not emit leading comments for the // module body. if (addVarForEnumOrModuleDeclaration(statements, node)) { // We should still emit the comments if we are emitting a system module. if (moduleKind !== ts.ModuleKind.System || currentScope !== currentSourceFile) { emitFlags |= 512 /* NoLeadingComments */; } } // `parameterName` is the declaration name used inside of the namespace. var parameterName = getNamespaceParameterName(node); // `containerName` is the expression used inside of the namespace for exports. var containerName = getNamespaceContainerName(node); // `exportName` is the expression used within this node's container for any exported references. var exportName = ts.hasModifier(node, 1 /* Export */) ? ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true) : ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x || (x = {}) // exports.x || (exports.x = {}) var moduleArg = ts.createLogicalOr(exportName, ts.createAssignment(exportName, ts.createObjectLiteral())); if (hasNamespaceQualifiedExportName(node)) { // `localName` is the expression used within this node's containing scope for any local references. var localName = ts.getLocalName(node, /*allowComments*/ false, /*allowSourceMaps*/ true); // x = (exports.x || (exports.x = {})) moduleArg = ts.createAssignment(localName, moduleArg); } // (function (x_1) { // x_1.y = ...; // })(x || (x = {})); var moduleStatement = ts.createStatement(ts.createCall(ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, transformModuleBody(node, containerName)), /*typeArguments*/ undefined, [moduleArg])); ts.setOriginalNode(moduleStatement, node); ts.setTextRange(moduleStatement, node); ts.setEmitFlags(moduleStatement, emitFlags); statements.push(moduleStatement); // Add a DeclarationMarker for the namespace to preserve trailing comments and mark // the end of the declaration. statements.push(ts.createEndOfDeclarationMarker(node)); return statements; } /** * Transforms the body of a module declaration. * * @param node The module declaration node. */ function transformModuleBody(node, namespaceLocalName) { var savedCurrentNamespaceContainerName = currentNamespaceContainerName; var savedCurrentNamespace = currentNamespace; var savedCurrentScopeFirstDeclarationsOfName = currentScopeFirstDeclarationsOfName; currentNamespaceContainerName = namespaceLocalName; currentNamespace = node; currentScopeFirstDeclarationsOfName = undefined; var statements = []; startLexicalEnvironment(); var statementsLocation; var blockLocation; var body = node.body; if (body.kind === 235 /* ModuleBlock */) { saveStateAndInvoke(body, function (body) { return ts.addRange(statements, ts.visitNodes(body.statements, namespaceElementVisitor, ts.isStatement)); }); statementsLocation = body.statements; blockLocation = body; } else { var result = visitModuleDeclaration(body); if (result) { if (ts.isArray(result)) { ts.addRange(statements, result); } else { statements.push(result); } } var moduleBlock = getInnerMostModuleDeclarationFromDottedModule(node).body; statementsLocation = ts.moveRangePos(moduleBlock.statements, -1); } ts.addRange(statements, endLexicalEnvironment()); currentNamespaceContainerName = savedCurrentNamespaceContainerName; currentNamespace = savedCurrentNamespace; currentScopeFirstDeclarationsOfName = savedCurrentScopeFirstDeclarationsOfName; var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ statementsLocation), /*multiLine*/ true); ts.setTextRange(block, blockLocation); // namespace hello.hi.world { // function foo() {} // // // TODO, blah // } // // should be emitted as // // var hello; // (function (hello) { // var hi; // (function (hi) { // var world; // (function (world) { // function foo() { } // // TODO, blah // })(world = hi.world || (hi.world = {})); // })(hi = hello.hi || (hello.hi = {})); // })(hello || (hello = {})); // We only want to emit comment on the namespace which contains block body itself, not the containing namespaces. if (body.kind !== 235 /* ModuleBlock */) { ts.setEmitFlags(block, ts.getEmitFlags(block) | 1536 /* NoComments */); } return block; } function getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration) { if (moduleDeclaration.body.kind === 234 /* ModuleDeclaration */) { var recursiveInnerModule = getInnerMostModuleDeclarationFromDottedModule(moduleDeclaration.body); return recursiveInnerModule || moduleDeclaration.body; } } /** * Visits an import declaration, eliding it if it is not referenced. * * @param node The import declaration node. */ function visitImportDeclaration(node) { if (!node.importClause) { // Do not elide a side-effect only import declaration. // import "foo"; return node; } // Elide the declaration if the import clause was elided. var importClause = ts.visitNode(node.importClause, visitImportClause, ts.isImportClause); return importClause ? ts.updateImportDeclaration(node, /*decorators*/ undefined, /*modifiers*/ undefined, importClause, node.moduleSpecifier) : undefined; } /** * Visits an import clause, eliding it if it is not referenced. * * @param node The import clause node. */ function visitImportClause(node) { // Elide the import clause if we elide both its name and its named bindings. var name = resolver.isReferencedAliasDeclaration(node) ? node.name : undefined; var namedBindings = ts.visitNode(node.namedBindings, visitNamedImportBindings, ts.isNamedImportBindings); return (name || namedBindings) ? ts.updateImportClause(node, name, namedBindings) : undefined; } /** * Visits named import bindings, eliding it if it is not referenced. * * @param node The named import bindings node. */ function visitNamedImportBindings(node) { if (node.kind === 241 /* NamespaceImport */) { // Elide a namespace import if it is not referenced. return resolver.isReferencedAliasDeclaration(node) ? node : undefined; } else { // Elide named imports if all of its import specifiers are elided. var elements = ts.visitNodes(node.elements, visitImportSpecifier, ts.isImportSpecifier); return ts.some(elements) ? ts.updateNamedImports(node, elements) : undefined; } } /** * Visits an import specifier, eliding it if it is not referenced. * * @param node The import specifier node. */ function visitImportSpecifier(node) { // Elide an import specifier if it is not referenced. return resolver.isReferencedAliasDeclaration(node) ? node : undefined; } /** * Visits an export assignment, eliding it if it does not contain a clause that resolves * to a value. * * @param node The export assignment node. */ function visitExportAssignment(node) { // Elide the export assignment if it does not reference a value. return resolver.isValueAliasDeclaration(node) ? ts.visitEachChild(node, visitor, context) : undefined; } /** * Visits an export declaration, eliding it if it does not contain a clause that resolves * to a value. * * @param node The export declaration node. */ function visitExportDeclaration(node) { if (!node.exportClause) { // Elide a star export if the module it references does not export a value. return compilerOptions.isolatedModules || resolver.moduleExportsSomeValue(node.moduleSpecifier) ? node : undefined; } if (!resolver.isValueAliasDeclaration(node)) { // Elide the export declaration if it does not export a value. return undefined; } // Elide the export declaration if all of its named exports are elided. var exportClause = ts.visitNode(node.exportClause, visitNamedExports, ts.isNamedExports); return exportClause ? ts.updateExportDeclaration(node, /*decorators*/ undefined, /*modifiers*/ undefined, exportClause, node.moduleSpecifier) : undefined; } /** * Visits named exports, eliding it if it does not contain an export specifier that * resolves to a value. * * @param node The named exports node. */ function visitNamedExports(node) { // Elide the named exports if all of its export specifiers were elided. var elements = ts.visitNodes(node.elements, visitExportSpecifier, ts.isExportSpecifier); return ts.some(elements) ? ts.updateNamedExports(node, elements) : undefined; } /** * Visits an export specifier, eliding it if it does not resolve to a value. * * @param node The export specifier node. */ function visitExportSpecifier(node) { // Elide an export specifier if it does not reference a value. return resolver.isValueAliasDeclaration(node) ? node : undefined; } /** * Determines whether to emit an import equals declaration. * * @param node The import equals declaration node. */ function shouldEmitImportEqualsDeclaration(node) { // preserve old compiler's behavior: emit 'var' for import declaration (even if we do not consider them referenced) when // - current file is not external module // - import declaration is top level and target is value imported by entity name return resolver.isReferencedAliasDeclaration(node) || (!ts.isExternalModule(currentSourceFile) && resolver.isTopLevelValueImportEqualsWithEntityName(node)); } /** * Visits an import equals declaration. * * @param node The import equals declaration node. */ function visitImportEqualsDeclaration(node) { if (ts.isExternalModuleImportEqualsDeclaration(node)) { // Elide external module `import=` if it is not referenced. return resolver.isReferencedAliasDeclaration(node) ? ts.visitEachChild(node, visitor, context) : undefined; } if (!shouldEmitImportEqualsDeclaration(node)) { return undefined; } var moduleReference = ts.createExpressionFromEntityName(node.moduleReference); ts.setEmitFlags(moduleReference, 1536 /* NoComments */ | 2048 /* NoNestedComments */); if (isNamedExternalModuleExport(node) || !isExportOfNamespace(node)) { // export var ${name} = ${moduleReference}; // var ${name} = ${moduleReference}; return ts.setOriginalNode(ts.setTextRange(ts.createVariableStatement(ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.createVariableDeclarationList([ ts.setOriginalNode(ts.createVariableDeclaration(node.name, /*type*/ undefined, moduleReference), node) ])), node), node); } else { // exports.${name} = ${moduleReference}; return ts.setOriginalNode(createNamespaceExport(node.name, moduleReference, node), node); } } /** * Gets a value indicating whether the node is exported from a namespace. * * @param node The node to test. */ function isExportOfNamespace(node) { return currentNamespace !== undefined && ts.hasModifier(node, 1 /* Export */); } /** * Gets a value indicating whether the node is exported from an external module. * * @param node The node to test. */ function isExternalModuleExport(node) { return currentNamespace === undefined && ts.hasModifier(node, 1 /* Export */); } /** * Gets a value indicating whether the node is a named export from an external module. * * @param node The node to test. */ function isNamedExternalModuleExport(node) { return isExternalModuleExport(node) && !ts.hasModifier(node, 512 /* Default */); } /** * Gets a value indicating whether the node is the default export of an external module. * * @param node The node to test. */ function isDefaultExternalModuleExport(node) { return isExternalModuleExport(node) && ts.hasModifier(node, 512 /* Default */); } /** * Creates a statement for the provided expression. This is used in calls to `map`. */ function expressionToStatement(expression) { return ts.createStatement(expression); } function addExportMemberAssignment(statements, node) { var expression = ts.createAssignment(ts.getExternalModuleOrNamespaceExportName(currentNamespaceContainerName, node, /*allowComments*/ false, /*allowSourceMaps*/ true), ts.getLocalName(node)); ts.setSourceMapRange(expression, ts.createRange(node.name ? node.name.pos : node.pos, node.end)); var statement = ts.createStatement(expression); ts.setSourceMapRange(statement, ts.createRange(-1, node.end)); statements.push(statement); } function createNamespaceExport(exportName, exportValue, location) { return ts.setTextRange(ts.createStatement(ts.createAssignment(ts.getNamespaceMemberName(currentNamespaceContainerName, exportName, /*allowComments*/ false, /*allowSourceMaps*/ true), exportValue)), location); } function createNamespaceExportExpression(exportName, exportValue, location) { return ts.setTextRange(ts.createAssignment(getNamespaceMemberNameWithSourceMapsAndWithoutComments(exportName), exportValue), location); } function getNamespaceMemberNameWithSourceMapsAndWithoutComments(name) { return ts.getNamespaceMemberName(currentNamespaceContainerName, name, /*allowComments*/ false, /*allowSourceMaps*/ true); } /** * Gets the declaration name used inside of a namespace or enum. */ function getNamespaceParameterName(node) { var name = ts.getGeneratedNameForNode(node); ts.setSourceMapRange(name, node.name); return name; } /** * Gets the expression used to refer to a namespace or enum within the body * of its declaration. */ function getNamespaceContainerName(node) { return ts.getGeneratedNameForNode(node); } /** * Gets a local alias for a class declaration if it is a decorated class with an internal * reference to the static side of the class. This is necessary to avoid issues with * double-binding semantics for the class name. */ function getClassAliasIfNeeded(node) { if (resolver.getNodeCheckFlags(node) & 8388608 /* ClassWithConstructorReference */) { enableSubstitutionForClassAliases(); var classAlias = ts.createUniqueName(node.name && !ts.isGeneratedIdentifier(node.name) ? ts.idText(node.name) : "default"); classAliases[ts.getOriginalNodeId(node)] = classAlias; hoistVariableDeclaration(classAlias); return classAlias; } } function getClassPrototype(node) { return ts.createPropertyAccess(ts.getDeclarationName(node), "prototype"); } function getClassMemberPrefix(node, member) { return ts.hasModifier(member, 32 /* Static */) ? ts.getDeclarationName(node) : getClassPrototype(node); } function enableSubstitutionForNonQualifiedEnumMembers() { if ((enabledSubstitutions & 8 /* NonQualifiedEnumMembers */) === 0) { enabledSubstitutions |= 8 /* NonQualifiedEnumMembers */; context.enableSubstitution(71 /* Identifier */); } } function enableSubstitutionForClassAliases() { if ((enabledSubstitutions & 1 /* ClassAliases */) === 0) { enabledSubstitutions |= 1 /* ClassAliases */; // We need to enable substitutions for identifiers. This allows us to // substitute class names inside of a class declaration. context.enableSubstitution(71 /* Identifier */); // Keep track of class aliases. classAliases = []; } } function enableSubstitutionForNamespaceExports() { if ((enabledSubstitutions & 2 /* NamespaceExports */) === 0) { enabledSubstitutions |= 2 /* NamespaceExports */; // We need to enable substitutions for identifiers and shorthand property assignments. This allows us to // substitute the names of exported members of a namespace. context.enableSubstitution(71 /* Identifier */); context.enableSubstitution(266 /* ShorthandPropertyAssignment */); // We need to be notified when entering and exiting namespaces. context.enableEmitNotification(234 /* ModuleDeclaration */); } } function isTransformedModuleDeclaration(node) { return ts.getOriginalNode(node).kind === 234 /* ModuleDeclaration */; } function isTransformedEnumDeclaration(node) { return ts.getOriginalNode(node).kind === 233 /* EnumDeclaration */; } /** * Hook for node emit. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ function onEmitNode(hint, node, emitCallback) { var savedApplicableSubstitutions = applicableSubstitutions; var savedCurrentSourceFile = currentSourceFile; if (ts.isSourceFile(node)) { currentSourceFile = node; } if (enabledSubstitutions & 2 /* NamespaceExports */ && isTransformedModuleDeclaration(node)) { applicableSubstitutions |= 2 /* NamespaceExports */; } if (enabledSubstitutions & 8 /* NonQualifiedEnumMembers */ && isTransformedEnumDeclaration(node)) { applicableSubstitutions |= 8 /* NonQualifiedEnumMembers */; } previousOnEmitNode(hint, node, emitCallback); applicableSubstitutions = savedApplicableSubstitutions; currentSourceFile = savedCurrentSourceFile; } /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (hint === 1 /* Expression */) { return substituteExpression(node); } else if (ts.isShorthandPropertyAssignment(node)) { return substituteShorthandPropertyAssignment(node); } return node; } function substituteShorthandPropertyAssignment(node) { if (enabledSubstitutions & 2 /* NamespaceExports */) { var name = node.name; var exportedName = trySubstituteNamespaceExportedName(name); if (exportedName) { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { var initializer = ts.createAssignment(exportedName, node.objectAssignmentInitializer); return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node); } return ts.setTextRange(ts.createPropertyAssignment(name, exportedName), node); } } return node; } function substituteExpression(node) { switch (node.kind) { case 71 /* Identifier */: return substituteExpressionIdentifier(node); case 180 /* PropertyAccessExpression */: return substitutePropertyAccessExpression(node); case 181 /* ElementAccessExpression */: return substituteElementAccessExpression(node); } return node; } function substituteExpressionIdentifier(node) { return trySubstituteClassAlias(node) || trySubstituteNamespaceExportedName(node) || node; } function trySubstituteClassAlias(node) { if (enabledSubstitutions & 1 /* ClassAliases */) { if (resolver.getNodeCheckFlags(node) & 16777216 /* ConstructorReferenceInClass */) { // Due to the emit for class decorators, any reference to the class from inside of the class body // must instead be rewritten to point to a temporary variable to avoid issues with the double-bind // behavior of class names in ES6. // Also, when emitting statics for class expressions, we must substitute a class alias for // constructor references in static property initializers. var declaration = resolver.getReferencedValueDeclaration(node); if (declaration) { var classAlias = classAliases[declaration.id]; if (classAlias) { var clone_1 = ts.getSynthesizedClone(classAlias); ts.setSourceMapRange(clone_1, node); ts.setCommentRange(clone_1, node); return clone_1; } } } } return undefined; } function trySubstituteNamespaceExportedName(node) { // If this is explicitly a local name, do not substitute. if (enabledSubstitutions & applicableSubstitutions && !ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) { // If we are nested within a namespace declaration, we may need to qualifiy // an identifier that is exported from a merged namespace. var container = resolver.getReferencedExportContainer(node, /*prefixLocals*/ false); if (container && container.kind !== 269 /* SourceFile */) { var substitute = (applicableSubstitutions & 2 /* NamespaceExports */ && container.kind === 234 /* ModuleDeclaration */) || (applicableSubstitutions & 8 /* NonQualifiedEnumMembers */ && container.kind === 233 /* EnumDeclaration */); if (substitute) { return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(container), node), /*location*/ node); } } } return undefined; } function substitutePropertyAccessExpression(node) { return substituteConstantValue(node); } function substituteElementAccessExpression(node) { return substituteConstantValue(node); } function substituteConstantValue(node) { var constantValue = tryGetConstEnumValue(node); if (constantValue !== undefined) { // track the constant value on the node for the printer in needsDotDotForPropertyAccess ts.setConstantValue(node, constantValue); var substitute = ts.createLiteral(constantValue); if (!compilerOptions.removeComments) { var propertyName = ts.isPropertyAccessExpression(node) ? ts.declarationNameToString(node.name) : ts.getTextOfNode(node.argumentExpression); ts.addSyntheticTrailingComment(substitute, 3 /* MultiLineCommentTrivia */, " " + propertyName + " "); } return substitute; } return node; } function tryGetConstEnumValue(node) { if (compilerOptions.isolatedModules) { return undefined; } return ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node) ? resolver.getConstantValue(node) : undefined; } } ts.transformTypeScript = transformTypeScript; function createDecorateHelper(context, decoratorExpressions, target, memberName, descriptor, location) { var argumentsArray = []; argumentsArray.push(ts.createArrayLiteral(decoratorExpressions, /*multiLine*/ true)); argumentsArray.push(target); if (memberName) { argumentsArray.push(memberName); if (descriptor) { argumentsArray.push(descriptor); } } context.requestEmitHelper(decorateHelper); return ts.setTextRange(ts.createCall(ts.getHelperName("__decorate"), /*typeArguments*/ undefined, argumentsArray), location); } var decorateHelper = { name: "typescript:decorate", scoped: false, priority: 2, text: "\n var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n return c > 3 && r && Object.defineProperty(target, key, r), r;\n };" }; function createMetadataHelper(context, metadataKey, metadataValue) { context.requestEmitHelper(metadataHelper); return ts.createCall(ts.getHelperName("__metadata"), /*typeArguments*/ undefined, [ ts.createLiteral(metadataKey), metadataValue ]); } var metadataHelper = { name: "typescript:metadata", scoped: false, priority: 3, text: "\n var __metadata = (this && this.__metadata) || function (k, v) {\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(k, v);\n };" }; function createParamHelper(context, expression, parameterOffset, location) { context.requestEmitHelper(paramHelper); return ts.setTextRange(ts.createCall(ts.getHelperName("__param"), /*typeArguments*/ undefined, [ ts.createLiteral(parameterOffset), expression ]), location); } var paramHelper = { name: "typescript:param", scoped: false, priority: 4, text: "\n var __param = (this && this.__param) || function (paramIndex, decorator) {\n return function (target, key) { decorator(target, key, paramIndex); }\n };" }; })(ts || (ts = {})); /// /// /*@internal*/ var ts; (function (ts) { var ES2017SubstitutionFlags; (function (ES2017SubstitutionFlags) { /** Enables substitutions for async methods with `super` calls. */ ES2017SubstitutionFlags[ES2017SubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper"; })(ES2017SubstitutionFlags || (ES2017SubstitutionFlags = {})); function transformES2017(context) { var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment; var resolver = context.getEmitResolver(); var compilerOptions = context.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); /** * Keeps track of whether expression substitution has been enabled for specific edge cases. * They are persisted between each SourceFile transformation and should not be reset. */ var enabledSubstitutions; /** * This keeps track of containers where `super` is valid, for use with * just-in-time substitution for `super` expressions inside of async methods. */ var enclosingSuperContainerFlags = 0; // Save the previous transformation hooks. var previousOnEmitNode = context.onEmitNode; var previousOnSubstituteNode = context.onSubstituteNode; // Set new transformation hooks. context.onEmitNode = onEmitNode; context.onSubstituteNode = onSubstituteNode; return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } var visited = ts.visitEachChild(node, visitor, context); ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; } function visitor(node) { if ((node.transformFlags & 16 /* ContainsES2017 */) === 0) { return node; } switch (node.kind) { case 120 /* AsyncKeyword */: // ES2017 async modifier should be elided for targets < ES2017 return undefined; case 192 /* AwaitExpression */: return visitAwaitExpression(node); case 152 /* MethodDeclaration */: return visitMethodDeclaration(node); case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 187 /* FunctionExpression */: return visitFunctionExpression(node); case 188 /* ArrowFunction */: return visitArrowFunction(node); default: return ts.visitEachChild(node, visitor, context); } } /** * Visits an AwaitExpression node. * * This function will be called any time a ES2017 await expression is encountered. * * @param node The node to visit. */ function visitAwaitExpression(node) { return ts.setOriginalNode(ts.setTextRange(ts.createYield( /*asteriskToken*/ undefined, ts.visitNode(node.expression, visitor, ts.isExpression)), node), node); } /** * Visits a MethodDeclaration node. * * This function will be called when one of the following conditions are met: * - The node is marked as async * * @param node The node to visit. */ function visitMethodDeclaration(node) { return ts.updateMethod(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, /*questionToken*/ undefined, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } /** * Visits a FunctionDeclaration node. * * This function will be called when one of the following conditions are met: * - The node is marked async * * @param node The node to visit. */ function visitFunctionDeclaration(node) { return ts.updateFunctionDeclaration(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } /** * Visits a FunctionExpression node. * * This function will be called when one of the following conditions are met: * - The node is marked async * * @param node The node to visit. */ function visitFunctionExpression(node) { return ts.updateFunctionExpression(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } /** * Visits an ArrowFunction. * * This function will be called when one of the following conditions are met: * - The node is marked async * * @param node The node to visit. */ function visitArrowFunction(node) { return ts.updateArrowFunction(node, ts.visitNodes(node.modifiers, visitor, ts.isModifier), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, node.equalsGreaterThanToken, ts.getFunctionFlags(node) & 2 /* Async */ ? transformAsyncFunctionBody(node) : ts.visitFunctionBody(node.body, visitor, context)); } function transformAsyncFunctionBody(node) { resumeLexicalEnvironment(); var original = ts.getOriginalNode(node, ts.isFunctionLike); var nodeType = original.type; var promiseConstructor = languageVersion < 2 /* ES2015 */ ? getPromiseConstructor(nodeType) : undefined; var isArrowFunction = node.kind === 188 /* ArrowFunction */; var hasLexicalArguments = (resolver.getNodeCheckFlags(node) & 8192 /* CaptureArguments */) !== 0; // An async function is emit as an outer function that calls an inner // generator function. To preserve lexical bindings, we pass the current // `this` and `arguments` objects to `__awaiter`. The generator function // passed to `__awaiter` is executed inside of the callback to the // promise constructor. if (!isArrowFunction) { var statements = []; var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor); statements.push(ts.createReturn(createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body, statementOffset)))); ts.addRange(statements, endLexicalEnvironment()); var block = ts.createBlock(statements, /*multiLine*/ true); ts.setTextRange(block, node.body); // Minor optimization, emit `_super` helper to capture `super` access in an arrow. // This step isn't needed if we eventually transform this to ES5. if (languageVersion >= 2 /* ES2015 */) { if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) { enableSubstitutionForAsyncMethodsWithSuper(); ts.addEmitHelper(block, ts.advancedAsyncSuperHelper); } else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) { enableSubstitutionForAsyncMethodsWithSuper(); ts.addEmitHelper(block, ts.asyncSuperHelper); } } return block; } else { var expression = createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, transformFunctionBodyWorker(node.body)); var declarations = endLexicalEnvironment(); if (ts.some(declarations)) { var block = ts.convertToFunctionBody(expression); return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(ts.concatenate(block.statements, declarations)), block.statements)); } return expression; } } function transformFunctionBodyWorker(body, start) { if (ts.isBlock(body)) { return ts.updateBlock(body, ts.visitLexicalEnvironment(body.statements, visitor, context, start)); } else { startLexicalEnvironment(); var visited = ts.convertToFunctionBody(ts.visitNode(body, visitor, ts.isConciseBody)); var declarations = endLexicalEnvironment(); return ts.updateBlock(visited, ts.setTextRange(ts.createNodeArray(ts.concatenate(visited.statements, declarations)), visited.statements)); } } function getPromiseConstructor(type) { var typeName = type && ts.getEntityNameFromTypeNode(type); if (typeName && ts.isEntityName(typeName)) { var serializationKind = resolver.getTypeReferenceSerializationKind(typeName); if (serializationKind === ts.TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue || serializationKind === ts.TypeReferenceSerializationKind.Unknown) { return typeName; } } return undefined; } function enableSubstitutionForAsyncMethodsWithSuper() { if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) { enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */; // We need to enable substitutions for call, property access, and element access // if we need to rewrite super calls. context.enableSubstitution(182 /* CallExpression */); context.enableSubstitution(180 /* PropertyAccessExpression */); context.enableSubstitution(181 /* ElementAccessExpression */); // We need to be notified when entering and exiting declarations that bind super. context.enableEmitNotification(230 /* ClassDeclaration */); context.enableEmitNotification(152 /* MethodDeclaration */); context.enableEmitNotification(154 /* GetAccessor */); context.enableEmitNotification(155 /* SetAccessor */); context.enableEmitNotification(153 /* Constructor */); } } /** * Hook for node emit. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ function onEmitNode(hint, node, emitCallback) { // If we need to support substitutions for `super` in an async method, // we should track it here. if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) { var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */); if (superContainerFlags !== enclosingSuperContainerFlags) { var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; enclosingSuperContainerFlags = superContainerFlags; previousOnEmitNode(hint, node, emitCallback); enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; return; } } previousOnEmitNode(hint, node, emitCallback); } /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) { return substituteExpression(node); } return node; } function substituteExpression(node) { switch (node.kind) { case 180 /* PropertyAccessExpression */: return substitutePropertyAccessExpression(node); case 181 /* ElementAccessExpression */: return substituteElementAccessExpression(node); case 182 /* CallExpression */: return substituteCallExpression(node); } return node; } function substitutePropertyAccessExpression(node) { if (node.expression.kind === 97 /* SuperKeyword */) { return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node); } return node; } function substituteElementAccessExpression(node) { if (node.expression.kind === 97 /* SuperKeyword */) { return createSuperAccessInAsyncMethod(node.argumentExpression, node); } return node; } function substituteCallExpression(node) { var expression = node.expression; if (ts.isSuperProperty(expression)) { var argumentExpression = ts.isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression); return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), /*typeArguments*/ undefined, [ ts.createThis() ].concat(node.arguments)); } return node; } function isSuperContainer(node) { var kind = node.kind; return kind === 230 /* ClassDeclaration */ || kind === 153 /* Constructor */ || kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */; } function createSuperAccessInAsyncMethod(argumentExpression, location) { if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) { return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression]), "value"), location); } else { return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression]), location); } } } ts.transformES2017 = transformES2017; var awaiterHelper = { name: "typescript:awaiter", scoped: false, priority: 5, text: "\n var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {\n return new (P || (P = Promise))(function (resolve, reject) {\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\n step((generator = generator.apply(thisArg, _arguments || [])).next());\n });\n };" }; function createAwaiterHelper(context, hasLexicalArguments, promiseConstructor, body) { context.requestEmitHelper(awaiterHelper); var generatorFunc = ts.createFunctionExpression( /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, body); // Mark this node as originally an async function (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */ | 524288 /* ReuseTempVariableScope */; return ts.createCall(ts.getHelperName("__awaiter"), /*typeArguments*/ undefined, [ ts.createThis(), hasLexicalArguments ? ts.createIdentifier("arguments") : ts.createVoidZero(), promiseConstructor ? ts.createExpressionFromEntityName(promiseConstructor) : ts.createVoidZero(), generatorFunc ]); } ts.asyncSuperHelper = { name: "typescript:async-super", scoped: true, text: "\n const _super = name => super[name];\n " }; ts.advancedAsyncSuperHelper = { name: "typescript:advanced-async-super", scoped: true, text: "\n const _super = (function (geti, seti) {\n const cache = Object.create(null);\n return name => cache[name] || (cache[name] = { get value() { return geti(name); }, set value(v) { seti(name, v); } });\n })(name => super[name], (name, value) => super[name] = value);\n " }; })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { var ESNextSubstitutionFlags; (function (ESNextSubstitutionFlags) { /** Enables substitutions for async methods with `super` calls. */ ESNextSubstitutionFlags[ESNextSubstitutionFlags["AsyncMethodsWithSuper"] = 1] = "AsyncMethodsWithSuper"; })(ESNextSubstitutionFlags || (ESNextSubstitutionFlags = {})); function transformESNext(context) { var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration; var resolver = context.getEmitResolver(); var compilerOptions = context.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var previousOnEmitNode = context.onEmitNode; context.onEmitNode = onEmitNode; var previousOnSubstituteNode = context.onSubstituteNode; context.onSubstituteNode = onSubstituteNode; var enabledSubstitutions; var enclosingFunctionFlags; var enclosingSuperContainerFlags = 0; return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } var visited = ts.visitEachChild(node, visitor, context); ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; } function visitor(node) { return visitorWorker(node, /*noDestructuringValue*/ false); } function visitorNoDestructuringValue(node) { return visitorWorker(node, /*noDestructuringValue*/ true); } function visitorNoAsyncModifier(node) { if (node.kind === 120 /* AsyncKeyword */) { return undefined; } return node; } function visitorWorker(node, noDestructuringValue) { if ((node.transformFlags & 8 /* ContainsESNext */) === 0) { return node; } switch (node.kind) { case 192 /* AwaitExpression */: return visitAwaitExpression(node); case 198 /* YieldExpression */: return visitYieldExpression(node); case 223 /* LabeledStatement */: return visitLabeledStatement(node); case 179 /* ObjectLiteralExpression */: return visitObjectLiteralExpression(node); case 195 /* BinaryExpression */: return visitBinaryExpression(node, noDestructuringValue); case 227 /* VariableDeclaration */: return visitVariableDeclaration(node); case 217 /* ForOfStatement */: return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined); case 215 /* ForStatement */: return visitForStatement(node); case 191 /* VoidExpression */: return visitVoidExpression(node); case 153 /* Constructor */: return visitConstructorDeclaration(node); case 152 /* MethodDeclaration */: return visitMethodDeclaration(node); case 154 /* GetAccessor */: return visitGetAccessorDeclaration(node); case 155 /* SetAccessor */: return visitSetAccessorDeclaration(node); case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 187 /* FunctionExpression */: return visitFunctionExpression(node); case 188 /* ArrowFunction */: return visitArrowFunction(node); case 147 /* Parameter */: return visitParameter(node); case 211 /* ExpressionStatement */: return visitExpressionStatement(node); case 186 /* ParenthesizedExpression */: return visitParenthesizedExpression(node, noDestructuringValue); case 264 /* CatchClause */: return visitCatchClause(node); default: return ts.visitEachChild(node, visitor, context); } } function visitAwaitExpression(node) { if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) { return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.visitNode(node.expression, visitor, ts.isExpression))), /*location*/ node), node); } return ts.visitEachChild(node, visitor, context); } function visitYieldExpression(node) { if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ && node.asteriskToken) { var expression = ts.visitNode(node.expression, visitor, ts.isExpression); return ts.setOriginalNode(ts.setTextRange(ts.createYield(createAwaitHelper(context, ts.updateYield(node, node.asteriskToken, createAsyncDelegatorHelper(context, createAsyncValuesHelper(context, expression, expression), expression)))), node), node); } return ts.visitEachChild(node, visitor, context); } function visitLabeledStatement(node) { if (enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */) { var statement = ts.unwrapInnermostStatementOfLabel(node); if (statement.kind === 217 /* ForOfStatement */ && statement.awaitModifier) { return visitForOfStatement(statement, node); } return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), node); } return ts.visitEachChild(node, visitor, context); } function chunkObjectLiteralElements(elements) { var chunkObject; var objects = []; for (var _i = 0, elements_3 = elements; _i < elements_3.length; _i++) { var e = elements_3[_i]; if (e.kind === 267 /* SpreadAssignment */) { if (chunkObject) { objects.push(ts.createObjectLiteral(chunkObject)); chunkObject = undefined; } var target = e.expression; objects.push(ts.visitNode(target, visitor, ts.isExpression)); } else { if (!chunkObject) { chunkObject = []; } if (e.kind === 265 /* PropertyAssignment */) { var p = e; chunkObject.push(ts.createPropertyAssignment(p.name, ts.visitNode(p.initializer, visitor, ts.isExpression))); } else { chunkObject.push(ts.visitNode(e, visitor, ts.isObjectLiteralElementLike)); } } } if (chunkObject) { objects.push(ts.createObjectLiteral(chunkObject)); } return objects; } function visitObjectLiteralExpression(node) { if (node.transformFlags & 1048576 /* ContainsObjectSpread */) { // spread elements emit like so: // non-spread elements are chunked together into object literals, and then all are passed to __assign: // { a, ...o, b } => __assign({a}, o, {b}); // If the first element is a spread element, then the first argument to __assign is {}: // { ...o, a, b, ...o2 } => __assign({}, o, {a, b}, o2) var objects = chunkObjectLiteralElements(node.properties); if (objects.length && objects[0].kind !== 179 /* ObjectLiteralExpression */) { objects.unshift(ts.createObjectLiteral()); } return createAssignHelper(context, objects); } return ts.visitEachChild(node, visitor, context); } function visitExpressionStatement(node) { return ts.visitEachChild(node, visitorNoDestructuringValue, context); } function visitParenthesizedExpression(node, noDestructuringValue) { return ts.visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context); } function visitCatchClause(node) { if (!node.variableDeclaration) { return ts.updateCatchClause(node, ts.createVariableDeclaration(ts.createTempVariable(/*recordTempVariable*/ undefined)), ts.visitNode(node.block, visitor, ts.isBlock)); } return ts.visitEachChild(node, visitor, context); } /** * Visits a BinaryExpression that contains a destructuring assignment. * * @param node A BinaryExpression node. */ function visitBinaryExpression(node, noDestructuringValue) { if (ts.isDestructuringAssignment(node) && node.left.transformFlags & 1048576 /* ContainsObjectRest */) { return ts.flattenDestructuringAssignment(node, visitor, context, 1 /* ObjectRest */, !noDestructuringValue); } else if (node.operatorToken.kind === 26 /* CommaToken */) { return ts.updateBinary(node, ts.visitNode(node.left, visitorNoDestructuringValue, ts.isExpression), ts.visitNode(node.right, noDestructuringValue ? visitorNoDestructuringValue : visitor, ts.isExpression)); } return ts.visitEachChild(node, visitor, context); } /** * Visits a VariableDeclaration node with a binding pattern. * * @param node A VariableDeclaration node. */ function visitVariableDeclaration(node) { // If we are here it is because the name contains a binding pattern with a rest somewhere in it. if (ts.isBindingPattern(node.name) && node.name.transformFlags & 1048576 /* ContainsObjectRest */) { return ts.flattenDestructuringBinding(node, visitor, context, 1 /* ObjectRest */); } return ts.visitEachChild(node, visitor, context); } function visitForStatement(node) { return ts.updateFor(node, ts.visitNode(node.initializer, visitorNoDestructuringValue, ts.isForInitializer), ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement)); } function visitVoidExpression(node) { return ts.visitEachChild(node, visitorNoDestructuringValue, context); } /** * Visits a ForOfStatement and converts it into a ES2015-compatible ForOfStatement. * * @param node A ForOfStatement. */ function visitForOfStatement(node, outermostLabeledStatement) { if (node.initializer.transformFlags & 1048576 /* ContainsObjectRest */) { node = transformForOfStatementWithObjectRest(node); } if (node.awaitModifier) { return transformForAwaitOfStatement(node, outermostLabeledStatement); } else { return ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement); } } function transformForOfStatementWithObjectRest(node) { var initializerWithoutParens = ts.skipParentheses(node.initializer); if (ts.isVariableDeclarationList(initializerWithoutParens) || ts.isAssignmentPattern(initializerWithoutParens)) { var bodyLocation = void 0; var statementsLocation = void 0; var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); var statements = [ts.createForOfBindingStatement(initializerWithoutParens, temp)]; if (ts.isBlock(node.statement)) { ts.addRange(statements, node.statement.statements); bodyLocation = node.statement; statementsLocation = node.statement.statements; } return ts.updateForOf(node, node.awaitModifier, ts.setTextRange(ts.createVariableDeclarationList([ ts.setTextRange(ts.createVariableDeclaration(temp), node.initializer) ], 1 /* Let */), node.initializer), node.expression, ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), /*multiLine*/ true), bodyLocation)); } return node; } function convertForOfStatementHead(node, boundValue) { var binding = ts.createForOfBindingStatement(node.initializer, boundValue); var bodyLocation; var statementsLocation; var statements = [ts.visitNode(binding, visitor, ts.isStatement)]; var statement = ts.visitNode(node.statement, visitor, ts.isStatement); if (ts.isBlock(statement)) { ts.addRange(statements, statement.statements); bodyLocation = statement; statementsLocation = statement.statements; } else { statements.push(statement); } return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */); } function createDownlevelAwait(expression) { return enclosingFunctionFlags & 1 /* Generator */ ? ts.createYield(/*asteriskToken*/ undefined, createAwaitHelper(context, expression)) : ts.createAwait(expression); } function transformForAwaitOfStatement(node, outermostLabeledStatement) { var expression = ts.visitNode(node.expression, visitor, ts.isExpression); var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined); var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined); var errorRecord = ts.createUniqueName("e"); var catchVariable = ts.getGeneratedNameForNode(errorRecord); var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined); var callValues = createAsyncValuesHelper(context, expression, /*location*/ node.expression); var callNext = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []); var getDone = ts.createPropertyAccess(result, "done"); var getValue = ts.createPropertyAccess(result, "value"); var callReturn = ts.createFunctionCall(returnMethod, iterator, []); hoistVariableDeclaration(errorRecord); hoistVariableDeclaration(returnMethod); var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor( /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([ ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, callValues), node.expression), ts.createVariableDeclaration(result) ]), node.expression), 2097152 /* NoHoisting */), /*condition*/ ts.createComma(ts.createAssignment(result, createDownlevelAwait(callNext)), ts.createLogicalNot(getDone)), /*incrementor*/ undefined, /*statement*/ convertForOfStatementHead(node, createDownlevelAwait(getValue))), /*location*/ node), 256 /* NoTokenTrailingSourceMaps */); return ts.createTry(ts.createBlock([ ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement) ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([ ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([ ts.createPropertyAssignment("error", catchVariable) ]))) ]), 1 /* SingleLine */)), ts.createBlock([ ts.createTry( /*tryBlock*/ ts.createBlock([ ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(getDone)), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(createDownlevelAwait(callReturn))), 1 /* SingleLine */) ]), /*catchClause*/ undefined, /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([ ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */) ]), 1 /* SingleLine */)) ])); } function visitParameter(node) { if (node.transformFlags & 1048576 /* ContainsObjectRest */) { // Binding patterns are converted into a generated name and are // evaluated inside the function body. return ts.updateParameter(node, /*decorators*/ undefined, /*modifiers*/ undefined, node.dotDotDotToken, ts.getGeneratedNameForNode(node), /*questionToken*/ undefined, /*type*/ undefined, ts.visitNode(node.initializer, visitor, ts.isExpression)); } return ts.visitEachChild(node, visitor, context); } function visitConstructorDeclaration(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = 0 /* Normal */; var updated = ts.updateConstructor(node, /*decorators*/ undefined, node.modifiers, ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitGetAccessorDeclaration(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = 0 /* Normal */; var updated = ts.updateGetAccessor(node, /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitSetAccessorDeclaration(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = 0 /* Normal */; var updated = ts.updateSetAccessor(node, /*decorators*/ undefined, node.modifiers, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitParameterList(node.parameters, visitor, context), transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitMethodDeclaration(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateMethod(node, /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */ ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier) : node.modifiers, enclosingFunctionFlags & 2 /* Async */ ? undefined : node.asteriskToken, ts.visitNode(node.name, visitor, ts.isPropertyName), ts.visitNode(/*questionToken*/ undefined, visitor, ts.isToken), /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitFunctionDeclaration(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateFunctionDeclaration(node, /*decorators*/ undefined, enclosingFunctionFlags & 1 /* Generator */ ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier) : node.modifiers, enclosingFunctionFlags & 2 /* Async */ ? undefined : node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitArrowFunction(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateArrowFunction(node, node.modifiers, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, node.equalsGreaterThanToken, transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function visitFunctionExpression(node) { var savedEnclosingFunctionFlags = enclosingFunctionFlags; enclosingFunctionFlags = ts.getFunctionFlags(node); var updated = ts.updateFunctionExpression(node, enclosingFunctionFlags & 1 /* Generator */ ? ts.visitNodes(node.modifiers, visitorNoAsyncModifier, ts.isModifier) : node.modifiers, enclosingFunctionFlags & 2 /* Async */ ? undefined : node.asteriskToken, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, enclosingFunctionFlags & 2 /* Async */ && enclosingFunctionFlags & 1 /* Generator */ ? transformAsyncGeneratorFunctionBody(node) : transformFunctionBody(node)); enclosingFunctionFlags = savedEnclosingFunctionFlags; return updated; } function transformAsyncGeneratorFunctionBody(node) { resumeLexicalEnvironment(); var statements = []; var statementOffset = ts.addPrologue(statements, node.body.statements, /*ensureUseStrict*/ false, visitor); appendObjectRestAssignmentsIfNeeded(statements, node); statements.push(ts.createReturn(createAsyncGeneratorHelper(context, ts.createFunctionExpression( /*modifiers*/ undefined, ts.createToken(39 /* AsteriskToken */), node.name && ts.getGeneratedNameForNode(node.name), /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, ts.updateBlock(node.body, ts.visitLexicalEnvironment(node.body.statements, visitor, context, statementOffset)))))); ts.addRange(statements, endLexicalEnvironment()); var block = ts.updateBlock(node.body, statements); // Minor optimization, emit `_super` helper to capture `super` access in an arrow. // This step isn't needed if we eventually transform this to ES5. if (languageVersion >= 2 /* ES2015 */) { if (resolver.getNodeCheckFlags(node) & 4096 /* AsyncMethodWithSuperBinding */) { enableSubstitutionForAsyncMethodsWithSuper(); ts.addEmitHelper(block, ts.advancedAsyncSuperHelper); } else if (resolver.getNodeCheckFlags(node) & 2048 /* AsyncMethodWithSuper */) { enableSubstitutionForAsyncMethodsWithSuper(); ts.addEmitHelper(block, ts.asyncSuperHelper); } } return block; } function transformFunctionBody(node) { resumeLexicalEnvironment(); var statementOffset = 0; var statements = []; var body = ts.visitNode(node.body, visitor, ts.isConciseBody); if (ts.isBlock(body)) { statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor); } ts.addRange(statements, appendObjectRestAssignmentsIfNeeded(/*statements*/ undefined, node)); var trailingStatements = endLexicalEnvironment(); if (statementOffset > 0 || ts.some(statements) || ts.some(trailingStatements)) { var block = ts.convertToFunctionBody(body, /*multiLine*/ true); ts.addRange(statements, block.statements.slice(statementOffset)); ts.addRange(statements, trailingStatements); return ts.updateBlock(block, ts.setTextRange(ts.createNodeArray(statements), block.statements)); } return body; } function appendObjectRestAssignmentsIfNeeded(statements, node) { for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) { var parameter = _a[_i]; if (parameter.transformFlags & 1048576 /* ContainsObjectRest */) { var temp = ts.getGeneratedNameForNode(parameter); var declarations = ts.flattenDestructuringBinding(parameter, visitor, context, 1 /* ObjectRest */, temp, /*doNotRecordTempVariablesInLine*/ false, /*skipInitializer*/ true); if (ts.some(declarations)) { var statement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList(declarations)); ts.setEmitFlags(statement, 1048576 /* CustomPrologue */); statements = ts.append(statements, statement); } } } return statements; } function enableSubstitutionForAsyncMethodsWithSuper() { if ((enabledSubstitutions & 1 /* AsyncMethodsWithSuper */) === 0) { enabledSubstitutions |= 1 /* AsyncMethodsWithSuper */; // We need to enable substitutions for call, property access, and element access // if we need to rewrite super calls. context.enableSubstitution(182 /* CallExpression */); context.enableSubstitution(180 /* PropertyAccessExpression */); context.enableSubstitution(181 /* ElementAccessExpression */); // We need to be notified when entering and exiting declarations that bind super. context.enableEmitNotification(230 /* ClassDeclaration */); context.enableEmitNotification(152 /* MethodDeclaration */); context.enableEmitNotification(154 /* GetAccessor */); context.enableEmitNotification(155 /* SetAccessor */); context.enableEmitNotification(153 /* Constructor */); } } /** * Called by the printer just before a node is printed. * * @param hint A hint as to the intended usage of the node. * @param node The node to be printed. * @param emitCallback The callback used to emit the node. */ function onEmitNode(hint, node, emitCallback) { // If we need to support substitutions for `super` in an async method, // we should track it here. if (enabledSubstitutions & 1 /* AsyncMethodsWithSuper */ && isSuperContainer(node)) { var superContainerFlags = resolver.getNodeCheckFlags(node) & (2048 /* AsyncMethodWithSuper */ | 4096 /* AsyncMethodWithSuperBinding */); if (superContainerFlags !== enclosingSuperContainerFlags) { var savedEnclosingSuperContainerFlags = enclosingSuperContainerFlags; enclosingSuperContainerFlags = superContainerFlags; previousOnEmitNode(hint, node, emitCallback); enclosingSuperContainerFlags = savedEnclosingSuperContainerFlags; return; } } previousOnEmitNode(hint, node, emitCallback); } /** * Hooks node substitutions. * * @param hint The context for the emitter. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (hint === 1 /* Expression */ && enclosingSuperContainerFlags) { return substituteExpression(node); } return node; } function substituteExpression(node) { switch (node.kind) { case 180 /* PropertyAccessExpression */: return substitutePropertyAccessExpression(node); case 181 /* ElementAccessExpression */: return substituteElementAccessExpression(node); case 182 /* CallExpression */: return substituteCallExpression(node); } return node; } function substitutePropertyAccessExpression(node) { if (node.expression.kind === 97 /* SuperKeyword */) { return createSuperAccessInAsyncMethod(ts.createLiteral(ts.idText(node.name)), node); } return node; } function substituteElementAccessExpression(node) { if (node.expression.kind === 97 /* SuperKeyword */) { return createSuperAccessInAsyncMethod(node.argumentExpression, node); } return node; } function substituteCallExpression(node) { var expression = node.expression; if (ts.isSuperProperty(expression)) { var argumentExpression = ts.isPropertyAccessExpression(expression) ? substitutePropertyAccessExpression(expression) : substituteElementAccessExpression(expression); return ts.createCall(ts.createPropertyAccess(argumentExpression, "call"), /*typeArguments*/ undefined, [ ts.createThis() ].concat(node.arguments)); } return node; } function isSuperContainer(node) { var kind = node.kind; return kind === 230 /* ClassDeclaration */ || kind === 153 /* Constructor */ || kind === 152 /* MethodDeclaration */ || kind === 154 /* GetAccessor */ || kind === 155 /* SetAccessor */; } function createSuperAccessInAsyncMethod(argumentExpression, location) { if (enclosingSuperContainerFlags & 4096 /* AsyncMethodWithSuperBinding */) { return ts.setTextRange(ts.createPropertyAccess(ts.createCall(ts.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression]), "value"), location); } else { return ts.setTextRange(ts.createCall(ts.createIdentifier("_super"), /*typeArguments*/ undefined, [argumentExpression]), location); } } } ts.transformESNext = transformESNext; var assignHelper = { name: "typescript:assign", scoped: false, priority: 1, text: "\n var __assign = (this && this.__assign) || Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };" }; function createAssignHelper(context, attributesSegments) { if (context.getCompilerOptions().target >= 2 /* ES2015 */) { return ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "assign"), /*typeArguments*/ undefined, attributesSegments); } context.requestEmitHelper(assignHelper); return ts.createCall(ts.getHelperName("__assign"), /*typeArguments*/ undefined, attributesSegments); } ts.createAssignHelper = createAssignHelper; var awaitHelper = { name: "typescript:await", scoped: false, text: "\n var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }\n " }; function createAwaitHelper(context, expression) { context.requestEmitHelper(awaitHelper); return ts.createCall(ts.getHelperName("__await"), /*typeArguments*/ undefined, [expression]); } var asyncGeneratorHelper = { name: "typescript:asyncGenerator", scoped: false, text: "\n var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\n function fulfill(value) { resume(\"next\", value); }\n function reject(value) { resume(\"throw\", value); }\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\n };\n " }; function createAsyncGeneratorHelper(context, generatorFunc) { context.requestEmitHelper(awaitHelper); context.requestEmitHelper(asyncGeneratorHelper); // Mark this node as originally an async function (generatorFunc.emitNode || (generatorFunc.emitNode = {})).flags |= 262144 /* AsyncFunctionBody */; return ts.createCall(ts.getHelperName("__asyncGenerator"), /*typeArguments*/ undefined, [ ts.createThis(), ts.createIdentifier("arguments"), generatorFunc ]); } var asyncDelegator = { name: "typescript:asyncDelegator", scoped: false, text: "\n var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {\n var i, p;\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\n function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; }; }\n };\n " }; function createAsyncDelegatorHelper(context, expression, location) { context.requestEmitHelper(awaitHelper); context.requestEmitHelper(asyncDelegator); return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncDelegator"), /*typeArguments*/ undefined, [expression]), location); } var asyncValues = { name: "typescript:asyncValues", scoped: false, text: "\n var __asyncValues = (this && this.__asyncIterator) || function (o) {\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\n var m = o[Symbol.asyncIterator];\n return m ? m.call(o) : typeof __values === \"function\" ? __values(o) : o[Symbol.iterator]();\n };\n " }; function createAsyncValuesHelper(context, expression, location) { context.requestEmitHelper(asyncValues); return ts.setTextRange(ts.createCall(ts.getHelperName("__asyncValues"), /*typeArguments*/ undefined, [expression]), location); } })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { function transformJsx(context) { var compilerOptions = context.getCompilerOptions(); var currentSourceFile; return transformSourceFile; /** * Transform JSX-specific syntax in a SourceFile. * * @param node A SourceFile node. */ function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } currentSourceFile = node; var visited = ts.visitEachChild(node, visitor, context); ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; } function visitor(node) { if (node.transformFlags & 4 /* ContainsJsx */) { return visitorWorker(node); } else { return node; } } function visitorWorker(node) { switch (node.kind) { case 250 /* JsxElement */: return visitJsxElement(node, /*isChild*/ false); case 251 /* JsxSelfClosingElement */: return visitJsxSelfClosingElement(node, /*isChild*/ false); case 254 /* JsxFragment */: return visitJsxFragment(node, /*isChild*/ false); case 260 /* JsxExpression */: return visitJsxExpression(node); default: return ts.visitEachChild(node, visitor, context); } } function transformJsxChildToExpression(node) { switch (node.kind) { case 10 /* JsxText */: return visitJsxText(node); case 260 /* JsxExpression */: return visitJsxExpression(node); case 250 /* JsxElement */: return visitJsxElement(node, /*isChild*/ true); case 251 /* JsxSelfClosingElement */: return visitJsxSelfClosingElement(node, /*isChild*/ true); case 254 /* JsxFragment */: return visitJsxFragment(node, /*isChild*/ true); default: ts.Debug.failBadSyntaxKind(node); return undefined; } } function visitJsxElement(node, isChild) { return visitJsxOpeningLikeElement(node.openingElement, node.children, isChild, /*location*/ node); } function visitJsxSelfClosingElement(node, isChild) { return visitJsxOpeningLikeElement(node, /*children*/ undefined, isChild, /*location*/ node); } function visitJsxFragment(node, isChild) { return visitJsxOpeningFragment(node.openingFragment, node.children, isChild, /*location*/ node); } function visitJsxOpeningLikeElement(node, children, isChild, location) { var tagName = getTagName(node); var objectProperties; var attrs = node.attributes.properties; if (attrs.length === 0) { // When there are no attributes, React wants "null" objectProperties = ts.createNull(); } else { // Map spans of JsxAttribute nodes into object literals and spans // of JsxSpreadAttribute nodes into expressions. var segments = ts.flatten(ts.spanMap(attrs, ts.isJsxSpreadAttribute, function (attrs, isSpread) { return isSpread ? ts.map(attrs, transformJsxSpreadAttributeToExpression) : ts.createObjectLiteral(ts.map(attrs, transformJsxAttributeToObjectLiteralElement)); })); if (ts.isJsxSpreadAttribute(attrs[0])) { // We must always emit at least one object literal before a spread // argument. segments.unshift(ts.createObjectLiteral()); } // Either emit one big object literal (no spread attribs), or // a call to the __assign helper. objectProperties = ts.singleOrUndefined(segments); if (!objectProperties) { objectProperties = ts.createAssignHelper(context, segments); } } var element = ts.createExpressionForJsxElement(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, tagName, objectProperties, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } return element; } function visitJsxOpeningFragment(node, children, isChild, location) { var element = ts.createExpressionForJsxFragment(context.getEmitResolver().getJsxFactoryEntity(), compilerOptions.reactNamespace, ts.mapDefined(children, transformJsxChildToExpression), node, location); if (isChild) { ts.startOnNewLine(element); } return element; } function transformJsxSpreadAttributeToExpression(node) { return ts.visitNode(node.expression, visitor, ts.isExpression); } function transformJsxAttributeToObjectLiteralElement(node) { var name = getAttributeName(node); var expression = transformJsxAttributeInitializer(node.initializer); return ts.createPropertyAssignment(name, expression); } function transformJsxAttributeInitializer(node) { if (node === undefined) { return ts.createTrue(); } else if (node.kind === 9 /* StringLiteral */) { // Always recreate the literal to escape any escape sequences or newlines which may be in the original jsx string and which // Need to be escaped to be handled correctly in a normal string var literal = ts.createLiteral(tryDecodeEntities(node.text) || node.text); literal.singleQuote = node.singleQuote !== undefined ? node.singleQuote : !ts.isStringDoubleQuoted(node, currentSourceFile); return ts.setTextRange(literal, node); } else if (node.kind === 260 /* JsxExpression */) { if (node.expression === undefined) { return ts.createTrue(); } return visitJsxExpression(node); } else { ts.Debug.failBadSyntaxKind(node); } } function visitJsxText(node) { var fixed = fixupWhitespaceAndDecodeEntities(ts.getTextOfNode(node, /*includeTrivia*/ true)); return fixed === undefined ? undefined : ts.createLiteral(fixed); } /** * JSX trims whitespace at the end and beginning of lines, except that the * start/end of a tag is considered a start/end of a line only if that line is * on the same line as the closing tag. See examples in * tests/cases/conformance/jsx/tsxReactEmitWhitespace.tsx * See also https://www.w3.org/TR/html4/struct/text.html#h-9.1 and https://www.w3.org/TR/CSS2/text.html#white-space-model * * An equivalent algorithm would be: * - If there is only one line, return it. * - If there is only whitespace (but multiple lines), return `undefined`. * - Split the text into lines. * - 'trimRight' the first line, 'trimLeft' the last line, 'trim' middle lines. * - Decode entities on each line (individually). * - Remove empty lines and join the rest with " ". */ function fixupWhitespaceAndDecodeEntities(text) { var acc; // First non-whitespace character on this line. var firstNonWhitespace = 0; // Last non-whitespace character on this line. var lastNonWhitespace = -1; // These initial values are special because the first line is: // firstNonWhitespace = 0 to indicate that we want leading whitsepace, // but lastNonWhitespace = -1 as a special flag to indicate that we *don't* include the line if it's all whitespace. for (var i = 0; i < text.length; i++) { var c = text.charCodeAt(i); if (ts.isLineBreak(c)) { // If we've seen any non-whitespace characters on this line, add the 'trim' of the line. // (lastNonWhitespace === -1 is a special flag to detect whether the first line is all whitespace.) if (firstNonWhitespace !== -1 && lastNonWhitespace !== -1) { acc = addLineOfJsxText(acc, text.substr(firstNonWhitespace, lastNonWhitespace - firstNonWhitespace + 1)); } // Reset firstNonWhitespace for the next line. // Don't bother to reset lastNonWhitespace because we ignore it if firstNonWhitespace = -1. firstNonWhitespace = -1; } else if (!ts.isWhiteSpaceSingleLine(c)) { lastNonWhitespace = i; if (firstNonWhitespace === -1) { firstNonWhitespace = i; } } } return firstNonWhitespace !== -1 // Last line had a non-whitespace character. Emit the 'trimLeft', meaning keep trailing whitespace. ? addLineOfJsxText(acc, text.substr(firstNonWhitespace)) // Last line was all whitespace, so ignore it : acc; } function addLineOfJsxText(acc, trimmedLine) { // We do not escape the string here as that is handled by the printer // when it emits the literal. We do, however, need to decode JSX entities. var decoded = decodeEntities(trimmedLine); return acc === undefined ? decoded : acc + " " + decoded; } /** * Replace entities like " ", "{", and "�" with the characters they encode. * See https://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references */ function decodeEntities(text) { return text.replace(/&((#((\d+)|x([\da-fA-F]+)))|(\w+));/g, function (match, _all, _number, _digits, decimal, hex, word) { if (decimal) { return String.fromCharCode(parseInt(decimal, 10)); } else if (hex) { return String.fromCharCode(parseInt(hex, 16)); } else { var ch = entities.get(word); // If this is not a valid entity, then just use `match` (replace it with itself, i.e. don't replace) return ch ? String.fromCharCode(ch) : match; } }); } /** Like `decodeEntities` but returns `undefined` if there were no entities to decode. */ function tryDecodeEntities(text) { var decoded = decodeEntities(text); return decoded === text ? undefined : decoded; } function getTagName(node) { if (node.kind === 250 /* JsxElement */) { return getTagName(node.openingElement); } else { var name = node.tagName; if (ts.isIdentifier(name) && ts.isIntrinsicJsxName(name.escapedText)) { return ts.createLiteral(ts.idText(name)); } else { return ts.createExpressionFromEntityName(name); } } } /** * Emit an attribute name, which is quoted if it needs to be quoted. Because * these emit into an object literal property name, we don't need to be worried * about keywords, just non-identifier characters */ function getAttributeName(node) { var name = node.name; var text = ts.idText(name); if (/^[A-Za-z_]\w*$/.test(text)) { return name; } else { return ts.createLiteral(text); } } function visitJsxExpression(node) { return ts.visitNode(node.expression, visitor, ts.isExpression); } } ts.transformJsx = transformJsx; var entities = ts.createMapFromTemplate({ quot: 0x0022, amp: 0x0026, apos: 0x0027, lt: 0x003C, gt: 0x003E, nbsp: 0x00A0, iexcl: 0x00A1, cent: 0x00A2, pound: 0x00A3, curren: 0x00A4, yen: 0x00A5, brvbar: 0x00A6, sect: 0x00A7, uml: 0x00A8, copy: 0x00A9, ordf: 0x00AA, laquo: 0x00AB, not: 0x00AC, shy: 0x00AD, reg: 0x00AE, macr: 0x00AF, deg: 0x00B0, plusmn: 0x00B1, sup2: 0x00B2, sup3: 0x00B3, acute: 0x00B4, micro: 0x00B5, para: 0x00B6, middot: 0x00B7, cedil: 0x00B8, sup1: 0x00B9, ordm: 0x00BA, raquo: 0x00BB, frac14: 0x00BC, frac12: 0x00BD, frac34: 0x00BE, iquest: 0x00BF, Agrave: 0x00C0, Aacute: 0x00C1, Acirc: 0x00C2, Atilde: 0x00C3, Auml: 0x00C4, Aring: 0x00C5, AElig: 0x00C6, Ccedil: 0x00C7, Egrave: 0x00C8, Eacute: 0x00C9, Ecirc: 0x00CA, Euml: 0x00CB, Igrave: 0x00CC, Iacute: 0x00CD, Icirc: 0x00CE, Iuml: 0x00CF, ETH: 0x00D0, Ntilde: 0x00D1, Ograve: 0x00D2, Oacute: 0x00D3, Ocirc: 0x00D4, Otilde: 0x00D5, Ouml: 0x00D6, times: 0x00D7, Oslash: 0x00D8, Ugrave: 0x00D9, Uacute: 0x00DA, Ucirc: 0x00DB, Uuml: 0x00DC, Yacute: 0x00DD, THORN: 0x00DE, szlig: 0x00DF, agrave: 0x00E0, aacute: 0x00E1, acirc: 0x00E2, atilde: 0x00E3, auml: 0x00E4, aring: 0x00E5, aelig: 0x00E6, ccedil: 0x00E7, egrave: 0x00E8, eacute: 0x00E9, ecirc: 0x00EA, euml: 0x00EB, igrave: 0x00EC, iacute: 0x00ED, icirc: 0x00EE, iuml: 0x00EF, eth: 0x00F0, ntilde: 0x00F1, ograve: 0x00F2, oacute: 0x00F3, ocirc: 0x00F4, otilde: 0x00F5, ouml: 0x00F6, divide: 0x00F7, oslash: 0x00F8, ugrave: 0x00F9, uacute: 0x00FA, ucirc: 0x00FB, uuml: 0x00FC, yacute: 0x00FD, thorn: 0x00FE, yuml: 0x00FF, OElig: 0x0152, oelig: 0x0153, Scaron: 0x0160, scaron: 0x0161, Yuml: 0x0178, fnof: 0x0192, circ: 0x02C6, tilde: 0x02DC, Alpha: 0x0391, Beta: 0x0392, Gamma: 0x0393, Delta: 0x0394, Epsilon: 0x0395, Zeta: 0x0396, Eta: 0x0397, Theta: 0x0398, Iota: 0x0399, Kappa: 0x039A, Lambda: 0x039B, Mu: 0x039C, Nu: 0x039D, Xi: 0x039E, Omicron: 0x039F, Pi: 0x03A0, Rho: 0x03A1, Sigma: 0x03A3, Tau: 0x03A4, Upsilon: 0x03A5, Phi: 0x03A6, Chi: 0x03A7, Psi: 0x03A8, Omega: 0x03A9, alpha: 0x03B1, beta: 0x03B2, gamma: 0x03B3, delta: 0x03B4, epsilon: 0x03B5, zeta: 0x03B6, eta: 0x03B7, theta: 0x03B8, iota: 0x03B9, kappa: 0x03BA, lambda: 0x03BB, mu: 0x03BC, nu: 0x03BD, xi: 0x03BE, omicron: 0x03BF, pi: 0x03C0, rho: 0x03C1, sigmaf: 0x03C2, sigma: 0x03C3, tau: 0x03C4, upsilon: 0x03C5, phi: 0x03C6, chi: 0x03C7, psi: 0x03C8, omega: 0x03C9, thetasym: 0x03D1, upsih: 0x03D2, piv: 0x03D6, ensp: 0x2002, emsp: 0x2003, thinsp: 0x2009, zwnj: 0x200C, zwj: 0x200D, lrm: 0x200E, rlm: 0x200F, ndash: 0x2013, mdash: 0x2014, lsquo: 0x2018, rsquo: 0x2019, sbquo: 0x201A, ldquo: 0x201C, rdquo: 0x201D, bdquo: 0x201E, dagger: 0x2020, Dagger: 0x2021, bull: 0x2022, hellip: 0x2026, permil: 0x2030, prime: 0x2032, Prime: 0x2033, lsaquo: 0x2039, rsaquo: 0x203A, oline: 0x203E, frasl: 0x2044, euro: 0x20AC, image: 0x2111, weierp: 0x2118, real: 0x211C, trade: 0x2122, alefsym: 0x2135, larr: 0x2190, uarr: 0x2191, rarr: 0x2192, darr: 0x2193, harr: 0x2194, crarr: 0x21B5, lArr: 0x21D0, uArr: 0x21D1, rArr: 0x21D2, dArr: 0x21D3, hArr: 0x21D4, forall: 0x2200, part: 0x2202, exist: 0x2203, empty: 0x2205, nabla: 0x2207, isin: 0x2208, notin: 0x2209, ni: 0x220B, prod: 0x220F, sum: 0x2211, minus: 0x2212, lowast: 0x2217, radic: 0x221A, prop: 0x221D, infin: 0x221E, ang: 0x2220, and: 0x2227, or: 0x2228, cap: 0x2229, cup: 0x222A, int: 0x222B, there4: 0x2234, sim: 0x223C, cong: 0x2245, asymp: 0x2248, ne: 0x2260, equiv: 0x2261, le: 0x2264, ge: 0x2265, sub: 0x2282, sup: 0x2283, nsub: 0x2284, sube: 0x2286, supe: 0x2287, oplus: 0x2295, otimes: 0x2297, perp: 0x22A5, sdot: 0x22C5, lceil: 0x2308, rceil: 0x2309, lfloor: 0x230A, rfloor: 0x230B, lang: 0x2329, rang: 0x232A, loz: 0x25CA, spades: 0x2660, clubs: 0x2663, hearts: 0x2665, diams: 0x2666 }); })(ts || (ts = {})); /// /// /*@internal*/ var ts; (function (ts) { function transformES2016(context) { var hoistVariableDeclaration = context.hoistVariableDeclaration; return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } return ts.visitEachChild(node, visitor, context); } function visitor(node) { if ((node.transformFlags & 32 /* ContainsES2016 */) === 0) { return node; } switch (node.kind) { case 195 /* BinaryExpression */: return visitBinaryExpression(node); default: return ts.visitEachChild(node, visitor, context); } } function visitBinaryExpression(node) { switch (node.operatorToken.kind) { case 62 /* AsteriskAsteriskEqualsToken */: return visitExponentiationAssignmentExpression(node); case 40 /* AsteriskAsteriskToken */: return visitExponentiationExpression(node); default: return ts.visitEachChild(node, visitor, context); } } function visitExponentiationAssignmentExpression(node) { var target; var value; var left = ts.visitNode(node.left, visitor, ts.isExpression); var right = ts.visitNode(node.right, visitor, ts.isExpression); if (ts.isElementAccessExpression(left)) { // Transforms `a[x] **= b` into `(_a = a)[_x = x] = Math.pow(_a[_x], b)` var expressionTemp = ts.createTempVariable(hoistVariableDeclaration); var argumentExpressionTemp = ts.createTempVariable(hoistVariableDeclaration); target = ts.setTextRange(ts.createElementAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), ts.setTextRange(ts.createAssignment(argumentExpressionTemp, left.argumentExpression), left.argumentExpression)), left); value = ts.setTextRange(ts.createElementAccess(expressionTemp, argumentExpressionTemp), left); } else if (ts.isPropertyAccessExpression(left)) { // Transforms `a.x **= b` into `(_a = a).x = Math.pow(_a.x, b)` var expressionTemp = ts.createTempVariable(hoistVariableDeclaration); target = ts.setTextRange(ts.createPropertyAccess(ts.setTextRange(ts.createAssignment(expressionTemp, left.expression), left.expression), left.name), left); value = ts.setTextRange(ts.createPropertyAccess(expressionTemp, left.name), left); } else { // Transforms `a **= b` into `a = Math.pow(a, b)` target = left; value = left; } return ts.setTextRange(ts.createAssignment(target, ts.createMathPow(value, right, /*location*/ node)), node); } function visitExponentiationExpression(node) { // Transforms `a ** b` into `Math.pow(a, b)` var left = ts.visitNode(node.left, visitor, ts.isExpression); var right = ts.visitNode(node.right, visitor, ts.isExpression); return ts.createMathPow(left, right, /*location*/ node); } } ts.transformES2016 = transformES2016; })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { var ES2015SubstitutionFlags; (function (ES2015SubstitutionFlags) { /** Enables substitutions for captured `this` */ ES2015SubstitutionFlags[ES2015SubstitutionFlags["CapturedThis"] = 1] = "CapturedThis"; /** Enables substitutions for block-scoped bindings. */ ES2015SubstitutionFlags[ES2015SubstitutionFlags["BlockScopedBindings"] = 2] = "BlockScopedBindings"; })(ES2015SubstitutionFlags || (ES2015SubstitutionFlags = {})); var CopyDirection; (function (CopyDirection) { CopyDirection[CopyDirection["ToOriginal"] = 0] = "ToOriginal"; CopyDirection[CopyDirection["ToOutParameter"] = 1] = "ToOutParameter"; })(CopyDirection || (CopyDirection = {})); var Jump; (function (Jump) { Jump[Jump["Break"] = 2] = "Break"; Jump[Jump["Continue"] = 4] = "Continue"; Jump[Jump["Return"] = 8] = "Return"; })(Jump || (Jump = {})); var SuperCaptureResult; (function (SuperCaptureResult) { /** * A capture may have been added for calls to 'super', but * the caller should emit subsequent statements normally. */ SuperCaptureResult[SuperCaptureResult["NoReplacement"] = 0] = "NoReplacement"; /** * A call to 'super()' got replaced with a capturing statement like: * * var _this = _super.call(...) || this; * * Callers should skip the current statement. */ SuperCaptureResult[SuperCaptureResult["ReplaceSuperCapture"] = 1] = "ReplaceSuperCapture"; /** * A call to 'super()' got replaced with a capturing statement like: * * return _super.call(...) || this; * * Callers should skip the current statement and avoid any returns of '_this'. */ SuperCaptureResult[SuperCaptureResult["ReplaceWithReturn"] = 2] = "ReplaceWithReturn"; })(SuperCaptureResult || (SuperCaptureResult = {})); // Facts we track as we traverse the tree var HierarchyFacts; (function (HierarchyFacts) { HierarchyFacts[HierarchyFacts["None"] = 0] = "None"; // // Ancestor facts // HierarchyFacts[HierarchyFacts["Function"] = 1] = "Function"; HierarchyFacts[HierarchyFacts["ArrowFunction"] = 2] = "ArrowFunction"; HierarchyFacts[HierarchyFacts["AsyncFunctionBody"] = 4] = "AsyncFunctionBody"; HierarchyFacts[HierarchyFacts["NonStaticClassElement"] = 8] = "NonStaticClassElement"; HierarchyFacts[HierarchyFacts["CapturesThis"] = 16] = "CapturesThis"; HierarchyFacts[HierarchyFacts["ExportedVariableStatement"] = 32] = "ExportedVariableStatement"; HierarchyFacts[HierarchyFacts["TopLevel"] = 64] = "TopLevel"; HierarchyFacts[HierarchyFacts["Block"] = 128] = "Block"; HierarchyFacts[HierarchyFacts["IterationStatement"] = 256] = "IterationStatement"; HierarchyFacts[HierarchyFacts["IterationStatementBlock"] = 512] = "IterationStatementBlock"; HierarchyFacts[HierarchyFacts["ForStatement"] = 1024] = "ForStatement"; HierarchyFacts[HierarchyFacts["ForInOrForOfStatement"] = 2048] = "ForInOrForOfStatement"; HierarchyFacts[HierarchyFacts["ConstructorWithCapturedSuper"] = 4096] = "ConstructorWithCapturedSuper"; HierarchyFacts[HierarchyFacts["ComputedPropertyName"] = 8192] = "ComputedPropertyName"; // NOTE: do not add more ancestor flags without also updating AncestorFactsMask below. // // Ancestor masks // HierarchyFacts[HierarchyFacts["AncestorFactsMask"] = 16383] = "AncestorFactsMask"; // We are always in *some* kind of block scope, but only specific block-scope containers are // top-level or Blocks. HierarchyFacts[HierarchyFacts["BlockScopeIncludes"] = 0] = "BlockScopeIncludes"; HierarchyFacts[HierarchyFacts["BlockScopeExcludes"] = 4032] = "BlockScopeExcludes"; // A source file is a top-level block scope. HierarchyFacts[HierarchyFacts["SourceFileIncludes"] = 64] = "SourceFileIncludes"; HierarchyFacts[HierarchyFacts["SourceFileExcludes"] = 3968] = "SourceFileExcludes"; // Functions, methods, and accessors are both new lexical scopes and new block scopes. HierarchyFacts[HierarchyFacts["FunctionIncludes"] = 65] = "FunctionIncludes"; HierarchyFacts[HierarchyFacts["FunctionExcludes"] = 16286] = "FunctionExcludes"; HierarchyFacts[HierarchyFacts["AsyncFunctionBodyIncludes"] = 69] = "AsyncFunctionBodyIncludes"; HierarchyFacts[HierarchyFacts["AsyncFunctionBodyExcludes"] = 16278] = "AsyncFunctionBodyExcludes"; // Arrow functions are lexically scoped to their container, but are new block scopes. HierarchyFacts[HierarchyFacts["ArrowFunctionIncludes"] = 66] = "ArrowFunctionIncludes"; HierarchyFacts[HierarchyFacts["ArrowFunctionExcludes"] = 16256] = "ArrowFunctionExcludes"; // Constructors are both new lexical scopes and new block scopes. Constructors are also // always considered non-static members of a class. HierarchyFacts[HierarchyFacts["ConstructorIncludes"] = 73] = "ConstructorIncludes"; HierarchyFacts[HierarchyFacts["ConstructorExcludes"] = 16278] = "ConstructorExcludes"; // 'do' and 'while' statements are not block scopes. We track that the subtree is contained // within an IterationStatement to indicate whether the embedded statement is an // IterationStatementBlock. HierarchyFacts[HierarchyFacts["DoOrWhileStatementIncludes"] = 256] = "DoOrWhileStatementIncludes"; HierarchyFacts[HierarchyFacts["DoOrWhileStatementExcludes"] = 0] = "DoOrWhileStatementExcludes"; // 'for' statements are new block scopes and have special handling for 'let' declarations. HierarchyFacts[HierarchyFacts["ForStatementIncludes"] = 1280] = "ForStatementIncludes"; HierarchyFacts[HierarchyFacts["ForStatementExcludes"] = 3008] = "ForStatementExcludes"; // 'for-in' and 'for-of' statements are new block scopes and have special handling for // 'let' declarations. HierarchyFacts[HierarchyFacts["ForInOrForOfStatementIncludes"] = 2304] = "ForInOrForOfStatementIncludes"; HierarchyFacts[HierarchyFacts["ForInOrForOfStatementExcludes"] = 1984] = "ForInOrForOfStatementExcludes"; // Blocks (other than function bodies) are new block scopes. HierarchyFacts[HierarchyFacts["BlockIncludes"] = 128] = "BlockIncludes"; HierarchyFacts[HierarchyFacts["BlockExcludes"] = 3904] = "BlockExcludes"; HierarchyFacts[HierarchyFacts["IterationStatementBlockIncludes"] = 512] = "IterationStatementBlockIncludes"; HierarchyFacts[HierarchyFacts["IterationStatementBlockExcludes"] = 4032] = "IterationStatementBlockExcludes"; // Computed property names track subtree flags differently than their containing members. HierarchyFacts[HierarchyFacts["ComputedPropertyNameIncludes"] = 8192] = "ComputedPropertyNameIncludes"; HierarchyFacts[HierarchyFacts["ComputedPropertyNameExcludes"] = 0] = "ComputedPropertyNameExcludes"; // // Subtree facts // HierarchyFacts[HierarchyFacts["NewTarget"] = 16384] = "NewTarget"; HierarchyFacts[HierarchyFacts["NewTargetInComputedPropertyName"] = 32768] = "NewTargetInComputedPropertyName"; // // Subtree masks // HierarchyFacts[HierarchyFacts["SubtreeFactsMask"] = -16384] = "SubtreeFactsMask"; HierarchyFacts[HierarchyFacts["PropagateNewTargetMask"] = 49152] = "PropagateNewTargetMask"; })(HierarchyFacts || (HierarchyFacts = {})); function transformES2015(context) { var startLexicalEnvironment = context.startLexicalEnvironment, resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration; var compilerOptions = context.getCompilerOptions(); var resolver = context.getEmitResolver(); var previousOnSubstituteNode = context.onSubstituteNode; var previousOnEmitNode = context.onEmitNode; context.onEmitNode = onEmitNode; context.onSubstituteNode = onSubstituteNode; var currentSourceFile; var currentText; var hierarchyFacts; var taggedTemplateStringDeclarations; function recordTaggedTemplateString(temp) { taggedTemplateStringDeclarations = ts.append(taggedTemplateStringDeclarations, ts.createVariableDeclaration(temp)); } /** * Used to track if we are emitting body of the converted loop */ var convertedLoopState; /** * Keeps track of whether substitutions have been enabled for specific cases. * They are persisted between each SourceFile transformation and should not * be reset. */ var enabledSubstitutions; return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } currentSourceFile = node; currentText = node.text; var visited = visitSourceFile(node); ts.addEmitHelpers(visited, context.readEmitHelpers()); currentSourceFile = undefined; currentText = undefined; taggedTemplateStringDeclarations = undefined; hierarchyFacts = 0 /* None */; return visited; } /** * Sets the `HierarchyFacts` for this node prior to visiting this node's subtree, returning the facts set prior to modification. * @param excludeFacts The existing `HierarchyFacts` to reset before visiting the subtree. * @param includeFacts The new `HierarchyFacts` to set before visiting the subtree. */ function enterSubtree(excludeFacts, includeFacts) { var ancestorFacts = hierarchyFacts; hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & 16383 /* AncestorFactsMask */; return ancestorFacts; } /** * Restores the `HierarchyFacts` for this node's ancestor after visiting this node's * subtree, propagating specific facts from the subtree. * @param ancestorFacts The `HierarchyFacts` of the ancestor to restore after visiting the subtree. * @param excludeFacts The existing `HierarchyFacts` of the subtree that should not be propagated. * @param includeFacts The new `HierarchyFacts` of the subtree that should be propagated. */ function exitSubtree(ancestorFacts, excludeFacts, includeFacts) { hierarchyFacts = (hierarchyFacts & ~excludeFacts | includeFacts) & -16384 /* SubtreeFactsMask */ | ancestorFacts; } function isReturnVoidStatementInConstructorWithCapturedSuper(node) { return hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && node.kind === 220 /* ReturnStatement */ && !node.expression; } function shouldVisitNode(node) { return (node.transformFlags & 128 /* ContainsES2015 */) !== 0 || convertedLoopState !== undefined || (hierarchyFacts & 4096 /* ConstructorWithCapturedSuper */ && (ts.isStatement(node) || (node.kind === 208 /* Block */))) || (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false) && shouldConvertIterationStatementBody(node)) || (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) !== 0; } function visitor(node) { if (shouldVisitNode(node)) { return visitJavaScript(node); } else { return node; } } function functionBodyVisitor(node) { if (shouldVisitNode(node)) { return visitBlock(node, /*isFunctionBody*/ true); } return node; } function callExpressionVisitor(node) { if (node.kind === 97 /* SuperKeyword */) { return visitSuperKeyword(/*isExpressionOfCall*/ true); } return visitor(node); } function visitJavaScript(node) { switch (node.kind) { case 115 /* StaticKeyword */: return undefined; // elide static keyword case 230 /* ClassDeclaration */: return visitClassDeclaration(node); case 200 /* ClassExpression */: return visitClassExpression(node); case 147 /* Parameter */: return visitParameter(node); case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 188 /* ArrowFunction */: return visitArrowFunction(node); case 187 /* FunctionExpression */: return visitFunctionExpression(node); case 227 /* VariableDeclaration */: return visitVariableDeclaration(node); case 71 /* Identifier */: return visitIdentifier(node); case 228 /* VariableDeclarationList */: return visitVariableDeclarationList(node); case 222 /* SwitchStatement */: return visitSwitchStatement(node); case 236 /* CaseBlock */: return visitCaseBlock(node); case 208 /* Block */: return visitBlock(node, /*isFunctionBody*/ false); case 219 /* BreakStatement */: case 218 /* ContinueStatement */: return visitBreakOrContinueStatement(node); case 223 /* LabeledStatement */: return visitLabeledStatement(node); case 213 /* DoStatement */: case 214 /* WhileStatement */: return visitDoOrWhileStatement(node, /*outermostLabeledStatement*/ undefined); case 215 /* ForStatement */: return visitForStatement(node, /*outermostLabeledStatement*/ undefined); case 216 /* ForInStatement */: return visitForInStatement(node, /*outermostLabeledStatement*/ undefined); case 217 /* ForOfStatement */: return visitForOfStatement(node, /*outermostLabeledStatement*/ undefined); case 211 /* ExpressionStatement */: return visitExpressionStatement(node); case 179 /* ObjectLiteralExpression */: return visitObjectLiteralExpression(node); case 264 /* CatchClause */: return visitCatchClause(node); case 266 /* ShorthandPropertyAssignment */: return visitShorthandPropertyAssignment(node); case 145 /* ComputedPropertyName */: return visitComputedPropertyName(node); case 178 /* ArrayLiteralExpression */: return visitArrayLiteralExpression(node); case 182 /* CallExpression */: return visitCallExpression(node); case 183 /* NewExpression */: return visitNewExpression(node); case 186 /* ParenthesizedExpression */: return visitParenthesizedExpression(node, /*needsDestructuringValue*/ true); case 195 /* BinaryExpression */: return visitBinaryExpression(node, /*needsDestructuringValue*/ true); case 13 /* NoSubstitutionTemplateLiteral */: case 14 /* TemplateHead */: case 15 /* TemplateMiddle */: case 16 /* TemplateTail */: return visitTemplateLiteral(node); case 9 /* StringLiteral */: return visitStringLiteral(node); case 8 /* NumericLiteral */: return visitNumericLiteral(node); case 184 /* TaggedTemplateExpression */: return visitTaggedTemplateExpression(node); case 197 /* TemplateExpression */: return visitTemplateExpression(node); case 198 /* YieldExpression */: return visitYieldExpression(node); case 199 /* SpreadElement */: return visitSpreadElement(node); case 97 /* SuperKeyword */: return visitSuperKeyword(/*isExpressionOfCall*/ false); case 99 /* ThisKeyword */: return visitThisKeyword(node); case 205 /* MetaProperty */: return visitMetaProperty(node); case 152 /* MethodDeclaration */: return visitMethodDeclaration(node); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return visitAccessorDeclaration(node); case 209 /* VariableStatement */: return visitVariableStatement(node); case 220 /* ReturnStatement */: return visitReturnStatement(node); default: return ts.visitEachChild(node, visitor, context); } } function visitSourceFile(node) { var ancestorFacts = enterSubtree(3968 /* SourceFileExcludes */, 64 /* SourceFileIncludes */); var statements = []; startLexicalEnvironment(); var statementOffset = ts.addStandardPrologue(statements, node.statements, /*ensureUseStrict*/ false); addCaptureThisForNodeIfNeeded(statements, node); statementOffset = ts.addCustomPrologue(statements, node.statements, statementOffset, visitor); ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset)); if (taggedTemplateStringDeclarations) { statements.push(ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList(taggedTemplateStringDeclarations))); } ts.addRange(statements, endLexicalEnvironment()); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements)); } function visitSwitchStatement(node) { if (convertedLoopState !== undefined) { var savedAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps; // for switch statement allow only non-labeled break convertedLoopState.allowedNonLabeledJumps |= 2 /* Break */; var result = ts.visitEachChild(node, visitor, context); convertedLoopState.allowedNonLabeledJumps = savedAllowedNonLabeledJumps; return result; } return ts.visitEachChild(node, visitor, context); } function visitCaseBlock(node) { var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */); var updated = ts.visitEachChild(node, visitor, context); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } function returnCapturedThis(node) { return ts.setOriginalNode(ts.createReturn(ts.createIdentifier("_this")), node); } function visitReturnStatement(node) { if (convertedLoopState) { convertedLoopState.nonLocalJumps |= 8 /* Return */; if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) { node = returnCapturedThis(node); } return ts.createReturn(ts.createObjectLiteral([ ts.createPropertyAssignment(ts.createIdentifier("value"), node.expression ? ts.visitNode(node.expression, visitor, ts.isExpression) : ts.createVoidZero()) ])); } else if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) { return returnCapturedThis(node); } return ts.visitEachChild(node, visitor, context); } function visitThisKeyword(node) { if (convertedLoopState) { if (hierarchyFacts & 2 /* ArrowFunction */) { // if the enclosing function is an ArrowFunction then we use the captured 'this' keyword. convertedLoopState.containsLexicalThis = true; return node; } return convertedLoopState.thisName || (convertedLoopState.thisName = ts.createUniqueName("this")); } return node; } function visitIdentifier(node) { if (!convertedLoopState) { return node; } if (ts.isGeneratedIdentifier(node)) { return node; } if (node.escapedText !== "arguments" || !resolver.isArgumentsLocalBinding(node)) { return node; } return convertedLoopState.argumentsName || (convertedLoopState.argumentsName = ts.createUniqueName("arguments")); } function visitBreakOrContinueStatement(node) { if (convertedLoopState) { // check if we can emit break/continue as is // it is possible if either // - break/continue is labeled and label is located inside the converted loop // - break/continue is non-labeled and located in non-converted loop/switch statement var jump = node.kind === 219 /* BreakStatement */ ? 2 /* Break */ : 4 /* Continue */; var canUseBreakOrContinue = (node.label && convertedLoopState.labels && convertedLoopState.labels.get(ts.idText(node.label))) || (!node.label && (convertedLoopState.allowedNonLabeledJumps & jump)); if (!canUseBreakOrContinue) { var labelMarker = void 0; if (!node.label) { if (node.kind === 219 /* BreakStatement */) { convertedLoopState.nonLocalJumps |= 2 /* Break */; labelMarker = "break"; } else { convertedLoopState.nonLocalJumps |= 4 /* Continue */; // note: return value is emitted only to simplify debugging, call to converted loop body does not do any dispatching on it. labelMarker = "continue"; } } else { if (node.kind === 219 /* BreakStatement */) { labelMarker = "break-" + node.label.escapedText; setLabeledJump(convertedLoopState, /*isBreak*/ true, ts.idText(node.label), labelMarker); } else { labelMarker = "continue-" + node.label.escapedText; setLabeledJump(convertedLoopState, /*isBreak*/ false, ts.idText(node.label), labelMarker); } } var returnExpression = ts.createLiteral(labelMarker); if (convertedLoopState.loopOutParameters.length) { var outParams = convertedLoopState.loopOutParameters; var expr = void 0; for (var i = 0; i < outParams.length; i++) { var copyExpr = copyOutParameter(outParams[i], 1 /* ToOutParameter */); if (i === 0) { expr = copyExpr; } else { expr = ts.createBinary(expr, 26 /* CommaToken */, copyExpr); } } returnExpression = ts.createBinary(expr, 26 /* CommaToken */, returnExpression); } return ts.createReturn(returnExpression); } } return ts.visitEachChild(node, visitor, context); } /** * Visits a ClassDeclaration and transforms it into a variable statement. * * @param node A ClassDeclaration node. */ function visitClassDeclaration(node) { // [source] // class C { } // // [output] // var C = (function () { // function C() { // } // return C; // }()); var variable = ts.createVariableDeclaration(ts.getLocalName(node, /*allowComments*/ true), /*type*/ undefined, transformClassLikeDeclarationToExpression(node)); ts.setOriginalNode(variable, node); var statements = []; var statement = ts.createVariableStatement(/*modifiers*/ undefined, ts.createVariableDeclarationList([variable])); ts.setOriginalNode(statement, node); ts.setTextRange(statement, node); ts.startOnNewLine(statement); statements.push(statement); // Add an `export default` statement for default exports (for `--target es5 --module es6`) if (ts.hasModifier(node, 1 /* Export */)) { var exportStatement = ts.hasModifier(node, 512 /* Default */) ? ts.createExportDefault(ts.getLocalName(node)) : ts.createExternalModuleExport(ts.getLocalName(node)); ts.setOriginalNode(exportStatement, statement); statements.push(exportStatement); } var emitFlags = ts.getEmitFlags(node); if ((emitFlags & 4194304 /* HasEndOfDeclarationMarker */) === 0) { // Add a DeclarationMarker as a marker for the end of the declaration statements.push(ts.createEndOfDeclarationMarker(node)); ts.setEmitFlags(statement, emitFlags | 4194304 /* HasEndOfDeclarationMarker */); } return ts.singleOrMany(statements); } /** * Visits a ClassExpression and transforms it into an expression. * * @param node A ClassExpression node. */ function visitClassExpression(node) { // [source] // C = class { } // // [output] // C = (function () { // function class_1() { // } // return class_1; // }()) return transformClassLikeDeclarationToExpression(node); } /** * Transforms a ClassExpression or ClassDeclaration into an expression. * * @param node A ClassExpression or ClassDeclaration node. */ function transformClassLikeDeclarationToExpression(node) { // [source] // class C extends D { // constructor() {} // method() {} // get prop() {} // set prop(v) {} // } // // [output] // (function (_super) { // __extends(C, _super); // function C() { // } // C.prototype.method = function () {} // Object.defineProperty(C.prototype, "prop", { // get: function() {}, // set: function() {}, // enumerable: true, // configurable: true // }); // return C; // }(D)) if (node.name) { enableSubstitutionsForBlockScopedBindings(); } var extendsClauseElement = ts.getClassExtendsHeritageClauseElement(node); var classFunction = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, extendsClauseElement ? [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [], /*type*/ undefined, transformClassBody(node, extendsClauseElement)); // To preserve the behavior of the old emitter, we explicitly indent // the body of the function here if it was requested in an earlier // transformation. ts.setEmitFlags(classFunction, (ts.getEmitFlags(node) & 65536 /* Indented */) | 524288 /* ReuseTempVariableScope */); // "inner" and "outer" below are added purely to preserve source map locations from // the old emitter var inner = ts.createPartiallyEmittedExpression(classFunction); inner.end = node.end; ts.setEmitFlags(inner, 1536 /* NoComments */); var outer = ts.createPartiallyEmittedExpression(inner); outer.end = ts.skipTrivia(currentText, node.pos); ts.setEmitFlags(outer, 1536 /* NoComments */); var result = ts.createParen(ts.createCall(outer, /*typeArguments*/ undefined, extendsClauseElement ? [ts.visitNode(extendsClauseElement.expression, visitor, ts.isExpression)] : [])); ts.addSyntheticLeadingComment(result, 3 /* MultiLineCommentTrivia */, "* @class "); return result; } /** * Transforms a ClassExpression or ClassDeclaration into a function body. * * @param node A ClassExpression or ClassDeclaration node. * @param extendsClauseElement The expression for the class `extends` clause. */ function transformClassBody(node, extendsClauseElement) { var statements = []; startLexicalEnvironment(); addExtendsHelperIfNeeded(statements, node, extendsClauseElement); addConstructor(statements, node, extendsClauseElement); addClassMembers(statements, node); // Create a synthetic text range for the return statement. var closingBraceLocation = ts.createTokenRange(ts.skipTrivia(currentText, node.members.end), 18 /* CloseBraceToken */); var localName = ts.getInternalName(node); // The following partially-emitted expression exists purely to align our sourcemap // emit with the original emitter. var outer = ts.createPartiallyEmittedExpression(localName); outer.end = closingBraceLocation.end; ts.setEmitFlags(outer, 1536 /* NoComments */); var statement = ts.createReturn(outer); statement.pos = closingBraceLocation.pos; ts.setEmitFlags(statement, 1536 /* NoComments */ | 384 /* NoTokenSourceMaps */); statements.push(statement); ts.addRange(statements, endLexicalEnvironment()); var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ node.members), /*multiLine*/ true); ts.setEmitFlags(block, 1536 /* NoComments */); return block; } /** * Adds a call to the `__extends` helper if needed for a class. * * @param statements The statements of the class body function. * @param node The ClassExpression or ClassDeclaration node. * @param extendsClauseElement The expression for the class `extends` clause. */ function addExtendsHelperIfNeeded(statements, node, extendsClauseElement) { if (extendsClauseElement) { statements.push(ts.setTextRange(ts.createStatement(createExtendsHelper(context, ts.getLocalName(node))), /*location*/ extendsClauseElement)); } } /** * Adds the constructor of the class to a class body function. * * @param statements The statements of the class body function. * @param node The ClassExpression or ClassDeclaration node. * @param extendsClauseElement The expression for the class `extends` clause. */ function addConstructor(statements, node, extendsClauseElement) { var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var ancestorFacts = enterSubtree(16278 /* ConstructorExcludes */, 73 /* ConstructorIncludes */); var constructor = ts.getFirstConstructorWithBody(node); var hasSynthesizedSuper = hasSynthesizedDefaultSuperCall(constructor, extendsClauseElement !== undefined); var constructorFunction = ts.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, ts.getInternalName(node), /*typeParameters*/ undefined, transformConstructorParameters(constructor, hasSynthesizedSuper), /*type*/ undefined, transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper)); ts.setTextRange(constructorFunction, constructor || node); if (extendsClauseElement) { ts.setEmitFlags(constructorFunction, 8 /* CapturesThis */); } statements.push(constructorFunction); exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */); convertedLoopState = savedConvertedLoopState; } /** * Transforms the parameters of the constructor declaration of a class. * * @param constructor The constructor for the class. * @param hasSynthesizedSuper A value indicating whether the constructor starts with a * synthesized `super` call. */ function transformConstructorParameters(constructor, hasSynthesizedSuper) { // If the TypeScript transformer needed to synthesize a constructor for property // initializers, it would have also added a synthetic `...args` parameter and // `super` call. // If this is the case, we do not include the synthetic `...args` parameter and // will instead use the `arguments` object in ES5/3. return ts.visitParameterList(constructor && !hasSynthesizedSuper && constructor.parameters, visitor, context) || []; } /** * Transforms the body of a constructor declaration of a class. * * @param constructor The constructor for the class. * @param node The node which contains the constructor. * @param extendsClauseElement The expression for the class `extends` clause. * @param hasSynthesizedSuper A value indicating whether the constructor starts with a * synthesized `super` call. */ function transformConstructorBody(constructor, node, extendsClauseElement, hasSynthesizedSuper) { var statements = []; resumeLexicalEnvironment(); var statementOffset = -1; if (hasSynthesizedSuper) { // If a super call has already been synthesized, // we're going to assume that we should just transform everything after that. // The assumption is that no prior step in the pipeline has added any prologue directives. statementOffset = 0; } else if (constructor) { statementOffset = ts.addStandardPrologue(statements, constructor.body.statements, /*ensureUseStrict*/ false); } if (constructor) { addDefaultValueAssignmentsIfNeeded(statements, constructor); addRestParameterIfNeeded(statements, constructor, hasSynthesizedSuper); if (!hasSynthesizedSuper) { // If no super call has been synthesized, emit custom prologue directives. statementOffset = ts.addCustomPrologue(statements, constructor.body.statements, statementOffset, visitor); } ts.Debug.assert(statementOffset >= 0, "statementOffset not initialized correctly!"); } // determine whether the class is known syntactically to be a derived class (e.g. a // class that extends a value that is not syntactically known to be `null`). var isDerivedClass = extendsClauseElement && ts.skipOuterExpressions(extendsClauseElement.expression).kind !== 95 /* NullKeyword */; var superCaptureStatus = declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, constructor, isDerivedClass, hasSynthesizedSuper, statementOffset); // The last statement expression was replaced. Skip it. if (superCaptureStatus === 1 /* ReplaceSuperCapture */ || superCaptureStatus === 2 /* ReplaceWithReturn */) { statementOffset++; } if (constructor) { if (superCaptureStatus === 1 /* ReplaceSuperCapture */) { hierarchyFacts |= 4096 /* ConstructorWithCapturedSuper */; } ts.addRange(statements, ts.visitNodes(constructor.body.statements, visitor, ts.isStatement, /*start*/ statementOffset)); } // Return `_this` unless we're sure enough that it would be pointless to add a return statement. // If there's a constructor that we can tell returns in enough places, then we *do not* want to add a return. if (isDerivedClass && superCaptureStatus !== 2 /* ReplaceWithReturn */ && !(constructor && isSufficientlyCoveredByReturnStatements(constructor.body))) { statements.push(ts.createReturn(ts.createIdentifier("_this"))); } ts.addRange(statements, endLexicalEnvironment()); if (constructor) { prependCaptureNewTargetIfNeeded(statements, constructor, /*copyOnWrite*/ false); } var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), /*location*/ constructor ? constructor.body.statements : node.members), /*multiLine*/ true); ts.setTextRange(block, constructor ? constructor.body : node); if (!constructor) { ts.setEmitFlags(block, 1536 /* NoComments */); } return block; } /** * We want to try to avoid emitting a return statement in certain cases if a user already returned something. * It would generate obviously dead code, so we'll try to make things a little bit prettier * by doing a minimal check on whether some common patterns always explicitly return. */ function isSufficientlyCoveredByReturnStatements(statement) { // A return statement is considered covered. if (statement.kind === 220 /* ReturnStatement */) { return true; } else if (statement.kind === 212 /* IfStatement */) { var ifStatement = statement; if (ifStatement.elseStatement) { return isSufficientlyCoveredByReturnStatements(ifStatement.thenStatement) && isSufficientlyCoveredByReturnStatements(ifStatement.elseStatement); } } else if (statement.kind === 208 /* Block */) { var lastStatement = ts.lastOrUndefined(statement.statements); if (lastStatement && isSufficientlyCoveredByReturnStatements(lastStatement)) { return true; } } return false; } /** * Declares a `_this` variable for derived classes and for when arrow functions capture `this`. * * @returns The new statement offset into the `statements` array. */ function declareOrCaptureOrReturnThisForConstructorIfNeeded(statements, ctor, isDerivedClass, hasSynthesizedSuper, statementOffset) { // If this isn't a derived class, just capture 'this' for arrow functions if necessary. if (!isDerivedClass) { if (ctor) { addCaptureThisForNodeIfNeeded(statements, ctor); } return 0 /* NoReplacement */; } // We must be here because the user didn't write a constructor // but we needed to call 'super(...args)' anyway as per 14.5.14 of the ES2016 spec. // If that's the case we can just immediately return the result of a 'super()' call. if (!ctor) { statements.push(ts.createReturn(createDefaultSuperCallOrThis())); return 2 /* ReplaceWithReturn */; } // The constructor exists, but it and the 'super()' call it contains were generated // for something like property initializers. // Create a captured '_this' variable and assume it will subsequently be used. if (hasSynthesizedSuper) { captureThisForNode(statements, ctor, createDefaultSuperCallOrThis()); enableSubstitutionsForCapturedThis(); return 1 /* ReplaceSuperCapture */; } // Most of the time, a 'super' call will be the first real statement in a constructor body. // In these cases, we'd like to transform these into a *single* statement instead of a declaration // followed by an assignment statement for '_this'. For instance, if we emitted without an initializer, // we'd get: // // var _this; // _this = _super.call(...) || this; // // instead of // // var _this = _super.call(...) || this; // // Additionally, if the 'super()' call is the last statement, we should just avoid capturing // entirely and immediately return the result like so: // // return _super.call(...) || this; // var firstStatement; var superCallExpression; var ctorStatements = ctor.body.statements; if (statementOffset < ctorStatements.length) { firstStatement = ctorStatements[statementOffset]; if (firstStatement.kind === 211 /* ExpressionStatement */ && ts.isSuperCall(firstStatement.expression)) { superCallExpression = visitImmediateSuperCallInBody(firstStatement.expression); } } // Return the result if we have an immediate super() call on the last statement, // but only if the constructor itself doesn't use 'this' elsewhere. if (superCallExpression && statementOffset === ctorStatements.length - 1 && !(ctor.transformFlags & (16384 /* ContainsLexicalThis */ | 32768 /* ContainsCapturedLexicalThis */))) { var returnStatement = ts.createReturn(superCallExpression); if (superCallExpression.kind !== 195 /* BinaryExpression */ || superCallExpression.left.kind !== 182 /* CallExpression */) { ts.Debug.fail("Assumed generated super call would have form 'super.call(...) || this'."); } // Shift comments from the original super call to the return statement. ts.setCommentRange(returnStatement, ts.getCommentRange(ts.setEmitFlags(superCallExpression.left, 1536 /* NoComments */))); statements.push(returnStatement); return 2 /* ReplaceWithReturn */; } // Perform the capture. captureThisForNode(statements, ctor, superCallExpression || createActualThis(), firstStatement); // If we're actually replacing the original statement, we need to signal this to the caller. if (superCallExpression) { return 1 /* ReplaceSuperCapture */; } return 0 /* NoReplacement */; } function createActualThis() { return ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */); } function createDefaultSuperCallOrThis() { return ts.createLogicalOr(ts.createLogicalAnd(ts.createStrictInequality(ts.createIdentifier("_super"), ts.createNull()), ts.createFunctionApply(ts.createIdentifier("_super"), createActualThis(), ts.createIdentifier("arguments"))), createActualThis()); } /** * Visits a parameter declaration. * * @param node A ParameterDeclaration node. */ function visitParameter(node) { if (node.dotDotDotToken) { // rest parameters are elided return undefined; } else if (ts.isBindingPattern(node.name)) { // Binding patterns are converted into a generated name and are // evaluated inside the function body. return ts.setOriginalNode(ts.setTextRange(ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, ts.getGeneratedNameForNode(node), /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined), /*location*/ node), /*original*/ node); } else if (node.initializer) { // Initializers are elided return ts.setOriginalNode(ts.setTextRange(ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, node.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined), /*location*/ node), /*original*/ node); } else { return node; } } /** * Gets a value indicating whether we need to add default value assignments for a * function-like node. * * @param node A function-like node. */ function shouldAddDefaultValueAssignments(node) { return (node.transformFlags & 131072 /* ContainsDefaultValueAssignments */) !== 0; } /** * Adds statements to the body of a function-like node if it contains parameters with * binding patterns or initializers. * * @param statements The statements for the new function body. * @param node A function-like node. */ function addDefaultValueAssignmentsIfNeeded(statements, node) { if (!shouldAddDefaultValueAssignments(node)) { return; } for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) { var parameter = _a[_i]; var name = parameter.name, initializer = parameter.initializer, dotDotDotToken = parameter.dotDotDotToken; // A rest parameter cannot have a binding pattern or an initializer, // so let's just ignore it. if (dotDotDotToken) { continue; } if (ts.isBindingPattern(name)) { addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer); } else if (initializer) { addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer); } } } /** * Adds statements to the body of a function-like node for parameters with binding patterns * * @param statements The statements for the new function body. * @param parameter The parameter for the function. * @param name The name of the parameter. * @param initializer The initializer for the parameter. */ function addDefaultValueAssignmentForBindingPattern(statements, parameter, name, initializer) { var temp = ts.getGeneratedNameForNode(parameter); // In cases where a binding pattern is simply '[]' or '{}', // we usually don't want to emit a var declaration; however, in the presence // of an initializer, we must emit that expression to preserve side effects. if (name.elements.length > 0) { statements.push(ts.setEmitFlags(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList(ts.flattenDestructuringBinding(parameter, visitor, context, 0 /* All */, temp))), 1048576 /* CustomPrologue */)); } else if (initializer) { statements.push(ts.setEmitFlags(ts.createStatement(ts.createAssignment(temp, ts.visitNode(initializer, visitor, ts.isExpression))), 1048576 /* CustomPrologue */)); } } /** * Adds statements to the body of a function-like node for parameters with initializers. * * @param statements The statements for the new function body. * @param parameter The parameter for the function. * @param name The name of the parameter. * @param initializer The initializer for the parameter. */ function addDefaultValueAssignmentForInitializer(statements, parameter, name, initializer) { initializer = ts.visitNode(initializer, visitor, ts.isExpression); var statement = ts.createIf(ts.createTypeCheck(ts.getSynthesizedClone(name), "undefined"), ts.setEmitFlags(ts.setTextRange(ts.createBlock([ ts.createStatement(ts.setTextRange(ts.createAssignment(ts.setEmitFlags(ts.getMutableClone(name), 48 /* NoSourceMap */), ts.setEmitFlags(initializer, 48 /* NoSourceMap */ | ts.getEmitFlags(initializer))), parameter)) ]), parameter), 1 /* SingleLine */ | 32 /* NoTrailingSourceMap */ | 384 /* NoTokenSourceMaps */)); ts.startOnNewLine(statement); ts.setTextRange(statement, parameter); ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1048576 /* CustomPrologue */); statements.push(statement); } /** * Gets a value indicating whether we need to add statements to handle a rest parameter. * * @param node A ParameterDeclaration node. * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is * part of a constructor declaration with a * synthesized call to `super` */ function shouldAddRestParameter(node, inConstructorWithSynthesizedSuper) { return node && node.dotDotDotToken && node.name.kind === 71 /* Identifier */ && !inConstructorWithSynthesizedSuper; } /** * Adds statements to the body of a function-like node if it contains a rest parameter. * * @param statements The statements for the new function body. * @param node A function-like node. * @param inConstructorWithSynthesizedSuper A value indicating whether the parameter is * part of a constructor declaration with a * synthesized call to `super` */ function addRestParameterIfNeeded(statements, node, inConstructorWithSynthesizedSuper) { var parameter = ts.lastOrUndefined(node.parameters); if (!shouldAddRestParameter(parameter, inConstructorWithSynthesizedSuper)) { return; } // `declarationName` is the name of the local declaration for the parameter. var declarationName = ts.getMutableClone(parameter.name); ts.setEmitFlags(declarationName, 48 /* NoSourceMap */); // `expressionName` is the name of the parameter used in expressions. var expressionName = ts.getSynthesizedClone(parameter.name); var restIndex = node.parameters.length - 1; var temp = ts.createLoopVariable(); // var param = []; statements.push(ts.setEmitFlags(ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(declarationName, /*type*/ undefined, ts.createArrayLiteral([])) ])), /*location*/ parameter), 1048576 /* CustomPrologue */)); // for (var _i = restIndex; _i < arguments.length; _i++) { // param[_i - restIndex] = arguments[_i]; // } var forStatement = ts.createFor(ts.setTextRange(ts.createVariableDeclarationList([ ts.createVariableDeclaration(temp, /*type*/ undefined, ts.createLiteral(restIndex)) ]), parameter), ts.setTextRange(ts.createLessThan(temp, ts.createPropertyAccess(ts.createIdentifier("arguments"), "length")), parameter), ts.setTextRange(ts.createPostfixIncrement(temp), parameter), ts.createBlock([ ts.startOnNewLine(ts.setTextRange(ts.createStatement(ts.createAssignment(ts.createElementAccess(expressionName, restIndex === 0 ? temp : ts.createSubtract(temp, ts.createLiteral(restIndex))), ts.createElementAccess(ts.createIdentifier("arguments"), temp))), /*location*/ parameter)) ])); ts.setEmitFlags(forStatement, 1048576 /* CustomPrologue */); ts.startOnNewLine(forStatement); statements.push(forStatement); } /** * Adds a statement to capture the `this` of a function declaration if it is needed. * * @param statements The statements for the new function body. * @param node A node. */ function addCaptureThisForNodeIfNeeded(statements, node) { if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */ && node.kind !== 188 /* ArrowFunction */) { captureThisForNode(statements, node, ts.createThis()); } } function captureThisForNode(statements, node, initializer, originalStatement) { enableSubstitutionsForCapturedThis(); var captureThisStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration("_this", /*type*/ undefined, initializer) ])); ts.setEmitFlags(captureThisStatement, 1536 /* NoComments */ | 1048576 /* CustomPrologue */); ts.setTextRange(captureThisStatement, originalStatement); ts.setSourceMapRange(captureThisStatement, node); statements.push(captureThisStatement); } function prependCaptureNewTargetIfNeeded(statements, node, copyOnWrite) { if (hierarchyFacts & 16384 /* NewTarget */) { var newTarget = void 0; switch (node.kind) { case 188 /* ArrowFunction */: return statements; case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: // Methods and accessors cannot be constructors, so 'new.target' will // always return 'undefined'. newTarget = ts.createVoidZero(); break; case 153 /* Constructor */: // Class constructors can only be called with `new`, so `this.constructor` // should be relatively safe to use. newTarget = ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"); break; case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: // Functions can be called or constructed, and may have a `this` due to // being a member or when calling an imported function via `other_1.f()`. newTarget = ts.createConditional(ts.createLogicalAnd(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), ts.createBinary(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), 93 /* InstanceOfKeyword */, ts.getLocalName(node))), ts.createPropertyAccess(ts.setEmitFlags(ts.createThis(), 4 /* NoSubstitution */), "constructor"), ts.createVoidZero()); break; default: ts.Debug.failBadSyntaxKind(node); break; } var captureNewTargetStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration("_newTarget", /*type*/ undefined, newTarget) ])); if (copyOnWrite) { return [captureNewTargetStatement].concat(statements); } statements.unshift(captureNewTargetStatement); } return statements; } /** * Adds statements to the class body function for a class to define the members of the * class. * * @param statements The statements for the class body function. * @param node The ClassExpression or ClassDeclaration node. */ function addClassMembers(statements, node) { for (var _i = 0, _a = node.members; _i < _a.length; _i++) { var member = _a[_i]; switch (member.kind) { case 207 /* SemicolonClassElement */: statements.push(transformSemicolonClassElementToStatement(member)); break; case 152 /* MethodDeclaration */: statements.push(transformClassMethodDeclarationToStatement(getClassMemberPrefix(node, member), member, node)); break; case 154 /* GetAccessor */: case 155 /* SetAccessor */: var accessors = ts.getAllAccessorDeclarations(node.members, member); if (member === accessors.firstAccessor) { statements.push(transformAccessorsToStatement(getClassMemberPrefix(node, member), accessors, node)); } break; case 153 /* Constructor */: // Constructors are handled in visitClassExpression/visitClassDeclaration break; default: ts.Debug.failBadSyntaxKind(node); break; } } } /** * Transforms a SemicolonClassElement into a statement for a class body function. * * @param member The SemicolonClassElement node. */ function transformSemicolonClassElementToStatement(member) { return ts.setTextRange(ts.createEmptyStatement(), member); } /** * Transforms a MethodDeclaration into a statement for a class body function. * * @param receiver The receiver for the member. * @param member The MethodDeclaration node. */ function transformClassMethodDeclarationToStatement(receiver, member, container) { var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */); var commentRange = ts.getCommentRange(member); var sourceMapRange = ts.getSourceMapRange(member); var memberName = ts.createMemberAccessForPropertyName(receiver, ts.visitNode(member.name, visitor, ts.isPropertyName), /*location*/ member.name); var memberFunction = transformFunctionLikeToExpression(member, /*location*/ member, /*name*/ undefined, container); ts.setEmitFlags(memberFunction, 1536 /* NoComments */); ts.setSourceMapRange(memberFunction, sourceMapRange); var statement = ts.setTextRange(ts.createStatement(ts.createAssignment(memberName, memberFunction)), /*location*/ member); ts.setOriginalNode(statement, member); ts.setCommentRange(statement, commentRange); // The location for the statement is used to emit comments only. // No source map should be emitted for this statement to align with the // old emitter. ts.setEmitFlags(statement, 48 /* NoSourceMap */); exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */); return statement; } /** * Transforms a set of related of get/set accessors into a statement for a class body function. * * @param receiver The receiver for the member. * @param accessors The set of related get/set accessors. */ function transformAccessorsToStatement(receiver, accessors, container) { var statement = ts.createStatement(transformAccessorsToExpression(receiver, accessors, container, /*startsOnNewLine*/ false)); // The location for the statement is used to emit source maps only. // No comments should be emitted for this statement to align with the // old emitter. ts.setEmitFlags(statement, 1536 /* NoComments */); ts.setSourceMapRange(statement, ts.getSourceMapRange(accessors.firstAccessor)); return statement; } /** * Transforms a set of related get/set accessors into an expression for either a class * body function or an ObjectLiteralExpression with computed properties. * * @param receiver The receiver for the member. */ function transformAccessorsToExpression(receiver, _a, container, startsOnNewLine) { var firstAccessor = _a.firstAccessor, getAccessor = _a.getAccessor, setAccessor = _a.setAccessor; var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */); // To align with source maps in the old emitter, the receiver and property name // arguments are both mapped contiguously to the accessor name. var target = ts.getMutableClone(receiver); ts.setEmitFlags(target, 1536 /* NoComments */ | 32 /* NoTrailingSourceMap */); ts.setSourceMapRange(target, firstAccessor.name); var propertyName = ts.createExpressionForPropertyName(ts.visitNode(firstAccessor.name, visitor, ts.isPropertyName)); ts.setEmitFlags(propertyName, 1536 /* NoComments */ | 16 /* NoLeadingSourceMap */); ts.setSourceMapRange(propertyName, firstAccessor.name); var properties = []; if (getAccessor) { var getterFunction = transformFunctionLikeToExpression(getAccessor, /*location*/ undefined, /*name*/ undefined, container); ts.setSourceMapRange(getterFunction, ts.getSourceMapRange(getAccessor)); ts.setEmitFlags(getterFunction, 512 /* NoLeadingComments */); var getter = ts.createPropertyAssignment("get", getterFunction); ts.setCommentRange(getter, ts.getCommentRange(getAccessor)); properties.push(getter); } if (setAccessor) { var setterFunction = transformFunctionLikeToExpression(setAccessor, /*location*/ undefined, /*name*/ undefined, container); ts.setSourceMapRange(setterFunction, ts.getSourceMapRange(setAccessor)); ts.setEmitFlags(setterFunction, 512 /* NoLeadingComments */); var setter = ts.createPropertyAssignment("set", setterFunction); ts.setCommentRange(setter, ts.getCommentRange(setAccessor)); properties.push(setter); } properties.push(ts.createPropertyAssignment("enumerable", ts.createTrue()), ts.createPropertyAssignment("configurable", ts.createTrue())); var call = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ target, propertyName, ts.createObjectLiteral(properties, /*multiLine*/ true) ]); if (startsOnNewLine) { ts.startOnNewLine(call); } exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */); return call; } /** * Visits an ArrowFunction and transforms it into a FunctionExpression. * * @param node An ArrowFunction node. */ function visitArrowFunction(node) { if (node.transformFlags & 16384 /* ContainsLexicalThis */) { enableSubstitutionsForCapturedThis(); } var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var ancestorFacts = enterSubtree(16256 /* ArrowFunctionExcludes */, 66 /* ArrowFunctionIncludes */); var func = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, transformFunctionBody(node)); ts.setTextRange(func, node); ts.setOriginalNode(func, node); ts.setEmitFlags(func, 8 /* CapturesThis */); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); convertedLoopState = savedConvertedLoopState; return func; } /** * Visits a FunctionExpression node. * * @param node a FunctionExpression node. */ function visitFunctionExpression(node) { var ancestorFacts = ts.getEmitFlags(node) & 262144 /* AsyncFunctionBody */ ? enterSubtree(16278 /* AsyncFunctionBodyExcludes */, 69 /* AsyncFunctionBodyIncludes */) : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */); var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var parameters = ts.visitParameterList(node.parameters, visitor, context); var body = node.transformFlags & 64 /* ES2015 */ ? transformFunctionBody(node) : visitFunctionBodyDownLevel(node); var name = hierarchyFacts & 16384 /* NewTarget */ ? ts.getLocalName(node) : node.name; exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */); convertedLoopState = savedConvertedLoopState; return ts.updateFunctionExpression(node, /*modifiers*/ undefined, node.asteriskToken, name, /*typeParameters*/ undefined, parameters, /*type*/ undefined, body); } /** * Visits a FunctionDeclaration node. * * @param node a FunctionDeclaration node. */ function visitFunctionDeclaration(node) { var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */); var parameters = ts.visitParameterList(node.parameters, visitor, context); var body = node.transformFlags & 64 /* ES2015 */ ? transformFunctionBody(node) : visitFunctionBodyDownLevel(node); var name = hierarchyFacts & 16384 /* NewTarget */ ? ts.getLocalName(node) : node.name; exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */); convertedLoopState = savedConvertedLoopState; return ts.updateFunctionDeclaration(node, /*decorators*/ undefined, ts.visitNodes(node.modifiers, visitor, ts.isModifier), node.asteriskToken, name, /*typeParameters*/ undefined, parameters, /*type*/ undefined, body); } /** * Transforms a function-like node into a FunctionExpression. * * @param node The function-like node to transform. * @param location The source-map location for the new FunctionExpression. * @param name The name of the new FunctionExpression. */ function transformFunctionLikeToExpression(node, location, name, container) { var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var ancestorFacts = container && ts.isClassLike(container) && !ts.hasModifier(node, 32 /* Static */) ? enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */ | 8 /* NonStaticClassElement */) : enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */); var parameters = ts.visitParameterList(node.parameters, visitor, context); var body = transformFunctionBody(node); if (hierarchyFacts & 16384 /* NewTarget */ && !name && (node.kind === 229 /* FunctionDeclaration */ || node.kind === 187 /* FunctionExpression */)) { name = ts.getGeneratedNameForNode(node); } exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */); convertedLoopState = savedConvertedLoopState; return ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression( /*modifiers*/ undefined, node.asteriskToken, name, /*typeParameters*/ undefined, parameters, /*type*/ undefined, body), location), /*original*/ node); } /** * Transforms the body of a function-like node. * * @param node A function-like node. */ function transformFunctionBody(node) { var multiLine = false; // indicates whether the block *must* be emitted as multiple lines var singleLine = false; // indicates whether the block *may* be emitted as a single line var statementsLocation; var closeBraceLocation; var statements = []; var body = node.body; var statementOffset; resumeLexicalEnvironment(); if (ts.isBlock(body)) { // ensureUseStrict is false because no new prologue-directive should be added. // addStandardPrologue will put already-existing directives at the beginning of the target statement-array statementOffset = ts.addStandardPrologue(statements, body.statements, /*ensureUseStrict*/ false); } addCaptureThisForNodeIfNeeded(statements, node); addDefaultValueAssignmentsIfNeeded(statements, node); addRestParameterIfNeeded(statements, node, /*inConstructorWithSynthesizedSuper*/ false); // If we added any generated statements, this must be a multi-line block. if (!multiLine && statements.length > 0) { multiLine = true; } if (ts.isBlock(body)) { // addCustomPrologue puts already-existing directives at the beginning of the target statement-array statementOffset = ts.addCustomPrologue(statements, body.statements, statementOffset, visitor); statementsLocation = body.statements; ts.addRange(statements, ts.visitNodes(body.statements, visitor, ts.isStatement, statementOffset)); // If the original body was a multi-line block, this must be a multi-line block. if (!multiLine && body.multiLine) { multiLine = true; } } else { ts.Debug.assert(node.kind === 188 /* ArrowFunction */); // To align with the old emitter, we use a synthetic end position on the location // for the statement list we synthesize when we down-level an arrow function with // an expression function body. This prevents both comments and source maps from // being emitted for the end position only. statementsLocation = ts.moveRangeEnd(body, -1); var equalsGreaterThanToken = node.equalsGreaterThanToken; if (!ts.nodeIsSynthesized(equalsGreaterThanToken) && !ts.nodeIsSynthesized(body)) { if (ts.rangeEndIsOnSameLineAsRangeStart(equalsGreaterThanToken, body, currentSourceFile)) { singleLine = true; } else { multiLine = true; } } var expression = ts.visitNode(body, visitor, ts.isExpression); var returnStatement = ts.createReturn(expression); ts.setTextRange(returnStatement, body); ts.setEmitFlags(returnStatement, 384 /* NoTokenSourceMaps */ | 32 /* NoTrailingSourceMap */ | 1024 /* NoTrailingComments */); statements.push(returnStatement); // To align with the source map emit for the old emitter, we set a custom // source map location for the close brace. closeBraceLocation = body; } var lexicalEnvironment = context.endLexicalEnvironment(); ts.addRange(statements, lexicalEnvironment); prependCaptureNewTargetIfNeeded(statements, node, /*copyOnWrite*/ false); // If we added any final generated statements, this must be a multi-line block if (!multiLine && lexicalEnvironment && lexicalEnvironment.length) { multiLine = true; } var block = ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), multiLine); ts.setTextRange(block, node.body); if (!multiLine && singleLine) { ts.setEmitFlags(block, 1 /* SingleLine */); } if (closeBraceLocation) { ts.setTokenSourceMapRange(block, 18 /* CloseBraceToken */, closeBraceLocation); } ts.setOriginalNode(block, node.body); return block; } function visitFunctionBodyDownLevel(node) { var updated = ts.visitFunctionBody(node.body, functionBodyVisitor, context); return ts.updateBlock(updated, ts.setTextRange(ts.createNodeArray(prependCaptureNewTargetIfNeeded(updated.statements, node, /*copyOnWrite*/ true)), /*location*/ updated.statements)); } function visitBlock(node, isFunctionBody) { if (isFunctionBody) { // A function body is not a block scope. return ts.visitEachChild(node, visitor, context); } var ancestorFacts = hierarchyFacts & 256 /* IterationStatement */ ? enterSubtree(4032 /* IterationStatementBlockExcludes */, 512 /* IterationStatementBlockIncludes */) : enterSubtree(3904 /* BlockExcludes */, 128 /* BlockIncludes */); var updated = ts.visitEachChild(node, visitor, context); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } /** * Visits an ExpressionStatement that contains a destructuring assignment. * * @param node An ExpressionStatement node. */ function visitExpressionStatement(node) { // If we are here it is most likely because our expression is a destructuring assignment. switch (node.expression.kind) { case 186 /* ParenthesizedExpression */: return ts.updateStatement(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); case 195 /* BinaryExpression */: return ts.updateStatement(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); } return ts.visitEachChild(node, visitor, context); } /** * Visits a ParenthesizedExpression that may contain a destructuring assignment. * * @param node A ParenthesizedExpression node. * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs * of a destructuring assignment. */ function visitParenthesizedExpression(node, needsDestructuringValue) { // If we are here it is most likely because our expression is a destructuring assignment. if (!needsDestructuringValue) { // By default we always emit the RHS at the end of a flattened destructuring // expression. If we are in a state where we do not need the destructuring value, // we pass that information along to the children that care about it. switch (node.expression.kind) { case 186 /* ParenthesizedExpression */: return ts.updateParen(node, visitParenthesizedExpression(node.expression, /*needsDestructuringValue*/ false)); case 195 /* BinaryExpression */: return ts.updateParen(node, visitBinaryExpression(node.expression, /*needsDestructuringValue*/ false)); } } return ts.visitEachChild(node, visitor, context); } /** * Visits a BinaryExpression that contains a destructuring assignment. * * @param node A BinaryExpression node. * @param needsDestructuringValue A value indicating whether we need to hold onto the rhs * of a destructuring assignment. */ function visitBinaryExpression(node, needsDestructuringValue) { // If we are here it is because this is a destructuring assignment. if (ts.isDestructuringAssignment(node)) { return ts.flattenDestructuringAssignment(node, visitor, context, 0 /* All */, needsDestructuringValue); } return ts.visitEachChild(node, visitor, context); } function visitVariableStatement(node) { var ancestorFacts = enterSubtree(0 /* None */, ts.hasModifier(node, 1 /* Export */) ? 32 /* ExportedVariableStatement */ : 0 /* None */); var updated; if (convertedLoopState && (node.declarationList.flags & 3 /* BlockScoped */) === 0) { // we are inside a converted loop - hoist variable declarations var assignments = void 0; for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var decl = _a[_i]; hoistVariableDeclarationDeclaredInConvertedLoop(convertedLoopState, decl); if (decl.initializer) { var assignment = void 0; if (ts.isBindingPattern(decl.name)) { assignment = ts.flattenDestructuringAssignment(decl, visitor, context, 0 /* All */); } else { assignment = ts.createBinary(decl.name, 58 /* EqualsToken */, ts.visitNode(decl.initializer, visitor, ts.isExpression)); ts.setTextRange(assignment, decl); } assignments = ts.append(assignments, assignment); } } if (assignments) { updated = ts.setTextRange(ts.createStatement(ts.inlineExpressions(assignments)), node); } else { // none of declarations has initializer - the entire variable statement can be deleted updated = undefined; } } else { updated = ts.visitEachChild(node, visitor, context); } exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } /** * Visits a VariableDeclarationList that is block scoped (e.g. `let` or `const`). * * @param node A VariableDeclarationList node. */ function visitVariableDeclarationList(node) { if (node.transformFlags & 64 /* ES2015 */) { if (node.flags & 3 /* BlockScoped */) { enableSubstitutionsForBlockScopedBindings(); } var declarations = ts.flatMap(node.declarations, node.flags & 1 /* Let */ ? visitVariableDeclarationInLetDeclarationList : visitVariableDeclaration); var declarationList = ts.createVariableDeclarationList(declarations); ts.setOriginalNode(declarationList, node); ts.setTextRange(declarationList, node); ts.setCommentRange(declarationList, node); if (node.transformFlags & 8388608 /* ContainsBindingPattern */ && (ts.isBindingPattern(node.declarations[0].name) || ts.isBindingPattern(ts.lastOrUndefined(node.declarations).name))) { // If the first or last declaration is a binding pattern, we need to modify // the source map range for the declaration list. var firstDeclaration = ts.firstOrUndefined(declarations); if (firstDeclaration) { var lastDeclaration = ts.lastOrUndefined(declarations); ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); } } return declarationList; } return ts.visitEachChild(node, visitor, context); } /** * Gets a value indicating whether we should emit an explicit initializer for a variable * declaration in a `let` declaration list. * * @param node A VariableDeclaration node. */ function shouldEmitExplicitInitializerForLetDeclaration(node) { // Nested let bindings might need to be initialized explicitly to preserve // ES6 semantic: // // { let x = 1; } // { let x; } // x here should be undefined. not 1 // // Top level bindings never collide with anything and thus don't require // explicit initialization. As for nested let bindings there are two cases: // // - Nested let bindings that were not renamed definitely should be // initialized explicitly: // // { let x = 1; } // { let x; if (some-condition) { x = 1}; if (x) { /*1*/ } } // // Without explicit initialization code in /*1*/ can be executed even if // some-condition is evaluated to false. // // - Renaming introduces fresh name that should not collide with any // existing names, however renamed bindings sometimes also should be // explicitly initialized. One particular case: non-captured binding // declared inside loop body (but not in loop initializer): // // let x; // for (;;) { // let x; // } // // In downlevel codegen inner 'x' will be renamed so it won't collide // with outer 'x' however it will should be reset on every iteration as // if it was declared anew. // // * Why non-captured binding? // - Because if loop contains block scoped binding captured in some // function then loop body will be rewritten to have a fresh scope // on every iteration so everything will just work. // // * Why loop initializer is excluded? // - Since we've introduced a fresh name it already will be undefined. var flags = resolver.getNodeCheckFlags(node); var isCapturedInFunction = flags & 131072 /* CapturedBlockScopedBinding */; var isDeclaredInLoop = flags & 262144 /* BlockScopedBindingInLoop */; var emittedAsTopLevel = (hierarchyFacts & 64 /* TopLevel */) !== 0 || (isCapturedInFunction && isDeclaredInLoop && (hierarchyFacts & 512 /* IterationStatementBlock */) !== 0); var emitExplicitInitializer = !emittedAsTopLevel && (hierarchyFacts & 2048 /* ForInOrForOfStatement */) === 0 && (!resolver.isDeclarationWithCollidingName(node) || (isDeclaredInLoop && !isCapturedInFunction && (hierarchyFacts & (1024 /* ForStatement */ | 2048 /* ForInOrForOfStatement */)) === 0)); return emitExplicitInitializer; } /** * Visits a VariableDeclaration in a `let` declaration list. * * @param node A VariableDeclaration node. */ function visitVariableDeclarationInLetDeclarationList(node) { // For binding pattern names that lack initializers there is no point to emit // explicit initializer since downlevel codegen for destructuring will fail // in the absence of initializer so all binding elements will say uninitialized var name = node.name; if (ts.isBindingPattern(name)) { return visitVariableDeclaration(node); } if (!node.initializer && shouldEmitExplicitInitializerForLetDeclaration(node)) { var clone_2 = ts.getMutableClone(node); clone_2.initializer = ts.createVoidZero(); return clone_2; } return ts.visitEachChild(node, visitor, context); } /** * Visits a VariableDeclaration node with a binding pattern. * * @param node A VariableDeclaration node. */ function visitVariableDeclaration(node) { var ancestorFacts = enterSubtree(32 /* ExportedVariableStatement */, 0 /* None */); var updated; if (ts.isBindingPattern(node.name)) { updated = ts.flattenDestructuringBinding(node, visitor, context, 0 /* All */, /*value*/ undefined, (ancestorFacts & 32 /* ExportedVariableStatement */) !== 0); } else { updated = ts.visitEachChild(node, visitor, context); } exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } function recordLabel(node) { convertedLoopState.labels.set(ts.idText(node.label), true); } function resetLabel(node) { convertedLoopState.labels.set(ts.idText(node.label), false); } function visitLabeledStatement(node) { if (convertedLoopState && !convertedLoopState.labels) { convertedLoopState.labels = ts.createMap(); } var statement = ts.unwrapInnermostStatementOfLabel(node, convertedLoopState && recordLabel); return ts.isIterationStatement(statement, /*lookInLabeledStatements*/ false) ? visitIterationStatement(statement, /*outermostLabeledStatement*/ node) : ts.restoreEnclosingLabel(ts.visitNode(statement, visitor, ts.isStatement), node, convertedLoopState && resetLabel); } function visitIterationStatement(node, outermostLabeledStatement) { switch (node.kind) { case 213 /* DoStatement */: case 214 /* WhileStatement */: return visitDoOrWhileStatement(node, outermostLabeledStatement); case 215 /* ForStatement */: return visitForStatement(node, outermostLabeledStatement); case 216 /* ForInStatement */: return visitForInStatement(node, outermostLabeledStatement); case 217 /* ForOfStatement */: return visitForOfStatement(node, outermostLabeledStatement); } } function visitIterationStatementWithFacts(excludeFacts, includeFacts, node, outermostLabeledStatement, convert) { var ancestorFacts = enterSubtree(excludeFacts, includeFacts); var updated = convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } function visitDoOrWhileStatement(node, outermostLabeledStatement) { return visitIterationStatementWithFacts(0 /* DoOrWhileStatementExcludes */, 256 /* DoOrWhileStatementIncludes */, node, outermostLabeledStatement); } function visitForStatement(node, outermostLabeledStatement) { return visitIterationStatementWithFacts(3008 /* ForStatementExcludes */, 1280 /* ForStatementIncludes */, node, outermostLabeledStatement); } function visitForInStatement(node, outermostLabeledStatement) { return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement); } function visitForOfStatement(node, outermostLabeledStatement) { return visitIterationStatementWithFacts(1984 /* ForInOrForOfStatementExcludes */, 2304 /* ForInOrForOfStatementIncludes */, node, outermostLabeledStatement, compilerOptions.downlevelIteration ? convertForOfStatementForIterable : convertForOfStatementForArray); } function convertForOfStatementHead(node, boundValue, convertedLoopBodyStatements) { var statements = []; if (ts.isVariableDeclarationList(node.initializer)) { if (node.initializer.flags & 3 /* BlockScoped */) { enableSubstitutionsForBlockScopedBindings(); } var firstOriginalDeclaration = ts.firstOrUndefined(node.initializer.declarations); if (firstOriginalDeclaration && ts.isBindingPattern(firstOriginalDeclaration.name)) { // This works whether the declaration is a var, let, or const. // It will use rhsIterationValue _a[_i] as the initializer. var declarations = ts.flattenDestructuringBinding(firstOriginalDeclaration, visitor, context, 0 /* All */, boundValue); var declarationList = ts.setTextRange(ts.createVariableDeclarationList(declarations), node.initializer); ts.setOriginalNode(declarationList, node.initializer); // Adjust the source map range for the first declaration to align with the old // emitter. var firstDeclaration = declarations[0]; var lastDeclaration = ts.lastOrUndefined(declarations); ts.setSourceMapRange(declarationList, ts.createRange(firstDeclaration.pos, lastDeclaration.end)); statements.push(ts.createVariableStatement( /*modifiers*/ undefined, declarationList)); } else { // The following call does not include the initializer, so we have // to emit it separately. statements.push(ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.setOriginalNode(ts.setTextRange(ts.createVariableDeclarationList([ ts.createVariableDeclaration(firstOriginalDeclaration ? firstOriginalDeclaration.name : ts.createTempVariable(/*recordTempVariable*/ undefined), /*type*/ undefined, boundValue) ]), ts.moveRangePos(node.initializer, -1)), node.initializer)), ts.moveRangeEnd(node.initializer, -1))); } } else { // Initializer is an expression. Emit the expression in the body, so that it's // evaluated on every iteration. var assignment = ts.createAssignment(node.initializer, boundValue); if (ts.isDestructuringAssignment(assignment)) { ts.aggregateTransformFlags(assignment); statements.push(ts.createStatement(visitBinaryExpression(assignment, /*needsDestructuringValue*/ false))); } else { assignment.end = node.initializer.end; statements.push(ts.setTextRange(ts.createStatement(ts.visitNode(assignment, visitor, ts.isExpression)), ts.moveRangeEnd(node.initializer, -1))); } } var bodyLocation; var statementsLocation; if (convertedLoopBodyStatements) { ts.addRange(statements, convertedLoopBodyStatements); } else { var statement = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock); if (ts.isBlock(statement)) { ts.addRange(statements, statement.statements); bodyLocation = statement; statementsLocation = statement.statements; } else { statements.push(statement); } } // The old emitter does not emit source maps for the block. // We add the location to preserve comments. return ts.setEmitFlags(ts.setTextRange(ts.createBlock(ts.setTextRange(ts.createNodeArray(statements), statementsLocation), /*multiLine*/ true), bodyLocation), 48 /* NoSourceMap */ | 384 /* NoTokenSourceMaps */); } function convertForOfStatementForArray(node, outermostLabeledStatement, convertedLoopBodyStatements) { // The following ES6 code: // // for (let v of expr) { } // // should be emitted as // // for (var _i = 0, _a = expr; _i < _a.length; _i++) { // var v = _a[_i]; // } // // where _a and _i are temps emitted to capture the RHS and the counter, // respectively. // When the left hand side is an expression instead of a let declaration, // the "let v" is not emitted. // When the left hand side is a let/const, the v is renamed if there is // another v in scope. // Note that all assignments to the LHS are emitted in the body, including // all destructuring. // Note also that because an extra statement is needed to assign to the LHS, // for-of bodies are always emitted as blocks. var expression = ts.visitNode(node.expression, visitor, ts.isExpression); // In the case where the user wrote an identifier as the RHS, like this: // // for (let v of arr) { } // // we don't want to emit a temporary variable for the RHS, just use it directly. var counter = ts.createLoopVariable(); var rhsReference = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined); // The old emitter does not emit source maps for the expression ts.setEmitFlags(expression, 48 /* NoSourceMap */ | ts.getEmitFlags(expression)); var forStatement = ts.setTextRange(ts.createFor( /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([ ts.setTextRange(ts.createVariableDeclaration(counter, /*type*/ undefined, ts.createLiteral(0)), ts.moveRangePos(node.expression, -1)), ts.setTextRange(ts.createVariableDeclaration(rhsReference, /*type*/ undefined, expression), node.expression) ]), node.expression), 2097152 /* NoHoisting */), /*condition*/ ts.setTextRange(ts.createLessThan(counter, ts.createPropertyAccess(rhsReference, "length")), node.expression), /*incrementor*/ ts.setTextRange(ts.createPostfixIncrement(counter), node.expression), /*statement*/ convertForOfStatementHead(node, ts.createElementAccess(rhsReference, counter), convertedLoopBodyStatements)), /*location*/ node); // Disable trailing source maps for the OpenParenToken to align source map emit with the old emitter. ts.setEmitFlags(forStatement, 256 /* NoTokenTrailingSourceMaps */); ts.setTextRange(forStatement, node); return ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel); } function convertForOfStatementForIterable(node, outermostLabeledStatement, convertedLoopBodyStatements) { var expression = ts.visitNode(node.expression, visitor, ts.isExpression); var iterator = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(expression) : ts.createTempVariable(/*recordTempVariable*/ undefined); var result = ts.isIdentifier(expression) ? ts.getGeneratedNameForNode(iterator) : ts.createTempVariable(/*recordTempVariable*/ undefined); var errorRecord = ts.createUniqueName("e"); var catchVariable = ts.getGeneratedNameForNode(errorRecord); var returnMethod = ts.createTempVariable(/*recordTempVariable*/ undefined); var values = ts.createValuesHelper(context, expression, node.expression); var next = ts.createCall(ts.createPropertyAccess(iterator, "next"), /*typeArguments*/ undefined, []); hoistVariableDeclaration(errorRecord); hoistVariableDeclaration(returnMethod); var forStatement = ts.setEmitFlags(ts.setTextRange(ts.createFor( /*initializer*/ ts.setEmitFlags(ts.setTextRange(ts.createVariableDeclarationList([ ts.setTextRange(ts.createVariableDeclaration(iterator, /*type*/ undefined, values), node.expression), ts.createVariableDeclaration(result, /*type*/ undefined, next) ]), node.expression), 2097152 /* NoHoisting */), /*condition*/ ts.createLogicalNot(ts.createPropertyAccess(result, "done")), /*incrementor*/ ts.createAssignment(result, next), /*statement*/ convertForOfStatementHead(node, ts.createPropertyAccess(result, "value"), convertedLoopBodyStatements)), /*location*/ node), 256 /* NoTokenTrailingSourceMaps */); return ts.createTry(ts.createBlock([ ts.restoreEnclosingLabel(forStatement, outermostLabeledStatement, convertedLoopState && resetLabel) ]), ts.createCatchClause(ts.createVariableDeclaration(catchVariable), ts.setEmitFlags(ts.createBlock([ ts.createStatement(ts.createAssignment(errorRecord, ts.createObjectLiteral([ ts.createPropertyAssignment("error", catchVariable) ]))) ]), 1 /* SingleLine */)), ts.createBlock([ ts.createTry( /*tryBlock*/ ts.createBlock([ ts.setEmitFlags(ts.createIf(ts.createLogicalAnd(ts.createLogicalAnd(result, ts.createLogicalNot(ts.createPropertyAccess(result, "done"))), ts.createAssignment(returnMethod, ts.createPropertyAccess(iterator, "return"))), ts.createStatement(ts.createFunctionCall(returnMethod, iterator, []))), 1 /* SingleLine */), ]), /*catchClause*/ undefined, /*finallyBlock*/ ts.setEmitFlags(ts.createBlock([ ts.setEmitFlags(ts.createIf(errorRecord, ts.createThrow(ts.createPropertyAccess(errorRecord, "error"))), 1 /* SingleLine */) ]), 1 /* SingleLine */)) ])); } /** * Visits an ObjectLiteralExpression with computed propety names. * * @param node An ObjectLiteralExpression node. */ function visitObjectLiteralExpression(node) { // We are here because a ComputedPropertyName was used somewhere in the expression. var properties = node.properties; var numProperties = properties.length; // Find the first computed property. // Everything until that point can be emitted as part of the initial object literal. var numInitialProperties = numProperties; var numInitialPropertiesWithoutYield = numProperties; for (var i = 0; i < numProperties; i++) { var property = properties[i]; if ((property.transformFlags & 16777216 /* ContainsYield */ && hierarchyFacts & 4 /* AsyncFunctionBody */) && i < numInitialPropertiesWithoutYield) { numInitialPropertiesWithoutYield = i; } if (property.name.kind === 145 /* ComputedPropertyName */) { numInitialProperties = i; break; } } if (numInitialProperties !== numProperties) { if (numInitialPropertiesWithoutYield < numInitialProperties) { numInitialProperties = numInitialPropertiesWithoutYield; } // For computed properties, we need to create a unique handle to the object // literal so we can modify it without risking internal assignments tainting the object. var temp = ts.createTempVariable(hoistVariableDeclaration); // Write out the first non-computed properties, then emit the rest through indexing on the temp variable. var expressions = []; var assignment = ts.createAssignment(temp, ts.setEmitFlags(ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), node.multiLine), 65536 /* Indented */)); if (node.multiLine) { ts.startOnNewLine(assignment); } expressions.push(assignment); addObjectLiteralMembers(expressions, node, temp, numInitialProperties); // We need to clone the temporary identifier so that we can write it on a // new line expressions.push(node.multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp); return ts.inlineExpressions(expressions); } return ts.visitEachChild(node, visitor, context); } function shouldConvertIterationStatementBody(node) { return (resolver.getNodeCheckFlags(node) & 65536 /* LoopWithCapturedBlockScopedBinding */) !== 0; } /** * Records constituents of name for the given variable to be hoisted in the outer scope. */ function hoistVariableDeclarationDeclaredInConvertedLoop(state, node) { if (!state.hoistedLocalVariables) { state.hoistedLocalVariables = []; } visit(node.name); function visit(node) { if (node.kind === 71 /* Identifier */) { state.hoistedLocalVariables.push(node); } else { for (var _i = 0, _a = node.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { visit(element.name); } } } } } function convertIterationStatementBodyIfNecessary(node, outermostLabeledStatement, convert) { if (!shouldConvertIterationStatementBody(node)) { var saveAllowedNonLabeledJumps = void 0; if (convertedLoopState) { // we get here if we are trying to emit normal loop loop inside converted loop // set allowedNonLabeledJumps to Break | Continue to mark that break\continue inside the loop should be emitted as is saveAllowedNonLabeledJumps = convertedLoopState.allowedNonLabeledJumps; convertedLoopState.allowedNonLabeledJumps = 2 /* Break */ | 4 /* Continue */; } var result = convert ? convert(node, outermostLabeledStatement, /*convertedLoopBodyStatements*/ undefined) : ts.restoreEnclosingLabel(ts.visitEachChild(node, visitor, context), outermostLabeledStatement, convertedLoopState && resetLabel); if (convertedLoopState) { convertedLoopState.allowedNonLabeledJumps = saveAllowedNonLabeledJumps; } return result; } var functionName = ts.createUniqueName("_loop"); var loopInitializer; switch (node.kind) { case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: var initializer = node.initializer; if (initializer && initializer.kind === 228 /* VariableDeclarationList */) { loopInitializer = initializer; } break; } // variables that will be passed to the loop as parameters var loopParameters = []; // variables declared in the loop initializer that will be changed inside the loop var loopOutParameters = []; if (loopInitializer && (ts.getCombinedNodeFlags(loopInitializer) & 3 /* BlockScoped */)) { for (var _i = 0, _a = loopInitializer.declarations; _i < _a.length; _i++) { var decl = _a[_i]; processLoopVariableDeclaration(decl, loopParameters, loopOutParameters); } } var outerConvertedLoopState = convertedLoopState; convertedLoopState = { loopOutParameters: loopOutParameters }; if (outerConvertedLoopState) { // convertedOuterLoopState !== undefined means that this converted loop is nested in another converted loop. // if outer converted loop has already accumulated some state - pass it through if (outerConvertedLoopState.argumentsName) { // outer loop has already used 'arguments' so we've already have some name to alias it // use the same name in all nested loops convertedLoopState.argumentsName = outerConvertedLoopState.argumentsName; } if (outerConvertedLoopState.thisName) { // outer loop has already used 'this' so we've already have some name to alias it // use the same name in all nested loops convertedLoopState.thisName = outerConvertedLoopState.thisName; } if (outerConvertedLoopState.hoistedLocalVariables) { // we've already collected some non-block scoped variable declarations in enclosing loop // use the same storage in nested loop convertedLoopState.hoistedLocalVariables = outerConvertedLoopState.hoistedLocalVariables; } } startLexicalEnvironment(); var loopBody = ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock); var lexicalEnvironment = endLexicalEnvironment(); var currentState = convertedLoopState; convertedLoopState = outerConvertedLoopState; if (loopOutParameters.length || lexicalEnvironment) { var statements_4 = ts.isBlock(loopBody) ? loopBody.statements.slice() : [loopBody]; if (loopOutParameters.length) { copyOutParameters(loopOutParameters, 1 /* ToOutParameter */, statements_4); } ts.addRange(statements_4, lexicalEnvironment); loopBody = ts.createBlock(statements_4, /*multiline*/ true); } if (ts.isBlock(loopBody)) { loopBody.multiLine = true; } else { loopBody = ts.createBlock([loopBody], /*multiline*/ true); } var containsYield = (node.statement.transformFlags & 16777216 /* ContainsYield */) !== 0; var isAsyncBlockContainingAwait = containsYield && (hierarchyFacts & 4 /* AsyncFunctionBody */) !== 0; var loopBodyFlags = 0; if (currentState.containsLexicalThis) { loopBodyFlags |= 8 /* CapturesThis */; } if (isAsyncBlockContainingAwait) { loopBodyFlags |= 262144 /* AsyncFunctionBody */; } var convertedLoopVariable = ts.createVariableStatement( /*modifiers*/ undefined, ts.setEmitFlags(ts.createVariableDeclarationList([ ts.createVariableDeclaration(functionName, /*type*/ undefined, ts.setEmitFlags(ts.createFunctionExpression( /*modifiers*/ undefined, containsYield ? ts.createToken(39 /* AsteriskToken */) : undefined, /*name*/ undefined, /*typeParameters*/ undefined, loopParameters, /*type*/ undefined, loopBody), loopBodyFlags)) ]), 2097152 /* NoHoisting */)); var statements = [convertedLoopVariable]; var extraVariableDeclarations; // propagate state from the inner loop to the outer loop if necessary if (currentState.argumentsName) { // if alias for arguments is set if (outerConvertedLoopState) { // pass it to outer converted loop outerConvertedLoopState.argumentsName = currentState.argumentsName; } else { // this is top level converted loop and we need to create an alias for 'arguments' object (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.argumentsName, /*type*/ undefined, ts.createIdentifier("arguments"))); } } if (currentState.thisName) { // if alias for this is set if (outerConvertedLoopState) { // pass it to outer converted loop outerConvertedLoopState.thisName = currentState.thisName; } else { // this is top level converted loop so we need to create an alias for 'this' here // NOTE: // if converted loops were all nested in arrow function then we'll always emit '_this' so convertedLoopState.thisName will not be set. // If it is set this means that all nested loops are not nested in arrow function and it is safe to capture 'this'. (extraVariableDeclarations || (extraVariableDeclarations = [])).push(ts.createVariableDeclaration(currentState.thisName, /*type*/ undefined, ts.createIdentifier("this"))); } } if (currentState.hoistedLocalVariables) { // if hoistedLocalVariables !== undefined this means that we've possibly collected some variable declarations to be hoisted later if (outerConvertedLoopState) { // pass them to outer converted loop outerConvertedLoopState.hoistedLocalVariables = currentState.hoistedLocalVariables; } else { if (!extraVariableDeclarations) { extraVariableDeclarations = []; } // hoist collected variable declarations for (var _b = 0, _c = currentState.hoistedLocalVariables; _b < _c.length; _b++) { var identifier = _c[_b]; extraVariableDeclarations.push(ts.createVariableDeclaration(identifier)); } } } // add extra variables to hold out parameters if necessary if (loopOutParameters.length) { if (!extraVariableDeclarations) { extraVariableDeclarations = []; } for (var _d = 0, loopOutParameters_1 = loopOutParameters; _d < loopOutParameters_1.length; _d++) { var outParam = loopOutParameters_1[_d]; extraVariableDeclarations.push(ts.createVariableDeclaration(outParam.outParamName)); } } // create variable statement to hold all introduced variable declarations if (extraVariableDeclarations) { statements.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList(extraVariableDeclarations))); } var convertedLoopBodyStatements = generateCallToConvertedLoop(functionName, loopParameters, currentState, containsYield); var loop; if (convert) { loop = convert(node, outermostLabeledStatement, convertedLoopBodyStatements); } else { var clone_3 = ts.getMutableClone(node); // clean statement part clone_3.statement = undefined; // visit childnodes to transform initializer/condition/incrementor parts clone_3 = ts.visitEachChild(clone_3, visitor, context); // set loop statement clone_3.statement = ts.createBlock(convertedLoopBodyStatements, /*multiline*/ true); // reset and re-aggregate the transform flags clone_3.transformFlags = 0; ts.aggregateTransformFlags(clone_3); loop = ts.restoreEnclosingLabel(clone_3, outermostLabeledStatement, convertedLoopState && resetLabel); } statements.push(loop); return statements; } function copyOutParameter(outParam, copyDirection) { var source = copyDirection === 0 /* ToOriginal */ ? outParam.outParamName : outParam.originalName; var target = copyDirection === 0 /* ToOriginal */ ? outParam.originalName : outParam.outParamName; return ts.createBinary(target, 58 /* EqualsToken */, source); } function copyOutParameters(outParams, copyDirection, statements) { for (var _i = 0, outParams_1 = outParams; _i < outParams_1.length; _i++) { var outParam = outParams_1[_i]; statements.push(ts.createStatement(copyOutParameter(outParam, copyDirection))); } } function generateCallToConvertedLoop(loopFunctionExpressionName, parameters, state, isAsyncBlockContainingAwait) { var outerConvertedLoopState = convertedLoopState; var statements = []; // loop is considered simple if it does not have any return statements or break\continue that transfer control outside of the loop // simple loops are emitted as just 'loop()'; // NOTE: if loop uses only 'continue' it still will be emitted as simple loop var isSimpleLoop = !(state.nonLocalJumps & ~4 /* Continue */) && !state.labeledNonLocalBreaks && !state.labeledNonLocalContinues; var call = ts.createCall(loopFunctionExpressionName, /*typeArguments*/ undefined, ts.map(parameters, function (p) { return p.name; })); var callResult = isAsyncBlockContainingAwait ? ts.createYield(ts.createToken(39 /* AsteriskToken */), ts.setEmitFlags(call, 8388608 /* Iterator */)) : call; if (isSimpleLoop) { statements.push(ts.createStatement(callResult)); copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements); } else { var loopResultName = ts.createUniqueName("state"); var stateVariable = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(loopResultName, /*type*/ undefined, callResult)])); statements.push(stateVariable); copyOutParameters(state.loopOutParameters, 0 /* ToOriginal */, statements); if (state.nonLocalJumps & 8 /* Return */) { var returnStatement = void 0; if (outerConvertedLoopState) { outerConvertedLoopState.nonLocalJumps |= 8 /* Return */; returnStatement = ts.createReturn(loopResultName); } else { returnStatement = ts.createReturn(ts.createPropertyAccess(loopResultName, "value")); } statements.push(ts.createIf(ts.createBinary(ts.createTypeOf(loopResultName), 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("object")), returnStatement)); } if (state.nonLocalJumps & 2 /* Break */) { statements.push(ts.createIf(ts.createBinary(loopResultName, 34 /* EqualsEqualsEqualsToken */, ts.createLiteral("break")), ts.createBreak())); } if (state.labeledNonLocalBreaks || state.labeledNonLocalContinues) { var caseClauses = []; processLabeledJumps(state.labeledNonLocalBreaks, /*isBreak*/ true, loopResultName, outerConvertedLoopState, caseClauses); processLabeledJumps(state.labeledNonLocalContinues, /*isBreak*/ false, loopResultName, outerConvertedLoopState, caseClauses); statements.push(ts.createSwitch(loopResultName, ts.createCaseBlock(caseClauses))); } } return statements; } function setLabeledJump(state, isBreak, labelText, labelMarker) { if (isBreak) { if (!state.labeledNonLocalBreaks) { state.labeledNonLocalBreaks = ts.createMap(); } state.labeledNonLocalBreaks.set(labelText, labelMarker); } else { if (!state.labeledNonLocalContinues) { state.labeledNonLocalContinues = ts.createMap(); } state.labeledNonLocalContinues.set(labelText, labelMarker); } } function processLabeledJumps(table, isBreak, loopResultName, outerLoop, caseClauses) { if (!table) { return; } table.forEach(function (labelMarker, labelText) { var statements = []; // if there are no outer converted loop or outer label in question is located inside outer converted loop // then emit labeled break\continue // otherwise propagate pair 'label -> marker' to outer converted loop and emit 'return labelMarker' so outer loop can later decide what to do if (!outerLoop || (outerLoop.labels && outerLoop.labels.get(labelText))) { var label = ts.createIdentifier(labelText); statements.push(isBreak ? ts.createBreak(label) : ts.createContinue(label)); } else { setLabeledJump(outerLoop, isBreak, labelText, labelMarker); statements.push(ts.createReturn(loopResultName)); } caseClauses.push(ts.createCaseClause(ts.createLiteral(labelMarker), statements)); }); } function processLoopVariableDeclaration(decl, loopParameters, loopOutParameters) { var name = decl.name; if (ts.isBindingPattern(name)) { for (var _i = 0, _a = name.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { processLoopVariableDeclaration(element, loopParameters, loopOutParameters); } } } else { loopParameters.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name)); if (resolver.getNodeCheckFlags(decl) & 2097152 /* NeedsLoopOutParameter */) { var outParamName = ts.createUniqueName("out_" + ts.idText(name)); loopOutParameters.push({ originalName: name, outParamName: outParamName }); } } } /** * Adds the members of an object literal to an array of expressions. * * @param expressions An array of expressions. * @param node An ObjectLiteralExpression node. * @param receiver The receiver for members of the ObjectLiteralExpression. * @param numInitialNonComputedProperties The number of initial properties without * computed property names. */ function addObjectLiteralMembers(expressions, node, receiver, start) { var properties = node.properties; var numProperties = properties.length; for (var i = start; i < numProperties; i++) { var property = properties[i]; switch (property.kind) { case 154 /* GetAccessor */: case 155 /* SetAccessor */: var accessors = ts.getAllAccessorDeclarations(node.properties, property); if (property === accessors.firstAccessor) { expressions.push(transformAccessorsToExpression(receiver, accessors, node, node.multiLine)); } break; case 152 /* MethodDeclaration */: expressions.push(transformObjectLiteralMethodDeclarationToExpression(property, receiver, node, node.multiLine)); break; case 265 /* PropertyAssignment */: expressions.push(transformPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; case 266 /* ShorthandPropertyAssignment */: expressions.push(transformShorthandPropertyAssignmentToExpression(property, receiver, node.multiLine)); break; default: ts.Debug.failBadSyntaxKind(node); break; } } } /** * Transforms a PropertyAssignment node into an expression. * * @param node The ObjectLiteralExpression that contains the PropertyAssignment. * @param property The PropertyAssignment node. * @param receiver The receiver for the assignment. */ function transformPropertyAssignmentToExpression(property, receiver, startsOnNewLine) { var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.visitNode(property.initializer, visitor, ts.isExpression)); ts.setTextRange(expression, property); if (startsOnNewLine) { ts.startOnNewLine(expression); } return expression; } /** * Transforms a ShorthandPropertyAssignment node into an expression. * * @param node The ObjectLiteralExpression that contains the ShorthandPropertyAssignment. * @param property The ShorthandPropertyAssignment node. * @param receiver The receiver for the assignment. */ function transformShorthandPropertyAssignmentToExpression(property, receiver, startsOnNewLine) { var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(property.name, visitor, ts.isPropertyName)), ts.getSynthesizedClone(property.name)); ts.setTextRange(expression, property); if (startsOnNewLine) { ts.startOnNewLine(expression); } return expression; } /** * Transforms a MethodDeclaration of an ObjectLiteralExpression into an expression. * * @param node The ObjectLiteralExpression that contains the MethodDeclaration. * @param method The MethodDeclaration node. * @param receiver The receiver for the assignment. */ function transformObjectLiteralMethodDeclarationToExpression(method, receiver, container, startsOnNewLine) { var ancestorFacts = enterSubtree(0 /* None */, 0 /* None */); var expression = ts.createAssignment(ts.createMemberAccessForPropertyName(receiver, ts.visitNode(method.name, visitor, ts.isPropertyName)), transformFunctionLikeToExpression(method, /*location*/ method, /*name*/ undefined, container)); ts.setTextRange(expression, method); if (startsOnNewLine) { ts.startOnNewLine(expression); } exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 16384 /* NewTarget */ : 0 /* None */); return expression; } function visitCatchClause(node) { var ancestorFacts = enterSubtree(4032 /* BlockScopeExcludes */, 0 /* BlockScopeIncludes */); var updated; ts.Debug.assert(!!node.variableDeclaration, "Catch clause variable should always be present when downleveling ES2015."); if (ts.isBindingPattern(node.variableDeclaration.name)) { var temp = ts.createTempVariable(/*recordTempVariable*/ undefined); var newVariableDeclaration = ts.createVariableDeclaration(temp); ts.setTextRange(newVariableDeclaration, node.variableDeclaration); var vars = ts.flattenDestructuringBinding(node.variableDeclaration, visitor, context, 0 /* All */, temp); var list = ts.createVariableDeclarationList(vars); ts.setTextRange(list, node.variableDeclaration); var destructure = ts.createVariableStatement(/*modifiers*/ undefined, list); updated = ts.updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure)); } else { updated = ts.visitEachChild(node, visitor, context); } exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return updated; } function addStatementToStartOfBlock(block, statement) { var transformedStatements = ts.visitNodes(block.statements, visitor, ts.isStatement); return ts.updateBlock(block, [statement].concat(transformedStatements)); } /** * Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a * PropertyAssignment. * * @param node A MethodDeclaration node. */ function visitMethodDeclaration(node) { // We should only get here for methods on an object literal with regular identifier names. // Methods on classes are handled in visitClassDeclaration/visitClassExpression. // Methods with computed property names are handled in visitObjectLiteralExpression. ts.Debug.assert(!ts.isComputedPropertyName(node.name)); var functionExpression = transformFunctionLikeToExpression(node, /*location*/ ts.moveRangePos(node, -1), /*name*/ undefined, /*container*/ undefined); ts.setEmitFlags(functionExpression, 512 /* NoLeadingComments */ | ts.getEmitFlags(functionExpression)); return ts.setTextRange(ts.createPropertyAssignment(node.name, functionExpression), /*location*/ node); } /** * Visits an AccessorDeclaration of an ObjectLiteralExpression. * * @param node An AccessorDeclaration node. */ function visitAccessorDeclaration(node) { ts.Debug.assert(!ts.isComputedPropertyName(node.name)); var savedConvertedLoopState = convertedLoopState; convertedLoopState = undefined; var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, 65 /* FunctionIncludes */); var updated; if (node.transformFlags & 32768 /* ContainsCapturedLexicalThis */) { var parameters = ts.visitParameterList(node.parameters, visitor, context); var body = transformFunctionBody(node); if (node.kind === 154 /* GetAccessor */) { updated = ts.updateGetAccessor(node, node.decorators, node.modifiers, node.name, parameters, node.type, body); } else { updated = ts.updateSetAccessor(node, node.decorators, node.modifiers, node.name, parameters, body); } } else { updated = ts.visitEachChild(node, visitor, context); } exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, 0 /* None */); convertedLoopState = savedConvertedLoopState; return updated; } /** * Visits a ShorthandPropertyAssignment and transforms it into a PropertyAssignment. * * @param node A ShorthandPropertyAssignment node. */ function visitShorthandPropertyAssignment(node) { return ts.setTextRange(ts.createPropertyAssignment(node.name, ts.getSynthesizedClone(node.name)), /*location*/ node); } function visitComputedPropertyName(node) { var ancestorFacts = enterSubtree(0 /* ComputedPropertyNameExcludes */, 8192 /* ComputedPropertyNameIncludes */); var updated = ts.visitEachChild(node, visitor, context); exitSubtree(ancestorFacts, 49152 /* PropagateNewTargetMask */, hierarchyFacts & 49152 /* PropagateNewTargetMask */ ? 32768 /* NewTargetInComputedPropertyName */ : 0 /* None */); return updated; } /** * Visits a YieldExpression node. * * @param node A YieldExpression node. */ function visitYieldExpression(node) { // `yield` expressions are transformed using the generators transformer. return ts.visitEachChild(node, visitor, context); } /** * Visits an ArrayLiteralExpression that contains a spread element. * * @param node An ArrayLiteralExpression node. */ function visitArrayLiteralExpression(node) { if (node.transformFlags & 64 /* ES2015 */) { // We are here because we contain a SpreadElementExpression. return transformAndSpreadElements(node.elements, /*needsUniqueCopy*/ true, node.multiLine, /*hasTrailingComma*/ node.elements.hasTrailingComma); } return ts.visitEachChild(node, visitor, context); } /** * Visits a CallExpression that contains either a spread element or `super`. * * @param node a CallExpression. */ function visitCallExpression(node) { if (ts.getEmitFlags(node) & 33554432 /* TypeScriptClassWrapper */) { return visitTypeScriptClassWrapper(node); } if (node.transformFlags & 64 /* ES2015 */) { return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ true); } return ts.updateCall(node, ts.visitNode(node.expression, callExpressionVisitor, ts.isExpression), /*typeArguments*/ undefined, ts.visitNodes(node.arguments, visitor, ts.isExpression)); } function visitTypeScriptClassWrapper(node) { // This is a call to a class wrapper function (an IIFE) created by the 'ts' transformer. // The wrapper has a form similar to: // // (function() { // class C { // 1 // } // C.x = 1; // 2 // return C; // }()) // // When we transform the class, we end up with something like this: // // (function () { // var C = (function () { // 3 // function C() { // } // return C; // 4 // }()); // C.x = 1; // return C; // }()) // // We want to simplify the two nested IIFEs to end up with something like this: // // (function () { // function C() { // } // C.x = 1; // return C; // }()) // We skip any outer expressions in a number of places to get to the innermost // expression, but we will restore them later to preserve comments and source maps. var body = ts.cast(ts.cast(ts.skipOuterExpressions(node.expression), ts.isArrowFunction).body, ts.isBlock); // The class statements are the statements generated by visiting the first statement of the // body (1), while all other statements are added to remainingStatements (2) var classStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 0, 1); var remainingStatements = ts.visitNodes(body.statements, visitor, ts.isStatement, 1, body.statements.length - 1); var varStatement = ts.cast(ts.firstOrUndefined(classStatements), ts.isVariableStatement); // We know there is only one variable declaration here as we verified this in an // earlier call to isTypeScriptClassWrapper var variable = varStatement.declarationList.declarations[0]; var initializer = ts.skipOuterExpressions(variable.initializer); // Under certain conditions, the 'ts' transformer may introduce a class alias, which // we see as an assignment, for example: // // (function () { // var C = C_1 = (function () { // function C() { // } // C.x = function () { return C_1; } // return C; // }()); // C = C_1 = __decorate([dec], C); // return C; // var C_1; // }()) // var aliasAssignment = ts.tryCast(initializer, ts.isAssignmentExpression); // The underlying call (3) is another IIFE that may contain a '_super' argument. var call = ts.cast(aliasAssignment ? ts.skipOuterExpressions(aliasAssignment.right) : initializer, ts.isCallExpression); var func = ts.cast(ts.skipOuterExpressions(call.expression), ts.isFunctionExpression); var funcStatements = func.body.statements; var classBodyStart = 0; var classBodyEnd = -1; var statements = []; if (aliasAssignment) { // If we have a class alias assignment, we need to move it to the down-level constructor // function we generated for the class. var extendsCall = ts.tryCast(funcStatements[classBodyStart], ts.isExpressionStatement); if (extendsCall) { statements.push(extendsCall); classBodyStart++; } // The next statement is the function declaration. statements.push(funcStatements[classBodyStart]); classBodyStart++; // Add the class alias following the declaration. statements.push(ts.createStatement(ts.createAssignment(aliasAssignment.left, ts.cast(variable.name, ts.isIdentifier)))); } // Find the trailing 'return' statement (4) while (!ts.isReturnStatement(ts.elementAt(funcStatements, classBodyEnd))) { classBodyEnd--; } // When we extract the statements of the inner IIFE, we exclude the 'return' statement (4) // as we already have one that has been introduced by the 'ts' transformer. ts.addRange(statements, funcStatements, classBodyStart, classBodyEnd); if (classBodyEnd < -1) { // If there were any hoisted declarations following the return statement, we should // append them. ts.addRange(statements, funcStatements, classBodyEnd + 1); } // Add the remaining statements of the outer wrapper. ts.addRange(statements, remainingStatements); // The 'es2015' class transform may add an end-of-declaration marker. If so we will add it // after the remaining statements from the 'ts' transformer. ts.addRange(statements, classStatements, /*start*/ 1); // Recreate any outer parentheses or partially-emitted expressions to preserve source map // and comment locations. return ts.recreateOuterExpressions(node.expression, ts.recreateOuterExpressions(variable.initializer, ts.recreateOuterExpressions(aliasAssignment && aliasAssignment.right, ts.updateCall(call, ts.recreateOuterExpressions(call.expression, ts.updateFunctionExpression(func, /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, func.parameters, /*type*/ undefined, ts.updateBlock(func.body, statements))), /*typeArguments*/ undefined, call.arguments)))); } function visitImmediateSuperCallInBody(node) { return visitCallExpressionWithPotentialCapturedThisAssignment(node, /*assignToCapturedThis*/ false); } function visitCallExpressionWithPotentialCapturedThisAssignment(node, assignToCapturedThis) { // We are here either because SuperKeyword was used somewhere in the expression, or // because we contain a SpreadElementExpression. var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg; if (node.expression.kind === 97 /* SuperKeyword */) { ts.setEmitFlags(thisArg, 4 /* NoSubstitution */); } var resultingCall; if (node.transformFlags & 524288 /* ContainsSpread */) { // [source] // f(...a, b) // x.m(...a, b) // super(...a, b) // super.m(...a, b) // in static // super.m(...a, b) // in instance // // [output] // f.apply(void 0, a.concat([b])) // (_a = x).m.apply(_a, a.concat([b])) // _super.apply(this, a.concat([b])) // _super.m.apply(this, a.concat([b])) // _super.prototype.m.apply(this, a.concat([b])) resultingCall = ts.createFunctionApply(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), transformAndSpreadElements(node.arguments, /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)); } else { // [source] // super(a) // super.m(a) // in static // super.m(a) // in instance // // [output] // _super.call(this, a) // _super.m.call(this, a) // _super.prototype.m.call(this, a) resultingCall = ts.createFunctionCall(ts.visitNode(target, callExpressionVisitor, ts.isExpression), ts.visitNode(thisArg, visitor, ts.isExpression), ts.visitNodes(node.arguments, visitor, ts.isExpression), /*location*/ node); } if (node.expression.kind === 97 /* SuperKeyword */) { var actualThis = ts.createThis(); ts.setEmitFlags(actualThis, 4 /* NoSubstitution */); var initializer = ts.createLogicalOr(resultingCall, actualThis); resultingCall = assignToCapturedThis ? ts.createAssignment(ts.createIdentifier("_this"), initializer) : initializer; } return ts.setOriginalNode(resultingCall, node); } /** * Visits a NewExpression that contains a spread element. * * @param node A NewExpression node. */ function visitNewExpression(node) { if (node.transformFlags & 524288 /* ContainsSpread */) { // We are here because we contain a SpreadElementExpression. // [source] // new C(...a) // // [output] // new ((_a = C).bind.apply(_a, [void 0].concat(a)))() var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg; return ts.createNew(ts.createFunctionApply(ts.visitNode(target, visitor, ts.isExpression), thisArg, transformAndSpreadElements(ts.createNodeArray([ts.createVoidZero()].concat(node.arguments)), /*needsUniqueCopy*/ false, /*multiLine*/ false, /*hasTrailingComma*/ false)), /*typeArguments*/ undefined, []); } return ts.visitEachChild(node, visitor, context); } /** * Transforms an array of Expression nodes that contains a SpreadExpression. * * @param elements The array of Expression nodes. * @param needsUniqueCopy A value indicating whether to ensure that the result is a fresh array. * @param multiLine A value indicating whether the result should be emitted on multiple lines. */ function transformAndSpreadElements(elements, needsUniqueCopy, multiLine, hasTrailingComma) { // [source] // [a, ...b, c] // // [output] // [a].concat(b, [c]) // Map spans of spread expressions into their expressions and spans of other // expressions into an array literal. var numElements = elements.length; var segments = ts.flatten(ts.spanMap(elements, partitionSpread, function (partition, visitPartition, _start, end) { return visitPartition(partition, multiLine, hasTrailingComma && end === numElements); })); if (compilerOptions.downlevelIteration) { if (segments.length === 1) { var firstSegment = segments[0]; if (ts.isCallExpression(firstSegment) && ts.isIdentifier(firstSegment.expression) && (ts.getEmitFlags(firstSegment.expression) & 4096 /* HelperName */) && firstSegment.expression.escapedText === "___spread") { return segments[0]; } } return ts.createSpreadHelper(context, segments); } else { if (segments.length === 1) { var firstElement = elements[0]; return needsUniqueCopy && ts.isSpreadElement(firstElement) && firstElement.expression.kind !== 178 /* ArrayLiteralExpression */ ? ts.createArraySlice(segments[0]) : segments[0]; } // Rewrite using the pattern .concat(, , ...) return ts.createArrayConcat(segments.shift(), segments); } } function partitionSpread(node) { return ts.isSpreadElement(node) ? visitSpanOfSpreads : visitSpanOfNonSpreads; } function visitSpanOfSpreads(chunk) { return ts.map(chunk, visitExpressionOfSpread); } function visitSpanOfNonSpreads(chunk, multiLine, hasTrailingComma) { return ts.createArrayLiteral(ts.visitNodes(ts.createNodeArray(chunk, hasTrailingComma), visitor, ts.isExpression), multiLine); } function visitSpreadElement(node) { return ts.visitNode(node.expression, visitor, ts.isExpression); } /** * Transforms the expression of a SpreadExpression node. * * @param node A SpreadExpression node. */ function visitExpressionOfSpread(node) { return ts.visitNode(node.expression, visitor, ts.isExpression); } /** * Visits a template literal. * * @param node A template literal. */ function visitTemplateLiteral(node) { return ts.setTextRange(ts.createLiteral(node.text), node); } /** * Visits a string literal with an extended unicode escape. * * @param node A string literal. */ function visitStringLiteral(node) { if (node.hasExtendedUnicodeEscape) { return ts.setTextRange(ts.createLiteral(node.text), node); } return node; } /** * Visits a binary or octal (ES6) numeric literal. * * @param node A string literal. */ function visitNumericLiteral(node) { if (node.numericLiteralFlags & 384 /* BinaryOrOctalSpecifier */) { return ts.setTextRange(ts.createNumericLiteral(node.text), node); } return node; } /** * Visits a TaggedTemplateExpression node. * * @param node A TaggedTemplateExpression node. */ function visitTaggedTemplateExpression(node) { // Visit the tag expression var tag = ts.visitNode(node.tag, visitor, ts.isExpression); // Build up the template arguments and the raw and cooked strings for the template. // We start out with 'undefined' for the first argument and revisit later // to avoid walking over the template string twice and shifting all our arguments over after the fact. var templateArguments = [undefined]; var cookedStrings = []; var rawStrings = []; var template = node.template; if (ts.isNoSubstitutionTemplateLiteral(template)) { cookedStrings.push(ts.createLiteral(template.text)); rawStrings.push(getRawLiteral(template)); } else { cookedStrings.push(ts.createLiteral(template.head.text)); rawStrings.push(getRawLiteral(template.head)); for (var _i = 0, _a = template.templateSpans; _i < _a.length; _i++) { var templateSpan = _a[_i]; cookedStrings.push(ts.createLiteral(templateSpan.literal.text)); rawStrings.push(getRawLiteral(templateSpan.literal)); templateArguments.push(ts.visitNode(templateSpan.expression, visitor, ts.isExpression)); } } var helperCall = createTemplateObjectHelper(context, ts.createArrayLiteral(cookedStrings), ts.createArrayLiteral(rawStrings)); // Create a variable to cache the template object if we're in a module. // Do not do this in the global scope, as any variable we currently generate could conflict with // variables from outside of the current compilation. In the future, we can revisit this behavior. if (ts.isExternalModule(currentSourceFile)) { var tempVar = ts.createUniqueName("templateObject"); recordTaggedTemplateString(tempVar); templateArguments[0] = ts.createLogicalOr(tempVar, ts.createAssignment(tempVar, helperCall)); } else { templateArguments[0] = helperCall; } return ts.createCall(tag, /*typeArguments*/ undefined, templateArguments); } /** * Creates an ES5 compatible literal from an ES6 template literal. * * @param node The ES6 template literal. */ function getRawLiteral(node) { // Find original source text, since we need to emit the raw strings of the tagged template. // The raw strings contain the (escaped) strings of what the user wrote. // Examples: `\n` is converted to "\\n", a template string with a newline to "\n". var text = ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node); // text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"), // thus we need to remove those characters. // First template piece starts with "`", others with "}" // Last template piece ends with "`", others with "${" var isLast = node.kind === 13 /* NoSubstitutionTemplateLiteral */ || node.kind === 16 /* TemplateTail */; text = text.substring(1, text.length - (isLast ? 1 : 2)); // Newline normalization: // ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's // and LineTerminatorSequences are normalized to for both TV and TRV. text = text.replace(/\r\n?/g, "\n"); return ts.setTextRange(ts.createLiteral(text), node); } /** * Visits a TemplateExpression node. * * @param node A TemplateExpression node. */ function visitTemplateExpression(node) { var expressions = []; addTemplateHead(expressions, node); addTemplateSpans(expressions, node); // createAdd will check if each expression binds less closely than binary '+'. // If it does, it wraps the expression in parentheses. Otherwise, something like // `abc${ 1 << 2 }` // becomes // "abc" + 1 << 2 + "" // which is really // ("abc" + 1) << (2 + "") // rather than // "abc" + (1 << 2) + "" var expression = ts.reduceLeft(expressions, ts.createAdd); if (ts.nodeIsSynthesized(expression)) { expression.pos = node.pos; expression.end = node.end; } return expression; } /** * Gets a value indicating whether we need to include the head of a TemplateExpression. * * @param node A TemplateExpression node. */ function shouldAddTemplateHead(node) { // If this expression has an empty head literal and the first template span has a non-empty // literal, then emitting the empty head literal is not necessary. // `${ foo } and ${ bar }` // can be emitted as // foo + " and " + bar // This is because it is only required that one of the first two operands in the emit // output must be a string literal, so that the other operand and all following operands // are forced into strings. // // If the first template span has an empty literal, then the head must still be emitted. // `${ foo }${ bar }` // must still be emitted as // "" + foo + bar // There is always atleast one templateSpan in this code path, since // NoSubstitutionTemplateLiterals are directly emitted via emitLiteral() ts.Debug.assert(node.templateSpans.length !== 0); return node.head.text.length !== 0 || node.templateSpans[0].literal.text.length === 0; } /** * Adds the head of a TemplateExpression to an array of expressions. * * @param expressions An array of expressions. * @param node A TemplateExpression node. */ function addTemplateHead(expressions, node) { if (!shouldAddTemplateHead(node)) { return; } expressions.push(ts.createLiteral(node.head.text)); } /** * Visits and adds the template spans of a TemplateExpression to an array of expressions. * * @param expressions An array of expressions. * @param node A TemplateExpression node. */ function addTemplateSpans(expressions, node) { for (var _i = 0, _a = node.templateSpans; _i < _a.length; _i++) { var span_6 = _a[_i]; expressions.push(ts.visitNode(span_6.expression, visitor, ts.isExpression)); // Only emit if the literal is non-empty. // The binary '+' operator is left-associative, so the first string concatenation // with the head will force the result up to this point to be a string. // Emitting a '+ ""' has no semantic effect for middles and tails. if (span_6.literal.text.length !== 0) { expressions.push(ts.createLiteral(span_6.literal.text)); } } } /** * Visits the `super` keyword */ function visitSuperKeyword(isExpressionOfCall) { return hierarchyFacts & 8 /* NonStaticClassElement */ && !isExpressionOfCall ? ts.createPropertyAccess(ts.createIdentifier("_super"), "prototype") : ts.createIdentifier("_super"); } function visitMetaProperty(node) { if (node.keywordToken === 94 /* NewKeyword */ && node.name.escapedText === "target") { if (hierarchyFacts & 8192 /* ComputedPropertyName */) { hierarchyFacts |= 32768 /* NewTargetInComputedPropertyName */; } else { hierarchyFacts |= 16384 /* NewTarget */; } return ts.createIdentifier("_newTarget"); } return node; } /** * Called by the printer just before a node is printed. * * @param hint A hint as to the intended usage of the node. * @param node The node to be printed. * @param emitCallback The callback used to emit the node. */ function onEmitNode(hint, node, emitCallback) { if (enabledSubstitutions & 1 /* CapturedThis */ && ts.isFunctionLike(node)) { // If we are tracking a captured `this`, keep track of the enclosing function. var ancestorFacts = enterSubtree(16286 /* FunctionExcludes */, ts.getEmitFlags(node) & 8 /* CapturesThis */ ? 65 /* FunctionIncludes */ | 16 /* CapturesThis */ : 65 /* FunctionIncludes */); previousOnEmitNode(hint, node, emitCallback); exitSubtree(ancestorFacts, 0 /* None */, 0 /* None */); return; } previousOnEmitNode(hint, node, emitCallback); } /** * Enables a more costly code path for substitutions when we determine a source file * contains block-scoped bindings (e.g. `let` or `const`). */ function enableSubstitutionsForBlockScopedBindings() { if ((enabledSubstitutions & 2 /* BlockScopedBindings */) === 0) { enabledSubstitutions |= 2 /* BlockScopedBindings */; context.enableSubstitution(71 /* Identifier */); } } /** * Enables a more costly code path for substitutions when we determine a source file * contains a captured `this`. */ function enableSubstitutionsForCapturedThis() { if ((enabledSubstitutions & 1 /* CapturedThis */) === 0) { enabledSubstitutions |= 1 /* CapturedThis */; context.enableSubstitution(99 /* ThisKeyword */); context.enableEmitNotification(153 /* Constructor */); context.enableEmitNotification(152 /* MethodDeclaration */); context.enableEmitNotification(154 /* GetAccessor */); context.enableEmitNotification(155 /* SetAccessor */); context.enableEmitNotification(188 /* ArrowFunction */); context.enableEmitNotification(187 /* FunctionExpression */); context.enableEmitNotification(229 /* FunctionDeclaration */); } } /** * Hooks node substitutions. * * @param hint The context for the emitter. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (hint === 1 /* Expression */) { return substituteExpression(node); } if (ts.isIdentifier(node)) { return substituteIdentifier(node); } return node; } /** * Hooks substitutions for non-expression identifiers. */ function substituteIdentifier(node) { // Only substitute the identifier if we have enabled substitutions for block-scoped // bindings. if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) { var original = ts.getParseTreeNode(node, ts.isIdentifier); if (original && isNameOfDeclarationWithCollidingName(original)) { return ts.setTextRange(ts.getGeneratedNameForNode(original), node); } } return node; } /** * Determines whether a name is the name of a declaration with a colliding name. * NOTE: This function expects to be called with an original source tree node. * * @param node An original source tree node. */ function isNameOfDeclarationWithCollidingName(node) { var parent = node.parent; switch (parent.kind) { case 177 /* BindingElement */: case 230 /* ClassDeclaration */: case 233 /* EnumDeclaration */: case 227 /* VariableDeclaration */: return parent.name === node && resolver.isDeclarationWithCollidingName(parent); } return false; } /** * Substitutes an expression. * * @param node An Expression node. */ function substituteExpression(node) { switch (node.kind) { case 71 /* Identifier */: return substituteExpressionIdentifier(node); case 99 /* ThisKeyword */: return substituteThisKeyword(node); } return node; } /** * Substitutes an expression identifier. * * @param node An Identifier node. */ function substituteExpressionIdentifier(node) { if (enabledSubstitutions & 2 /* BlockScopedBindings */ && !ts.isInternalName(node)) { var declaration = resolver.getReferencedDeclarationWithCollidingName(node); if (declaration && !(ts.isClassLike(declaration) && isPartOfClassBody(declaration, node))) { return ts.setTextRange(ts.getGeneratedNameForNode(ts.getNameOfDeclaration(declaration)), node); } } return node; } function isPartOfClassBody(declaration, node) { var currentNode = ts.getParseTreeNode(node); if (!currentNode || currentNode === declaration || currentNode.end <= declaration.pos || currentNode.pos >= declaration.end) { // if the node has no correlation to a parse tree node, its definitely not // part of the body. // if the node is outside of the document range of the declaration, its // definitely not part of the body. return false; } var blockScope = ts.getEnclosingBlockScopeContainer(declaration); while (currentNode) { if (currentNode === blockScope || currentNode === declaration) { // if we are in the enclosing block scope of the declaration, we are definitely // not inside the class body. return false; } if (ts.isClassElement(currentNode) && currentNode.parent === declaration) { return true; } currentNode = currentNode.parent; } return false; } /** * Substitutes `this` when contained within an arrow function. * * @param node The ThisKeyword node. */ function substituteThisKeyword(node) { if (enabledSubstitutions & 1 /* CapturedThis */ && hierarchyFacts & 16 /* CapturesThis */) { return ts.setTextRange(ts.createIdentifier("_this"), node); } return node; } function getClassMemberPrefix(node, member) { return ts.hasModifier(member, 32 /* Static */) ? ts.getInternalName(node) : ts.createPropertyAccess(ts.getInternalName(node), "prototype"); } function hasSynthesizedDefaultSuperCall(constructor, hasExtendsClause) { if (!constructor || !hasExtendsClause) { return false; } if (ts.some(constructor.parameters)) { return false; } var statement = ts.firstOrUndefined(constructor.body.statements); if (!statement || !ts.nodeIsSynthesized(statement) || statement.kind !== 211 /* ExpressionStatement */) { return false; } var statementExpression = statement.expression; if (!ts.nodeIsSynthesized(statementExpression) || statementExpression.kind !== 182 /* CallExpression */) { return false; } var callTarget = statementExpression.expression; if (!ts.nodeIsSynthesized(callTarget) || callTarget.kind !== 97 /* SuperKeyword */) { return false; } var callArgument = ts.singleOrUndefined(statementExpression.arguments); if (!callArgument || !ts.nodeIsSynthesized(callArgument) || callArgument.kind !== 199 /* SpreadElement */) { return false; } var expression = callArgument.expression; return ts.isIdentifier(expression) && expression.escapedText === "arguments"; } } ts.transformES2015 = transformES2015; function createExtendsHelper(context, name) { context.requestEmitHelper(extendsHelper); return ts.createCall(ts.getHelperName("__extends"), /*typeArguments*/ undefined, [ name, ts.createIdentifier("_super") ]); } function createTemplateObjectHelper(context, cooked, raw) { context.requestEmitHelper(templateObjectHelper); return ts.createCall(ts.getHelperName("__makeTemplateObject"), /*typeArguments*/ undefined, [ cooked, raw ]); } var extendsHelper = { name: "typescript:extends", scoped: false, priority: 0, text: "\n var __extends = (this && this.__extends) || (function () {\n var extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n })();" }; var templateObjectHelper = { name: "typescript:makeTemplateObject", scoped: false, priority: 0, text: "\n var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\n return cooked;\n };" }; })(ts || (ts = {})); /// /// // Transforms generator functions into a compatible ES5 representation with similar runtime // semantics. This is accomplished by first transforming the body of each generator // function into an intermediate representation that is the compiled into a JavaScript // switch statement. // // Many functions in this transformer will contain comments indicating the expected // intermediate representation. For illustrative purposes, the following intermediate // language is used to define this intermediate representation: // // .nop - Performs no operation. // .local NAME, ... - Define local variable declarations. // .mark LABEL - Mark the location of a label. // .br LABEL - Jump to a label. If jumping out of a protected // region, all .finally blocks are executed. // .brtrue LABEL, (x) - Jump to a label IIF the expression `x` is truthy. // If jumping out of a protected region, all .finally // blocks are executed. // .brfalse LABEL, (x) - Jump to a label IIF the expression `x` is falsey. // If jumping out of a protected region, all .finally // blocks are executed. // .yield (x) - Yield the value of the optional expression `x`. // Resume at the next label. // .yieldstar (x) - Delegate yield to the value of the optional // expression `x`. Resume at the next label. // NOTE: `x` must be an Iterator, not an Iterable. // .loop CONTINUE, BREAK - Marks the beginning of a loop. Any "continue" or // "break" abrupt completions jump to the CONTINUE or // BREAK labels, respectively. // .endloop - Marks the end of a loop. // .with (x) - Marks the beginning of a WithStatement block, using // the supplied expression. // .endwith - Marks the end of a WithStatement. // .switch - Marks the beginning of a SwitchStatement. // .endswitch - Marks the end of a SwitchStatement. // .labeled NAME - Marks the beginning of a LabeledStatement with the // supplied name. // .endlabeled - Marks the end of a LabeledStatement. // .try TRY, CATCH, FINALLY, END - Marks the beginning of a protected region, and the // labels for each block. // .catch (x) - Marks the beginning of a catch block. // .finally - Marks the beginning of a finally block. // .endfinally - Marks the end of a finally block. // .endtry - Marks the end of a protected region. // .throw (x) - Throws the value of the expression `x`. // .return (x) - Returns the value of the expression `x`. // // In addition, the illustrative intermediate representation introduces some special // variables: // // %sent% - Either returns the next value sent to the generator, // returns the result of a delegated yield, or throws // the exception sent to the generator. // %error% - Returns the value of the current exception in a // catch block. // // This intermediate representation is then compiled into JavaScript syntax. The resulting // compilation output looks something like the following: // // function f() { // var /*locals*/; // /*functions*/ // return __generator(function (state) { // switch (state.label) { // /*cases per label*/ // } // }); // } // // Each of the above instructions corresponds to JavaScript emit similar to the following: // // .local NAME | var NAME; // -------------------------------|---------------------------------------------- // .mark LABEL | case LABEL: // -------------------------------|---------------------------------------------- // .br LABEL | return [3 /*break*/, LABEL]; // -------------------------------|---------------------------------------------- // .brtrue LABEL, (x) | if (x) return [3 /*break*/, LABEL]; // -------------------------------|---------------------------------------------- // .brfalse LABEL, (x) | if (!(x)) return [3, /*break*/, LABEL]; // -------------------------------|---------------------------------------------- // .yield (x) | return [4 /*yield*/, x]; // .mark RESUME | case RESUME: // a = %sent%; | a = state.sent(); // -------------------------------|---------------------------------------------- // .yieldstar (x) | return [5 /*yield**/, x]; // .mark RESUME | case RESUME: // a = %sent%; | a = state.sent(); // -------------------------------|---------------------------------------------- // .with (_a) | with (_a) { // a(); | a(); // | } // | state.label = LABEL; // .mark LABEL | case LABEL: // | with (_a) { // b(); | b(); // | } // .endwith | // -------------------------------|---------------------------------------------- // | case 0: // | state.trys = []; // | ... // .try TRY, CATCH, FINALLY, END | // .mark TRY | case TRY: // | state.trys.push([TRY, CATCH, FINALLY, END]); // .nop | // a(); | a(); // .br END | return [3 /*break*/, END]; // .catch (e) | // .mark CATCH | case CATCH: // | e = state.sent(); // b(); | b(); // .br END | return [3 /*break*/, END]; // .finally | // .mark FINALLY | case FINALLY: // c(); | c(); // .endfinally | return [7 /*endfinally*/]; // .endtry | // .mark END | case END: /*@internal*/ var ts; (function (ts) { var OpCode; (function (OpCode) { OpCode[OpCode["Nop"] = 0] = "Nop"; OpCode[OpCode["Statement"] = 1] = "Statement"; OpCode[OpCode["Assign"] = 2] = "Assign"; OpCode[OpCode["Break"] = 3] = "Break"; OpCode[OpCode["BreakWhenTrue"] = 4] = "BreakWhenTrue"; OpCode[OpCode["BreakWhenFalse"] = 5] = "BreakWhenFalse"; OpCode[OpCode["Yield"] = 6] = "Yield"; OpCode[OpCode["YieldStar"] = 7] = "YieldStar"; OpCode[OpCode["Return"] = 8] = "Return"; OpCode[OpCode["Throw"] = 9] = "Throw"; OpCode[OpCode["Endfinally"] = 10] = "Endfinally"; // Marks the end of a `finally` block })(OpCode || (OpCode = {})); // whether a generated code block is opening or closing at the current operation for a FunctionBuilder var BlockAction; (function (BlockAction) { BlockAction[BlockAction["Open"] = 0] = "Open"; BlockAction[BlockAction["Close"] = 1] = "Close"; })(BlockAction || (BlockAction = {})); // the kind for a generated code block in a FunctionBuilder var CodeBlockKind; (function (CodeBlockKind) { CodeBlockKind[CodeBlockKind["Exception"] = 0] = "Exception"; CodeBlockKind[CodeBlockKind["With"] = 1] = "With"; CodeBlockKind[CodeBlockKind["Switch"] = 2] = "Switch"; CodeBlockKind[CodeBlockKind["Loop"] = 3] = "Loop"; CodeBlockKind[CodeBlockKind["Labeled"] = 4] = "Labeled"; })(CodeBlockKind || (CodeBlockKind = {})); // the state for a generated code exception block var ExceptionBlockState; (function (ExceptionBlockState) { ExceptionBlockState[ExceptionBlockState["Try"] = 0] = "Try"; ExceptionBlockState[ExceptionBlockState["Catch"] = 1] = "Catch"; ExceptionBlockState[ExceptionBlockState["Finally"] = 2] = "Finally"; ExceptionBlockState[ExceptionBlockState["Done"] = 3] = "Done"; })(ExceptionBlockState || (ExceptionBlockState = {})); // NOTE: changes to this enum should be reflected in the __generator helper. var Instruction; (function (Instruction) { Instruction[Instruction["Next"] = 0] = "Next"; Instruction[Instruction["Throw"] = 1] = "Throw"; Instruction[Instruction["Return"] = 2] = "Return"; Instruction[Instruction["Break"] = 3] = "Break"; Instruction[Instruction["Yield"] = 4] = "Yield"; Instruction[Instruction["YieldStar"] = 5] = "YieldStar"; Instruction[Instruction["Catch"] = 6] = "Catch"; Instruction[Instruction["Endfinally"] = 7] = "Endfinally"; })(Instruction || (Instruction = {})); function getInstructionName(instruction) { switch (instruction) { case 2 /* Return */: return "return"; case 3 /* Break */: return "break"; case 4 /* Yield */: return "yield"; case 5 /* YieldStar */: return "yield*"; case 7 /* Endfinally */: return "endfinally"; } } function transformGenerators(context) { var resumeLexicalEnvironment = context.resumeLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistFunctionDeclaration = context.hoistFunctionDeclaration, hoistVariableDeclaration = context.hoistVariableDeclaration; var compilerOptions = context.getCompilerOptions(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var resolver = context.getEmitResolver(); var previousOnSubstituteNode = context.onSubstituteNode; context.onSubstituteNode = onSubstituteNode; var renamedCatchVariables; var renamedCatchVariableDeclarations; var inGeneratorFunctionBody; var inStatementContainingYield; // The following three arrays store information about generated code blocks. // All three arrays are correlated by their index. This approach is used over allocating // objects to store the same information to avoid GC overhead. // var blocks; // Information about the code block var blockOffsets; // The operation offset at which a code block begins or ends var blockActions; // Whether the code block is opened or closed var blockStack; // A stack of currently open code blocks // Labels are used to mark locations in the code that can be the target of a Break (jump) // operation. These are translated into case clauses in a switch statement. // The following two arrays are correlated by their index. This approach is used over // allocating objects to store the same information to avoid GC overhead. // var labelOffsets; // The operation offset at which the label is defined. var labelExpressions; // The NumericLiteral nodes bound to each label. var nextLabelId = 1; // The next label id to use. // Operations store information about generated code for the function body. This // Includes things like statements, assignments, breaks (jumps), and yields. // The following three arrays are correlated by their index. This approach is used over // allocating objects to store the same information to avoid GC overhead. // var operations; // The operation to perform. var operationArguments; // The arguments to the operation. var operationLocations; // The source map location for the operation. var state; // The name of the state object used by the generator at runtime. // The following variables store information used by the `build` function: // var blockIndex = 0; // The index of the current block. var labelNumber = 0; // The current label number. var labelNumbers; var lastOperationWasAbrupt; // Indicates whether the last operation was abrupt (break/continue). var lastOperationWasCompletion; // Indicates whether the last operation was a completion (return/throw). var clauses; // The case clauses generated for labels. var statements; // The statements for the current label. var exceptionBlockStack; // A stack of containing exception blocks. var currentExceptionBlock; // The current exception block. var withBlockStack; // A stack containing `with` blocks. return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile || (node.transformFlags & 512 /* ContainsGenerator */) === 0) { return node; } var visited = ts.visitEachChild(node, visitor, context); ts.addEmitHelpers(visited, context.readEmitHelpers()); return visited; } /** * Visits a node. * * @param node The node to visit. */ function visitor(node) { var transformFlags = node.transformFlags; if (inStatementContainingYield) { return visitJavaScriptInStatementContainingYield(node); } else if (inGeneratorFunctionBody) { return visitJavaScriptInGeneratorFunctionBody(node); } else if (transformFlags & 256 /* Generator */) { return visitGenerator(node); } else if (transformFlags & 512 /* ContainsGenerator */) { return ts.visitEachChild(node, visitor, context); } else { return node; } } /** * Visits a node that is contained within a statement that contains yield. * * @param node The node to visit. */ function visitJavaScriptInStatementContainingYield(node) { switch (node.kind) { case 213 /* DoStatement */: return visitDoStatement(node); case 214 /* WhileStatement */: return visitWhileStatement(node); case 222 /* SwitchStatement */: return visitSwitchStatement(node); case 223 /* LabeledStatement */: return visitLabeledStatement(node); default: return visitJavaScriptInGeneratorFunctionBody(node); } } /** * Visits a node that is contained within a generator function. * * @param node The node to visit. */ function visitJavaScriptInGeneratorFunctionBody(node) { switch (node.kind) { case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 187 /* FunctionExpression */: return visitFunctionExpression(node); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return visitAccessorDeclaration(node); case 209 /* VariableStatement */: return visitVariableStatement(node); case 215 /* ForStatement */: return visitForStatement(node); case 216 /* ForInStatement */: return visitForInStatement(node); case 219 /* BreakStatement */: return visitBreakStatement(node); case 218 /* ContinueStatement */: return visitContinueStatement(node); case 220 /* ReturnStatement */: return visitReturnStatement(node); default: if (node.transformFlags & 16777216 /* ContainsYield */) { return visitJavaScriptContainingYield(node); } else if (node.transformFlags & (512 /* ContainsGenerator */ | 33554432 /* ContainsHoistedDeclarationOrCompletion */)) { return ts.visitEachChild(node, visitor, context); } else { return node; } } } /** * Visits a node that contains a YieldExpression. * * @param node The node to visit. */ function visitJavaScriptContainingYield(node) { switch (node.kind) { case 195 /* BinaryExpression */: return visitBinaryExpression(node); case 196 /* ConditionalExpression */: return visitConditionalExpression(node); case 198 /* YieldExpression */: return visitYieldExpression(node); case 178 /* ArrayLiteralExpression */: return visitArrayLiteralExpression(node); case 179 /* ObjectLiteralExpression */: return visitObjectLiteralExpression(node); case 181 /* ElementAccessExpression */: return visitElementAccessExpression(node); case 182 /* CallExpression */: return visitCallExpression(node); case 183 /* NewExpression */: return visitNewExpression(node); default: return ts.visitEachChild(node, visitor, context); } } /** * Visits a generator function. * * @param node The node to visit. */ function visitGenerator(node) { switch (node.kind) { case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 187 /* FunctionExpression */: return visitFunctionExpression(node); default: ts.Debug.failBadSyntaxKind(node); return ts.visitEachChild(node, visitor, context); } } /** * Visits a function declaration. * * This will be called when one of the following conditions are met: * - The function declaration is a generator function. * - The function declaration is contained within the body of a generator function. * * @param node The node to visit. */ function visitFunctionDeclaration(node) { // Currently, we only support generators that were originally async functions. if (node.asteriskToken) { node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration( /*decorators*/ undefined, node.modifiers, /*asteriskToken*/ undefined, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, transformGeneratorFunctionBody(node.body)), /*location*/ node), node); } else { var savedInGeneratorFunctionBody = inGeneratorFunctionBody; var savedInStatementContainingYield = inStatementContainingYield; inGeneratorFunctionBody = false; inStatementContainingYield = false; node = ts.visitEachChild(node, visitor, context); inGeneratorFunctionBody = savedInGeneratorFunctionBody; inStatementContainingYield = savedInStatementContainingYield; } if (inGeneratorFunctionBody) { // Function declarations in a generator function body are hoisted // to the top of the lexical scope and elided from the current statement. hoistFunctionDeclaration(node); return undefined; } else { return node; } } /** * Visits a function expression. * * This will be called when one of the following conditions are met: * - The function expression is a generator function. * - The function expression is contained within the body of a generator function. * * @param node The node to visit. */ function visitFunctionExpression(node) { // Currently, we only support generators that were originally async functions. if (node.asteriskToken) { node = ts.setOriginalNode(ts.setTextRange(ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, node.name, /*typeParameters*/ undefined, ts.visitParameterList(node.parameters, visitor, context), /*type*/ undefined, transformGeneratorFunctionBody(node.body)), /*location*/ node), node); } else { var savedInGeneratorFunctionBody = inGeneratorFunctionBody; var savedInStatementContainingYield = inStatementContainingYield; inGeneratorFunctionBody = false; inStatementContainingYield = false; node = ts.visitEachChild(node, visitor, context); inGeneratorFunctionBody = savedInGeneratorFunctionBody; inStatementContainingYield = savedInStatementContainingYield; } return node; } /** * Visits a get or set accessor declaration. * * This will be called when one of the following conditions are met: * - The accessor is contained within the body of a generator function. * * @param node The node to visit. */ function visitAccessorDeclaration(node) { var savedInGeneratorFunctionBody = inGeneratorFunctionBody; var savedInStatementContainingYield = inStatementContainingYield; inGeneratorFunctionBody = false; inStatementContainingYield = false; node = ts.visitEachChild(node, visitor, context); inGeneratorFunctionBody = savedInGeneratorFunctionBody; inStatementContainingYield = savedInStatementContainingYield; return node; } /** * Transforms the body of a generator function declaration. * * @param node The function body to transform. */ function transformGeneratorFunctionBody(body) { // Save existing generator state var statements = []; var savedInGeneratorFunctionBody = inGeneratorFunctionBody; var savedInStatementContainingYield = inStatementContainingYield; var savedBlocks = blocks; var savedBlockOffsets = blockOffsets; var savedBlockActions = blockActions; var savedBlockStack = blockStack; var savedLabelOffsets = labelOffsets; var savedLabelExpressions = labelExpressions; var savedNextLabelId = nextLabelId; var savedOperations = operations; var savedOperationArguments = operationArguments; var savedOperationLocations = operationLocations; var savedState = state; // Initialize generator state inGeneratorFunctionBody = true; inStatementContainingYield = false; blocks = undefined; blockOffsets = undefined; blockActions = undefined; blockStack = undefined; labelOffsets = undefined; labelExpressions = undefined; nextLabelId = 1; operations = undefined; operationArguments = undefined; operationLocations = undefined; state = ts.createTempVariable(/*recordTempVariable*/ undefined); // Build the generator resumeLexicalEnvironment(); var statementOffset = ts.addPrologue(statements, body.statements, /*ensureUseStrict*/ false, visitor); transformAndEmitStatements(body.statements, statementOffset); var buildResult = build(); ts.addRange(statements, endLexicalEnvironment()); statements.push(ts.createReturn(buildResult)); // Restore previous generator state inGeneratorFunctionBody = savedInGeneratorFunctionBody; inStatementContainingYield = savedInStatementContainingYield; blocks = savedBlocks; blockOffsets = savedBlockOffsets; blockActions = savedBlockActions; blockStack = savedBlockStack; labelOffsets = savedLabelOffsets; labelExpressions = savedLabelExpressions; nextLabelId = savedNextLabelId; operations = savedOperations; operationArguments = savedOperationArguments; operationLocations = savedOperationLocations; state = savedState; return ts.setTextRange(ts.createBlock(statements, body.multiLine), body); } /** * Visits a variable statement. * * This will be called when one of the following conditions are met: * - The variable statement is contained within the body of a generator function. * * @param node The node to visit. */ function visitVariableStatement(node) { if (node.transformFlags & 16777216 /* ContainsYield */) { transformAndEmitVariableDeclarationList(node.declarationList); return undefined; } else { // Do not hoist custom prologues. if (ts.getEmitFlags(node) & 1048576 /* CustomPrologue */) { return node; } for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var variable = _a[_i]; hoistVariableDeclaration(variable.name); } var variables = ts.getInitializedVariables(node.declarationList); if (variables.length === 0) { return undefined; } return ts.setSourceMapRange(ts.createStatement(ts.inlineExpressions(ts.map(variables, transformInitializedVariable))), node); } } /** * Visits a binary expression. * * This will be called when one of the following conditions are met: * - The node contains a YieldExpression. * * @param node The node to visit. */ function visitBinaryExpression(node) { switch (ts.getExpressionAssociativity(node)) { case 0 /* Left */: return visitLeftAssociativeBinaryExpression(node); case 1 /* Right */: return visitRightAssociativeBinaryExpression(node); default: ts.Debug.fail("Unknown associativity."); } } function isCompoundAssignment(kind) { return kind >= 59 /* FirstCompoundAssignment */ && kind <= 70 /* LastCompoundAssignment */; } function getOperatorForCompoundAssignment(kind) { switch (kind) { case 59 /* PlusEqualsToken */: return 37 /* PlusToken */; case 60 /* MinusEqualsToken */: return 38 /* MinusToken */; case 61 /* AsteriskEqualsToken */: return 39 /* AsteriskToken */; case 62 /* AsteriskAsteriskEqualsToken */: return 40 /* AsteriskAsteriskToken */; case 63 /* SlashEqualsToken */: return 41 /* SlashToken */; case 64 /* PercentEqualsToken */: return 42 /* PercentToken */; case 65 /* LessThanLessThanEqualsToken */: return 45 /* LessThanLessThanToken */; case 66 /* GreaterThanGreaterThanEqualsToken */: return 46 /* GreaterThanGreaterThanToken */; case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: return 47 /* GreaterThanGreaterThanGreaterThanToken */; case 68 /* AmpersandEqualsToken */: return 48 /* AmpersandToken */; case 69 /* BarEqualsToken */: return 49 /* BarToken */; case 70 /* CaretEqualsToken */: return 50 /* CaretToken */; } } /** * Visits a right-associative binary expression containing `yield`. * * @param node The node to visit. */ function visitRightAssociativeBinaryExpression(node) { var left = node.left, right = node.right; if (containsYield(right)) { var target = void 0; switch (left.kind) { case 180 /* PropertyAccessExpression */: // [source] // a.b = yield; // // [intermediate] // .local _a // _a = a; // .yield resumeLabel // .mark resumeLabel // _a.b = %sent%; target = ts.updatePropertyAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), left.name); break; case 181 /* ElementAccessExpression */: // [source] // a[b] = yield; // // [intermediate] // .local _a, _b // _a = a; // _b = b; // .yield resumeLabel // .mark resumeLabel // _a[_b] = %sent%; target = ts.updateElementAccess(left, cacheExpression(ts.visitNode(left.expression, visitor, ts.isLeftHandSideExpression)), cacheExpression(ts.visitNode(left.argumentExpression, visitor, ts.isExpression))); break; default: target = ts.visitNode(left, visitor, ts.isExpression); break; } var operator = node.operatorToken.kind; if (isCompoundAssignment(operator)) { return ts.setTextRange(ts.createAssignment(target, ts.setTextRange(ts.createBinary(cacheExpression(target), getOperatorForCompoundAssignment(operator), ts.visitNode(right, visitor, ts.isExpression)), node)), node); } else { return ts.updateBinary(node, target, ts.visitNode(right, visitor, ts.isExpression)); } } return ts.visitEachChild(node, visitor, context); } function visitLeftAssociativeBinaryExpression(node) { if (containsYield(node.right)) { if (ts.isLogicalOperator(node.operatorToken.kind)) { return visitLogicalBinaryExpression(node); } else if (node.operatorToken.kind === 26 /* CommaToken */) { return visitCommaExpression(node); } // [source] // a() + (yield) + c() // // [intermediate] // .local _a // _a = a(); // .yield resumeLabel // _a + %sent% + c() var clone_4 = ts.getMutableClone(node); clone_4.left = cacheExpression(ts.visitNode(node.left, visitor, ts.isExpression)); clone_4.right = ts.visitNode(node.right, visitor, ts.isExpression); return clone_4; } return ts.visitEachChild(node, visitor, context); } /** * Visits a logical binary expression containing `yield`. * * @param node A node to visit. */ function visitLogicalBinaryExpression(node) { // Logical binary expressions (`&&` and `||`) are shortcutting expressions and need // to be transformed as such: // // [source] // x = a() && yield; // // [intermediate] // .local _a // _a = a(); // .brfalse resultLabel, (_a) // .yield resumeLabel // .mark resumeLabel // _a = %sent%; // .mark resultLabel // x = _a; // // [source] // x = a() || yield; // // [intermediate] // .local _a // _a = a(); // .brtrue resultLabel, (_a) // .yield resumeLabel // .mark resumeLabel // _a = %sent%; // .mark resultLabel // x = _a; var resultLabel = defineLabel(); var resultLocal = declareLocal(); emitAssignment(resultLocal, ts.visitNode(node.left, visitor, ts.isExpression), /*location*/ node.left); if (node.operatorToken.kind === 53 /* AmpersandAmpersandToken */) { // Logical `&&` shortcuts when the left-hand operand is falsey. emitBreakWhenFalse(resultLabel, resultLocal, /*location*/ node.left); } else { // Logical `||` shortcuts when the left-hand operand is truthy. emitBreakWhenTrue(resultLabel, resultLocal, /*location*/ node.left); } emitAssignment(resultLocal, ts.visitNode(node.right, visitor, ts.isExpression), /*location*/ node.right); markLabel(resultLabel); return resultLocal; } /** * Visits a comma expression containing `yield`. * * @param node The node to visit. */ function visitCommaExpression(node) { // [source] // x = a(), yield, b(); // // [intermediate] // a(); // .yield resumeLabel // .mark resumeLabel // x = %sent%, b(); var pendingExpressions = []; visit(node.left); visit(node.right); return ts.inlineExpressions(pendingExpressions); function visit(node) { if (ts.isBinaryExpression(node) && node.operatorToken.kind === 26 /* CommaToken */) { visit(node.left); visit(node.right); } else { if (containsYield(node) && pendingExpressions.length > 0) { emitWorker(1 /* Statement */, [ts.createStatement(ts.inlineExpressions(pendingExpressions))]); pendingExpressions = []; } pendingExpressions.push(ts.visitNode(node, visitor, ts.isExpression)); } } } /** * Visits a conditional expression containing `yield`. * * @param node The node to visit. */ function visitConditionalExpression(node) { // [source] // x = a() ? yield : b(); // // [intermediate] // .local _a // .brfalse whenFalseLabel, (a()) // .yield resumeLabel // .mark resumeLabel // _a = %sent%; // .br resultLabel // .mark whenFalseLabel // _a = b(); // .mark resultLabel // x = _a; // We only need to perform a specific transformation if a `yield` expression exists // in either the `whenTrue` or `whenFalse` branches. // A `yield` in the condition will be handled by the normal visitor. if (containsYield(node.whenTrue) || containsYield(node.whenFalse)) { var whenFalseLabel = defineLabel(); var resultLabel = defineLabel(); var resultLocal = declareLocal(); emitBreakWhenFalse(whenFalseLabel, ts.visitNode(node.condition, visitor, ts.isExpression), /*location*/ node.condition); emitAssignment(resultLocal, ts.visitNode(node.whenTrue, visitor, ts.isExpression), /*location*/ node.whenTrue); emitBreak(resultLabel); markLabel(whenFalseLabel); emitAssignment(resultLocal, ts.visitNode(node.whenFalse, visitor, ts.isExpression), /*location*/ node.whenFalse); markLabel(resultLabel); return resultLocal; } return ts.visitEachChild(node, visitor, context); } /** * Visits a `yield` expression. * * @param node The node to visit. */ function visitYieldExpression(node) { // [source] // x = yield a(); // // [intermediate] // .yield resumeLabel, (a()) // .mark resumeLabel // x = %sent%; var resumeLabel = defineLabel(); var expression = ts.visitNode(node.expression, visitor, ts.isExpression); if (node.asteriskToken) { var iterator = (ts.getEmitFlags(node.expression) & 8388608 /* Iterator */) === 0 ? ts.createValuesHelper(context, expression, /*location*/ node) : expression; emitYieldStar(iterator, /*location*/ node); } else { emitYield(expression, /*location*/ node); } markLabel(resumeLabel); return createGeneratorResume(/*location*/ node); } /** * Visits an ArrayLiteralExpression that contains a YieldExpression. * * @param node The node to visit. */ function visitArrayLiteralExpression(node) { return visitElements(node.elements, /*leadingElement*/ undefined, /*location*/ undefined, node.multiLine); } /** * Visits an array of expressions containing one or more YieldExpression nodes * and returns an expression for the resulting value. * * @param elements The elements to visit. * @param multiLine Whether array literals created should be emitted on multiple lines. */ function visitElements(elements, leadingElement, location, multiLine) { // [source] // ar = [1, yield, 2]; // // [intermediate] // .local _a // _a = [1]; // .yield resumeLabel // .mark resumeLabel // ar = _a.concat([%sent%, 2]); var numInitialElements = countInitialNodesWithoutYield(elements); var temp; if (numInitialElements > 0) { temp = declareLocal(); var initialElements = ts.visitNodes(elements, visitor, ts.isExpression, 0, numInitialElements); emitAssignment(temp, ts.createArrayLiteral(leadingElement ? [leadingElement].concat(initialElements) : initialElements)); leadingElement = undefined; } var expressions = ts.reduceLeft(elements, reduceElement, [], numInitialElements); return temp ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)]) : ts.setTextRange(ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine), location); function reduceElement(expressions, element) { if (containsYield(element) && expressions.length > 0) { var hasAssignedTemp = temp !== undefined; if (!temp) { temp = declareLocal(); } emitAssignment(temp, hasAssignedTemp ? ts.createArrayConcat(temp, [ts.createArrayLiteral(expressions, multiLine)]) : ts.createArrayLiteral(leadingElement ? [leadingElement].concat(expressions) : expressions, multiLine)); leadingElement = undefined; expressions = []; } expressions.push(ts.visitNode(element, visitor, ts.isExpression)); return expressions; } } function visitObjectLiteralExpression(node) { // [source] // o = { // a: 1, // b: yield, // c: 2 // }; // // [intermediate] // .local _a // _a = { // a: 1 // }; // .yield resumeLabel // .mark resumeLabel // o = (_a.b = %sent%, // _a.c = 2, // _a); var properties = node.properties; var multiLine = node.multiLine; var numInitialProperties = countInitialNodesWithoutYield(properties); var temp = declareLocal(); emitAssignment(temp, ts.createObjectLiteral(ts.visitNodes(properties, visitor, ts.isObjectLiteralElementLike, 0, numInitialProperties), multiLine)); var expressions = ts.reduceLeft(properties, reduceProperty, [], numInitialProperties); expressions.push(multiLine ? ts.startOnNewLine(ts.getMutableClone(temp)) : temp); return ts.inlineExpressions(expressions); function reduceProperty(expressions, property) { if (containsYield(property) && expressions.length > 0) { emitStatement(ts.createStatement(ts.inlineExpressions(expressions))); expressions = []; } var expression = ts.createExpressionForObjectLiteralElementLike(node, property, temp); var visited = ts.visitNode(expression, visitor, ts.isExpression); if (visited) { if (multiLine) { ts.startOnNewLine(visited); } expressions.push(visited); } return expressions; } } /** * Visits an ElementAccessExpression that contains a YieldExpression. * * @param node The node to visit. */ function visitElementAccessExpression(node) { if (containsYield(node.argumentExpression)) { // [source] // a = x[yield]; // // [intermediate] // .local _a // _a = x; // .yield resumeLabel // .mark resumeLabel // a = _a[%sent%] var clone_5 = ts.getMutableClone(node); clone_5.expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isLeftHandSideExpression)); clone_5.argumentExpression = ts.visitNode(node.argumentExpression, visitor, ts.isExpression); return clone_5; } return ts.visitEachChild(node, visitor, context); } function visitCallExpression(node) { if (!ts.isImportCall(node) && ts.forEach(node.arguments, containsYield)) { // [source] // a.b(1, yield, 2); // // [intermediate] // .local _a, _b, _c // _b = (_a = a).b; // _c = [1]; // .yield resumeLabel // .mark resumeLabel // _b.apply(_a, _c.concat([%sent%, 2])); var _a = ts.createCallBinding(node.expression, hoistVariableDeclaration, languageVersion, /*cacheIdentifiers*/ true), target = _a.target, thisArg = _a.thisArg; return ts.setOriginalNode(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isLeftHandSideExpression)), thisArg, visitElements(node.arguments), /*location*/ node), node); } return ts.visitEachChild(node, visitor, context); } function visitNewExpression(node) { if (ts.forEach(node.arguments, containsYield)) { // [source] // new a.b(1, yield, 2); // // [intermediate] // .local _a, _b, _c // _b = (_a = a.b).bind; // _c = [1]; // .yield resumeLabel // .mark resumeLabel // new (_b.apply(_a, _c.concat([%sent%, 2]))); var _a = ts.createCallBinding(ts.createPropertyAccess(node.expression, "bind"), hoistVariableDeclaration), target = _a.target, thisArg = _a.thisArg; return ts.setOriginalNode(ts.setTextRange(ts.createNew(ts.createFunctionApply(cacheExpression(ts.visitNode(target, visitor, ts.isExpression)), thisArg, visitElements(node.arguments, /*leadingElement*/ ts.createVoidZero())), /*typeArguments*/ undefined, []), node), node); } return ts.visitEachChild(node, visitor, context); } function transformAndEmitStatements(statements, start) { if (start === void 0) { start = 0; } var numStatements = statements.length; for (var i = start; i < numStatements; i++) { transformAndEmitStatement(statements[i]); } } function transformAndEmitEmbeddedStatement(node) { if (ts.isBlock(node)) { transformAndEmitStatements(node.statements); } else { transformAndEmitStatement(node); } } function transformAndEmitStatement(node) { var savedInStatementContainingYield = inStatementContainingYield; if (!inStatementContainingYield) { inStatementContainingYield = containsYield(node); } transformAndEmitStatementWorker(node); inStatementContainingYield = savedInStatementContainingYield; } function transformAndEmitStatementWorker(node) { switch (node.kind) { case 208 /* Block */: return transformAndEmitBlock(node); case 211 /* ExpressionStatement */: return transformAndEmitExpressionStatement(node); case 212 /* IfStatement */: return transformAndEmitIfStatement(node); case 213 /* DoStatement */: return transformAndEmitDoStatement(node); case 214 /* WhileStatement */: return transformAndEmitWhileStatement(node); case 215 /* ForStatement */: return transformAndEmitForStatement(node); case 216 /* ForInStatement */: return transformAndEmitForInStatement(node); case 218 /* ContinueStatement */: return transformAndEmitContinueStatement(node); case 219 /* BreakStatement */: return transformAndEmitBreakStatement(node); case 220 /* ReturnStatement */: return transformAndEmitReturnStatement(node); case 221 /* WithStatement */: return transformAndEmitWithStatement(node); case 222 /* SwitchStatement */: return transformAndEmitSwitchStatement(node); case 223 /* LabeledStatement */: return transformAndEmitLabeledStatement(node); case 224 /* ThrowStatement */: return transformAndEmitThrowStatement(node); case 225 /* TryStatement */: return transformAndEmitTryStatement(node); default: return emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function transformAndEmitBlock(node) { if (containsYield(node)) { transformAndEmitStatements(node.statements); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function transformAndEmitExpressionStatement(node) { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } function transformAndEmitVariableDeclarationList(node) { for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) { var variable = _a[_i]; var name = ts.getSynthesizedClone(variable.name); ts.setCommentRange(name, variable.name); hoistVariableDeclaration(name); } var variables = ts.getInitializedVariables(node); var numVariables = variables.length; var variablesWritten = 0; var pendingExpressions = []; while (variablesWritten < numVariables) { for (var i = variablesWritten; i < numVariables; i++) { var variable = variables[i]; if (containsYield(variable.initializer) && pendingExpressions.length > 0) { break; } pendingExpressions.push(transformInitializedVariable(variable)); } if (pendingExpressions.length) { emitStatement(ts.createStatement(ts.inlineExpressions(pendingExpressions))); variablesWritten += pendingExpressions.length; pendingExpressions = []; } } return undefined; } function transformInitializedVariable(node) { return ts.setSourceMapRange(ts.createAssignment(ts.setSourceMapRange(ts.getSynthesizedClone(node.name), node.name), ts.visitNode(node.initializer, visitor, ts.isExpression)), node); } function transformAndEmitIfStatement(node) { if (containsYield(node)) { // [source] // if (x) // /*thenStatement*/ // else // /*elseStatement*/ // // [intermediate] // .brfalse elseLabel, (x) // /*thenStatement*/ // .br endLabel // .mark elseLabel // /*elseStatement*/ // .mark endLabel if (containsYield(node.thenStatement) || containsYield(node.elseStatement)) { var endLabel = defineLabel(); var elseLabel = node.elseStatement ? defineLabel() : undefined; emitBreakWhenFalse(node.elseStatement ? elseLabel : endLabel, ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node.expression); transformAndEmitEmbeddedStatement(node.thenStatement); if (node.elseStatement) { emitBreak(endLabel); markLabel(elseLabel); transformAndEmitEmbeddedStatement(node.elseStatement); } markLabel(endLabel); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function transformAndEmitDoStatement(node) { if (containsYield(node)) { // [source] // do { // /*body*/ // } // while (i < 10); // // [intermediate] // .loop conditionLabel, endLabel // .mark loopLabel // /*body*/ // .mark conditionLabel // .brtrue loopLabel, (i < 10) // .endloop // .mark endLabel var conditionLabel = defineLabel(); var loopLabel = defineLabel(); beginLoopBlock(/*continueLabel*/ conditionLabel); markLabel(loopLabel); transformAndEmitEmbeddedStatement(node.statement); markLabel(conditionLabel); emitBreakWhenTrue(loopLabel, ts.visitNode(node.expression, visitor, ts.isExpression)); endLoopBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitDoStatement(node) { if (inStatementContainingYield) { beginScriptLoopBlock(); node = ts.visitEachChild(node, visitor, context); endLoopBlock(); return node; } else { return ts.visitEachChild(node, visitor, context); } } function transformAndEmitWhileStatement(node) { if (containsYield(node)) { // [source] // while (i < 10) { // /*body*/ // } // // [intermediate] // .loop loopLabel, endLabel // .mark loopLabel // .brfalse endLabel, (i < 10) // /*body*/ // .br loopLabel // .endloop // .mark endLabel var loopLabel = defineLabel(); var endLabel = beginLoopBlock(loopLabel); markLabel(loopLabel); emitBreakWhenFalse(endLabel, ts.visitNode(node.expression, visitor, ts.isExpression)); transformAndEmitEmbeddedStatement(node.statement); emitBreak(loopLabel); endLoopBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitWhileStatement(node) { if (inStatementContainingYield) { beginScriptLoopBlock(); node = ts.visitEachChild(node, visitor, context); endLoopBlock(); return node; } else { return ts.visitEachChild(node, visitor, context); } } function transformAndEmitForStatement(node) { if (containsYield(node)) { // [source] // for (var i = 0; i < 10; i++) { // /*body*/ // } // // [intermediate] // .local i // i = 0; // .loop incrementLabel, endLoopLabel // .mark conditionLabel // .brfalse endLoopLabel, (i < 10) // /*body*/ // .mark incrementLabel // i++; // .br conditionLabel // .endloop // .mark endLoopLabel var conditionLabel = defineLabel(); var incrementLabel = defineLabel(); var endLabel = beginLoopBlock(incrementLabel); if (node.initializer) { var initializer = node.initializer; if (ts.isVariableDeclarationList(initializer)) { transformAndEmitVariableDeclarationList(initializer); } else { emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(initializer, visitor, ts.isExpression)), initializer)); } } markLabel(conditionLabel); if (node.condition) { emitBreakWhenFalse(endLabel, ts.visitNode(node.condition, visitor, ts.isExpression)); } transformAndEmitEmbeddedStatement(node.statement); markLabel(incrementLabel); if (node.incrementor) { emitStatement(ts.setTextRange(ts.createStatement(ts.visitNode(node.incrementor, visitor, ts.isExpression)), node.incrementor)); } emitBreak(conditionLabel); endLoopBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitForStatement(node) { if (inStatementContainingYield) { beginScriptLoopBlock(); } var initializer = node.initializer; if (initializer && ts.isVariableDeclarationList(initializer)) { for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) { var variable = _a[_i]; hoistVariableDeclaration(variable.name); } var variables = ts.getInitializedVariables(initializer); node = ts.updateFor(node, variables.length > 0 ? ts.inlineExpressions(ts.map(variables, transformInitializedVariable)) : undefined, ts.visitNode(node.condition, visitor, ts.isExpression), ts.visitNode(node.incrementor, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); } else { node = ts.visitEachChild(node, visitor, context); } if (inStatementContainingYield) { endLoopBlock(); } return node; } function transformAndEmitForInStatement(node) { // TODO(rbuckton): Source map locations if (containsYield(node)) { // [source] // for (var p in o) { // /*body*/ // } // // [intermediate] // .local _a, _b, _i // _a = []; // for (_b in o) _a.push(_b); // _i = 0; // .loop incrementLabel, endLoopLabel // .mark conditionLabel // .brfalse endLoopLabel, (_i < _a.length) // p = _a[_i]; // /*body*/ // .mark incrementLabel // _b++; // .br conditionLabel // .endloop // .mark endLoopLabel var keysArray = declareLocal(); // _a var key = declareLocal(); // _b var keysIndex = ts.createLoopVariable(); // _i var initializer = node.initializer; hoistVariableDeclaration(keysIndex); emitAssignment(keysArray, ts.createArrayLiteral()); emitStatement(ts.createForIn(key, ts.visitNode(node.expression, visitor, ts.isExpression), ts.createStatement(ts.createCall(ts.createPropertyAccess(keysArray, "push"), /*typeArguments*/ undefined, [key])))); emitAssignment(keysIndex, ts.createLiteral(0)); var conditionLabel = defineLabel(); var incrementLabel = defineLabel(); var endLabel = beginLoopBlock(incrementLabel); markLabel(conditionLabel); emitBreakWhenFalse(endLabel, ts.createLessThan(keysIndex, ts.createPropertyAccess(keysArray, "length"))); var variable = void 0; if (ts.isVariableDeclarationList(initializer)) { for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) { var variable_1 = _a[_i]; hoistVariableDeclaration(variable_1.name); } variable = ts.getSynthesizedClone(initializer.declarations[0].name); } else { variable = ts.visitNode(initializer, visitor, ts.isExpression); ts.Debug.assert(ts.isLeftHandSideExpression(variable)); } emitAssignment(variable, ts.createElementAccess(keysArray, keysIndex)); transformAndEmitEmbeddedStatement(node.statement); markLabel(incrementLabel); emitStatement(ts.createStatement(ts.createPostfixIncrement(keysIndex))); emitBreak(conditionLabel); endLoopBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitForInStatement(node) { // [source] // for (var x in a) { // /*body*/ // } // // [intermediate] // .local x // .loop // for (x in a) { // /*body*/ // } // .endloop if (inStatementContainingYield) { beginScriptLoopBlock(); } var initializer = node.initializer; if (ts.isVariableDeclarationList(initializer)) { for (var _i = 0, _a = initializer.declarations; _i < _a.length; _i++) { var variable = _a[_i]; hoistVariableDeclaration(variable.name); } node = ts.updateForIn(node, initializer.declarations[0].name, ts.visitNode(node.expression, visitor, ts.isExpression), ts.visitNode(node.statement, visitor, ts.isStatement, ts.liftToBlock)); } else { node = ts.visitEachChild(node, visitor, context); } if (inStatementContainingYield) { endLoopBlock(); } return node; } function transformAndEmitContinueStatement(node) { var label = findContinueTarget(node.label ? ts.idText(node.label) : undefined); if (label > 0) { emitBreak(label, /*location*/ node); } else { // invalid continue without a containing loop. Leave the node as is, per #17875. emitStatement(node); } } function visitContinueStatement(node) { if (inStatementContainingYield) { var label = findContinueTarget(node.label && ts.idText(node.label)); if (label > 0) { return createInlineBreak(label, /*location*/ node); } } return ts.visitEachChild(node, visitor, context); } function transformAndEmitBreakStatement(node) { var label = findBreakTarget(node.label ? ts.idText(node.label) : undefined); if (label > 0) { emitBreak(label, /*location*/ node); } else { // invalid break without a containing loop, switch, or labeled statement. Leave the node as is, per #17875. emitStatement(node); } } function visitBreakStatement(node) { if (inStatementContainingYield) { var label = findBreakTarget(node.label && ts.idText(node.label)); if (label > 0) { return createInlineBreak(label, /*location*/ node); } } return ts.visitEachChild(node, visitor, context); } function transformAndEmitReturnStatement(node) { emitReturn(ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node); } function visitReturnStatement(node) { return createInlineReturn(ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node); } function transformAndEmitWithStatement(node) { if (containsYield(node)) { // [source] // with (x) { // /*body*/ // } // // [intermediate] // .with (x) // /*body*/ // .endwith beginWithBlock(cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression))); transformAndEmitEmbeddedStatement(node.statement); endWithBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function transformAndEmitSwitchStatement(node) { if (containsYield(node.caseBlock)) { // [source] // switch (x) { // case a: // /*caseStatements*/ // case b: // /*caseStatements*/ // default: // /*defaultStatements*/ // } // // [intermediate] // .local _a // .switch endLabel // _a = x; // switch (_a) { // case a: // .br clauseLabels[0] // } // switch (_a) { // case b: // .br clauseLabels[1] // } // .br clauseLabels[2] // .mark clauseLabels[0] // /*caseStatements*/ // .mark clauseLabels[1] // /*caseStatements*/ // .mark clauseLabels[2] // /*caseStatements*/ // .endswitch // .mark endLabel var caseBlock = node.caseBlock; var numClauses = caseBlock.clauses.length; var endLabel = beginSwitchBlock(); var expression = cacheExpression(ts.visitNode(node.expression, visitor, ts.isExpression)); // Create labels for each clause and find the index of the first default clause. var clauseLabels = []; var defaultClauseIndex = -1; for (var i = 0; i < numClauses; i++) { var clause = caseBlock.clauses[i]; clauseLabels.push(defineLabel()); if (clause.kind === 262 /* DefaultClause */ && defaultClauseIndex === -1) { defaultClauseIndex = i; } } // Emit switch statements for each run of case clauses either from the first case // clause or the next case clause with a `yield` in its expression, up to the next // case clause with a `yield` in its expression. var clausesWritten = 0; var pendingClauses = []; while (clausesWritten < numClauses) { var defaultClausesSkipped = 0; for (var i = clausesWritten; i < numClauses; i++) { var clause = caseBlock.clauses[i]; if (clause.kind === 261 /* CaseClause */) { var caseClause = clause; if (containsYield(caseClause.expression) && pendingClauses.length > 0) { break; } pendingClauses.push(ts.createCaseClause(ts.visitNode(caseClause.expression, visitor, ts.isExpression), [ createInlineBreak(clauseLabels[i], /*location*/ caseClause.expression) ])); } else { defaultClausesSkipped++; } } if (pendingClauses.length) { emitStatement(ts.createSwitch(expression, ts.createCaseBlock(pendingClauses))); clausesWritten += pendingClauses.length; pendingClauses = []; } if (defaultClausesSkipped > 0) { clausesWritten += defaultClausesSkipped; defaultClausesSkipped = 0; } } if (defaultClauseIndex >= 0) { emitBreak(clauseLabels[defaultClauseIndex]); } else { emitBreak(endLabel); } for (var i = 0; i < numClauses; i++) { markLabel(clauseLabels[i]); transformAndEmitStatements(caseBlock.clauses[i].statements); } endSwitchBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitSwitchStatement(node) { if (inStatementContainingYield) { beginScriptSwitchBlock(); } node = ts.visitEachChild(node, visitor, context); if (inStatementContainingYield) { endSwitchBlock(); } return node; } function transformAndEmitLabeledStatement(node) { if (containsYield(node)) { // [source] // x: { // /*body*/ // } // // [intermediate] // .labeled "x", endLabel // /*body*/ // .endlabeled // .mark endLabel beginLabeledBlock(ts.idText(node.label)); transformAndEmitEmbeddedStatement(node.statement); endLabeledBlock(); } else { emitStatement(ts.visitNode(node, visitor, ts.isStatement)); } } function visitLabeledStatement(node) { if (inStatementContainingYield) { beginScriptLabeledBlock(ts.idText(node.label)); } node = ts.visitEachChild(node, visitor, context); if (inStatementContainingYield) { endLabeledBlock(); } return node; } function transformAndEmitThrowStatement(node) { emitThrow(ts.visitNode(node.expression, visitor, ts.isExpression), /*location*/ node); } function transformAndEmitTryStatement(node) { if (containsYield(node)) { // [source] // try { // /*tryBlock*/ // } // catch (e) { // /*catchBlock*/ // } // finally { // /*finallyBlock*/ // } // // [intermediate] // .local _a // .try tryLabel, catchLabel, finallyLabel, endLabel // .mark tryLabel // .nop // /*tryBlock*/ // .br endLabel // .catch // .mark catchLabel // _a = %error%; // /*catchBlock*/ // .br endLabel // .finally // .mark finallyLabel // /*finallyBlock*/ // .endfinally // .endtry // .mark endLabel beginExceptionBlock(); transformAndEmitEmbeddedStatement(node.tryBlock); if (node.catchClause) { beginCatchBlock(node.catchClause.variableDeclaration); transformAndEmitEmbeddedStatement(node.catchClause.block); } if (node.finallyBlock) { beginFinallyBlock(); transformAndEmitEmbeddedStatement(node.finallyBlock); } endExceptionBlock(); } else { emitStatement(ts.visitEachChild(node, visitor, context)); } } function containsYield(node) { return node && (node.transformFlags & 16777216 /* ContainsYield */) !== 0; } function countInitialNodesWithoutYield(nodes) { var numNodes = nodes.length; for (var i = 0; i < numNodes; i++) { if (containsYield(nodes[i])) { return i; } } return -1; } function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (hint === 1 /* Expression */) { return substituteExpression(node); } return node; } function substituteExpression(node) { if (ts.isIdentifier(node)) { return substituteExpressionIdentifier(node); } return node; } function substituteExpressionIdentifier(node) { if (!ts.isGeneratedIdentifier(node) && renamedCatchVariables && renamedCatchVariables.has(ts.idText(node))) { var original = ts.getOriginalNode(node); if (ts.isIdentifier(original) && original.parent) { var declaration = resolver.getReferencedValueDeclaration(original); if (declaration) { var name = renamedCatchVariableDeclarations[ts.getOriginalNodeId(declaration)]; if (name) { var clone_6 = ts.getMutableClone(name); ts.setSourceMapRange(clone_6, node); ts.setCommentRange(clone_6, node); return clone_6; } } } } return node; } function cacheExpression(node) { var temp; if (ts.isGeneratedIdentifier(node) || ts.getEmitFlags(node) & 4096 /* HelperName */) { return node; } temp = ts.createTempVariable(hoistVariableDeclaration); emitAssignment(temp, node, /*location*/ node); return temp; } function declareLocal(name) { var temp = name ? ts.createUniqueName(name) : ts.createTempVariable(/*recordTempVariable*/ undefined); hoistVariableDeclaration(temp); return temp; } /** * Defines a label, uses as the target of a Break operation. */ function defineLabel() { if (!labelOffsets) { labelOffsets = []; } var label = nextLabelId; nextLabelId++; labelOffsets[label] = -1; return label; } /** * Marks the current operation with the specified label. */ function markLabel(label) { ts.Debug.assert(labelOffsets !== undefined, "No labels were defined."); labelOffsets[label] = operations ? operations.length : 0; } /** * Begins a block operation (With, Break/Continue, Try/Catch/Finally) * * @param block Information about the block. */ function beginBlock(block) { if (!blocks) { blocks = []; blockActions = []; blockOffsets = []; blockStack = []; } var index = blockActions.length; blockActions[index] = 0 /* Open */; blockOffsets[index] = operations ? operations.length : 0; blocks[index] = block; blockStack.push(block); return index; } /** * Ends the current block operation. */ function endBlock() { var block = peekBlock(); ts.Debug.assert(block !== undefined, "beginBlock was never called."); var index = blockActions.length; blockActions[index] = 1 /* Close */; blockOffsets[index] = operations ? operations.length : 0; blocks[index] = block; blockStack.pop(); return block; } /** * Gets the current open block. */ function peekBlock() { return ts.lastOrUndefined(blockStack); } /** * Gets the kind of the current open block. */ function peekBlockKind() { var block = peekBlock(); return block && block.kind; } /** * Begins a code block for a generated `with` statement. * * @param expression An identifier representing expression for the `with` block. */ function beginWithBlock(expression) { var startLabel = defineLabel(); var endLabel = defineLabel(); markLabel(startLabel); beginBlock({ kind: 1 /* With */, expression: expression, startLabel: startLabel, endLabel: endLabel }); } /** * Ends a code block for a generated `with` statement. */ function endWithBlock() { ts.Debug.assert(peekBlockKind() === 1 /* With */); var block = endBlock(); markLabel(block.endLabel); } /** * Begins a code block for a generated `try` statement. */ function beginExceptionBlock() { var startLabel = defineLabel(); var endLabel = defineLabel(); markLabel(startLabel); beginBlock({ kind: 0 /* Exception */, state: 0 /* Try */, startLabel: startLabel, endLabel: endLabel }); emitNop(); return endLabel; } /** * Enters the `catch` clause of a generated `try` statement. * * @param variable The catch variable. */ function beginCatchBlock(variable) { ts.Debug.assert(peekBlockKind() === 0 /* Exception */); // generated identifiers should already be unique within a file var name; if (ts.isGeneratedIdentifier(variable.name)) { name = variable.name; hoistVariableDeclaration(variable.name); } else { var text = ts.idText(variable.name); name = declareLocal(text); if (!renamedCatchVariables) { renamedCatchVariables = ts.createMap(); renamedCatchVariableDeclarations = []; context.enableSubstitution(71 /* Identifier */); } renamedCatchVariables.set(text, true); renamedCatchVariableDeclarations[ts.getOriginalNodeId(variable)] = name; } var exception = peekBlock(); ts.Debug.assert(exception.state < 1 /* Catch */); var endLabel = exception.endLabel; emitBreak(endLabel); var catchLabel = defineLabel(); markLabel(catchLabel); exception.state = 1 /* Catch */; exception.catchVariable = name; exception.catchLabel = catchLabel; emitAssignment(name, ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, [])); emitNop(); } /** * Enters the `finally` block of a generated `try` statement. */ function beginFinallyBlock() { ts.Debug.assert(peekBlockKind() === 0 /* Exception */); var exception = peekBlock(); ts.Debug.assert(exception.state < 2 /* Finally */); var endLabel = exception.endLabel; emitBreak(endLabel); var finallyLabel = defineLabel(); markLabel(finallyLabel); exception.state = 2 /* Finally */; exception.finallyLabel = finallyLabel; } /** * Ends the code block for a generated `try` statement. */ function endExceptionBlock() { ts.Debug.assert(peekBlockKind() === 0 /* Exception */); var exception = endBlock(); var state = exception.state; if (state < 2 /* Finally */) { emitBreak(exception.endLabel); } else { emitEndfinally(); } markLabel(exception.endLabel); emitNop(); exception.state = 3 /* Done */; } /** * Begins a code block that supports `break` or `continue` statements that are defined in * the source tree and not from generated code. * * @param labelText Names from containing labeled statements. */ function beginScriptLoopBlock() { beginBlock({ kind: 3 /* Loop */, isScript: true, breakLabel: -1, continueLabel: -1 }); } /** * Begins a code block that supports `break` or `continue` statements that are defined in * generated code. Returns a label used to mark the operation to which to jump when a * `break` statement targets this block. * * @param continueLabel A Label used to mark the operation to which to jump when a * `continue` statement targets this block. */ function beginLoopBlock(continueLabel) { var breakLabel = defineLabel(); beginBlock({ kind: 3 /* Loop */, isScript: false, breakLabel: breakLabel, continueLabel: continueLabel, }); return breakLabel; } /** * Ends a code block that supports `break` or `continue` statements that are defined in * generated code or in the source tree. */ function endLoopBlock() { ts.Debug.assert(peekBlockKind() === 3 /* Loop */); var block = endBlock(); var breakLabel = block.breakLabel; if (!block.isScript) { markLabel(breakLabel); } } /** * Begins a code block that supports `break` statements that are defined in the source * tree and not from generated code. * */ function beginScriptSwitchBlock() { beginBlock({ kind: 2 /* Switch */, isScript: true, breakLabel: -1 }); } /** * Begins a code block that supports `break` statements that are defined in generated code. * Returns a label used to mark the operation to which to jump when a `break` statement * targets this block. */ function beginSwitchBlock() { var breakLabel = defineLabel(); beginBlock({ kind: 2 /* Switch */, isScript: false, breakLabel: breakLabel, }); return breakLabel; } /** * Ends a code block that supports `break` statements that are defined in generated code. */ function endSwitchBlock() { ts.Debug.assert(peekBlockKind() === 2 /* Switch */); var block = endBlock(); var breakLabel = block.breakLabel; if (!block.isScript) { markLabel(breakLabel); } } function beginScriptLabeledBlock(labelText) { beginBlock({ kind: 4 /* Labeled */, isScript: true, labelText: labelText, breakLabel: -1 }); } function beginLabeledBlock(labelText) { var breakLabel = defineLabel(); beginBlock({ kind: 4 /* Labeled */, isScript: false, labelText: labelText, breakLabel: breakLabel }); } function endLabeledBlock() { ts.Debug.assert(peekBlockKind() === 4 /* Labeled */); var block = endBlock(); if (!block.isScript) { markLabel(block.breakLabel); } } /** * Indicates whether the provided block supports `break` statements. * * @param block A code block. */ function supportsUnlabeledBreak(block) { return block.kind === 2 /* Switch */ || block.kind === 3 /* Loop */; } /** * Indicates whether the provided block supports `break` statements with labels. * * @param block A code block. */ function supportsLabeledBreakOrContinue(block) { return block.kind === 4 /* Labeled */; } /** * Indicates whether the provided block supports `continue` statements. * * @param block A code block. */ function supportsUnlabeledContinue(block) { return block.kind === 3 /* Loop */; } function hasImmediateContainingLabeledBlock(labelText, start) { for (var j = start; j >= 0; j--) { var containingBlock = blockStack[j]; if (supportsLabeledBreakOrContinue(containingBlock)) { if (containingBlock.labelText === labelText) { return true; } } else { break; } } return false; } /** * Finds the label that is the target for a `break` statement. * * @param labelText An optional name of a containing labeled statement. */ function findBreakTarget(labelText) { if (blockStack) { if (labelText) { for (var i = blockStack.length - 1; i >= 0; i--) { var block = blockStack[i]; if (supportsLabeledBreakOrContinue(block) && block.labelText === labelText) { return block.breakLabel; } else if (supportsUnlabeledBreak(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { return block.breakLabel; } } } else { for (var i = blockStack.length - 1; i >= 0; i--) { var block = blockStack[i]; if (supportsUnlabeledBreak(block)) { return block.breakLabel; } } } } return 0; } /** * Finds the label that is the target for a `continue` statement. * * @param labelText An optional name of a containing labeled statement. */ function findContinueTarget(labelText) { if (blockStack) { if (labelText) { for (var i = blockStack.length - 1; i >= 0; i--) { var block = blockStack[i]; if (supportsUnlabeledContinue(block) && hasImmediateContainingLabeledBlock(labelText, i - 1)) { return block.continueLabel; } } } else { for (var i = blockStack.length - 1; i >= 0; i--) { var block = blockStack[i]; if (supportsUnlabeledContinue(block)) { return block.continueLabel; } } } } return 0; } /** * Creates an expression that can be used to indicate the value for a label. * * @param label A label. */ function createLabel(label) { if (label > 0) { if (labelExpressions === undefined) { labelExpressions = []; } var expression = ts.createLiteral(-1); if (labelExpressions[label] === undefined) { labelExpressions[label] = [expression]; } else { labelExpressions[label].push(expression); } return expression; } return ts.createOmittedExpression(); } /** * Creates a numeric literal for the provided instruction. */ function createInstruction(instruction) { var literal = ts.createLiteral(instruction); ts.addSyntheticTrailingComment(literal, 3 /* MultiLineCommentTrivia */, getInstructionName(instruction)); return literal; } /** * Creates a statement that can be used indicate a Break operation to the provided label. * * @param label A label. * @param location An optional source map location for the statement. */ function createInlineBreak(label, location) { ts.Debug.assertLessThan(0, label, "Invalid label"); return ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) ])), location); } /** * Creates a statement that can be used indicate a Return operation. * * @param expression The expression for the return statement. * @param location An optional source map location for the statement. */ function createInlineReturn(expression, location) { return ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression ? [createInstruction(2 /* Return */), expression] : [createInstruction(2 /* Return */)])), location); } /** * Creates an expression that can be used to resume from a Yield operation. */ function createGeneratorResume(location) { return ts.setTextRange(ts.createCall(ts.createPropertyAccess(state, "sent"), /*typeArguments*/ undefined, []), location); } /** * Emits an empty instruction. */ function emitNop() { emitWorker(0 /* Nop */); } /** * Emits a Statement. * * @param node A statement. */ function emitStatement(node) { if (node) { emitWorker(1 /* Statement */, [node]); } else { emitNop(); } } /** * Emits an Assignment operation. * * @param left The left-hand side of the assignment. * @param right The right-hand side of the assignment. * @param location An optional source map location for the assignment. */ function emitAssignment(left, right, location) { emitWorker(2 /* Assign */, [left, right], location); } /** * Emits a Break operation to the specified label. * * @param label A label. * @param location An optional source map location for the assignment. */ function emitBreak(label, location) { emitWorker(3 /* Break */, [label], location); } /** * Emits a Break operation to the specified label when a condition evaluates to a truthy * value at runtime. * * @param label A label. * @param condition The condition. * @param location An optional source map location for the assignment. */ function emitBreakWhenTrue(label, condition, location) { emitWorker(4 /* BreakWhenTrue */, [label, condition], location); } /** * Emits a Break to the specified label when a condition evaluates to a falsey value at * runtime. * * @param label A label. * @param condition The condition. * @param location An optional source map location for the assignment. */ function emitBreakWhenFalse(label, condition, location) { emitWorker(5 /* BreakWhenFalse */, [label, condition], location); } /** * Emits a YieldStar operation for the provided expression. * * @param expression An optional value for the yield operation. * @param location An optional source map location for the assignment. */ function emitYieldStar(expression, location) { emitWorker(7 /* YieldStar */, [expression], location); } /** * Emits a Yield operation for the provided expression. * * @param expression An optional value for the yield operation. * @param location An optional source map location for the assignment. */ function emitYield(expression, location) { emitWorker(6 /* Yield */, [expression], location); } /** * Emits a Return operation for the provided expression. * * @param expression An optional value for the operation. * @param location An optional source map location for the assignment. */ function emitReturn(expression, location) { emitWorker(8 /* Return */, [expression], location); } /** * Emits a Throw operation for the provided expression. * * @param expression A value for the operation. * @param location An optional source map location for the assignment. */ function emitThrow(expression, location) { emitWorker(9 /* Throw */, [expression], location); } /** * Emits an Endfinally operation. This is used to handle `finally` block semantics. */ function emitEndfinally() { emitWorker(10 /* Endfinally */); } /** * Emits an operation. * * @param code The OpCode for the operation. * @param args The optional arguments for the operation. */ function emitWorker(code, args, location) { if (operations === undefined) { operations = []; operationArguments = []; operationLocations = []; } if (labelOffsets === undefined) { // mark entry point markLabel(defineLabel()); } var operationIndex = operations.length; operations[operationIndex] = code; operationArguments[operationIndex] = args; operationLocations[operationIndex] = location; } /** * Builds the generator function body. */ function build() { blockIndex = 0; labelNumber = 0; labelNumbers = undefined; lastOperationWasAbrupt = false; lastOperationWasCompletion = false; clauses = undefined; statements = undefined; exceptionBlockStack = undefined; currentExceptionBlock = undefined; withBlockStack = undefined; var buildResult = buildStatements(); return createGeneratorHelper(context, ts.setEmitFlags(ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)], /*type*/ undefined, ts.createBlock(buildResult, /*multiLine*/ buildResult.length > 0)), 524288 /* ReuseTempVariableScope */)); } /** * Builds the statements for the generator function body. */ function buildStatements() { if (operations) { for (var operationIndex = 0; operationIndex < operations.length; operationIndex++) { writeOperation(operationIndex); } flushFinalLabel(operations.length); } else { flushFinalLabel(0); } if (clauses) { var labelExpression = ts.createPropertyAccess(state, "label"); var switchStatement = ts.createSwitch(labelExpression, ts.createCaseBlock(clauses)); return [ts.startOnNewLine(switchStatement)]; } if (statements) { return statements; } return []; } /** * Flush the current label and advance to a new label. */ function flushLabel() { if (!statements) { return; } appendLabel(/*markLabelEnd*/ !lastOperationWasAbrupt); lastOperationWasAbrupt = false; lastOperationWasCompletion = false; labelNumber++; } /** * Flush the final label of the generator function body. */ function flushFinalLabel(operationIndex) { if (isFinalLabelReachable(operationIndex)) { tryEnterLabel(operationIndex); withBlockStack = undefined; writeReturn(/*expression*/ undefined, /*operationLocation*/ undefined); } if (statements && clauses) { appendLabel(/*markLabelEnd*/ false); } updateLabelExpressions(); } /** * Tests whether the final label of the generator function body * is reachable by user code. */ function isFinalLabelReachable(operationIndex) { // if the last operation was *not* a completion (return/throw) then // the final label is reachable. if (!lastOperationWasCompletion) { return true; } // if there are no labels defined or referenced, then the final label is // not reachable. if (!labelOffsets || !labelExpressions) { return false; } // if the label for this offset is referenced, then the final label // is reachable. for (var label = 0; label < labelOffsets.length; label++) { if (labelOffsets[label] === operationIndex && labelExpressions[label]) { return true; } } return false; } /** * Appends a case clause for the last label and sets the new label. * * @param markLabelEnd Indicates that the transition between labels was a fall-through * from a previous case clause and the change in labels should be * reflected on the `state` object. */ function appendLabel(markLabelEnd) { if (!clauses) { clauses = []; } if (statements) { if (withBlockStack) { // The previous label was nested inside one or more `with` blocks, so we // surround the statements in generated `with` blocks to create the same environment. for (var i = withBlockStack.length - 1; i >= 0; i--) { var withBlock = withBlockStack[i]; statements = [ts.createWith(withBlock.expression, ts.createBlock(statements))]; } } if (currentExceptionBlock) { // The previous label was nested inside of an exception block, so we must // indicate entry into a protected region by pushing the label numbers // for each block in the protected region. var startLabel = currentExceptionBlock.startLabel, catchLabel = currentExceptionBlock.catchLabel, finallyLabel = currentExceptionBlock.finallyLabel, endLabel = currentExceptionBlock.endLabel; statements.unshift(ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createPropertyAccess(state, "trys"), "push"), /*typeArguments*/ undefined, [ ts.createArrayLiteral([ createLabel(startLabel), createLabel(catchLabel), createLabel(finallyLabel), createLabel(endLabel) ]) ]))); currentExceptionBlock = undefined; } if (markLabelEnd) { // The case clause for the last label falls through to this label, so we // add an assignment statement to reflect the change in labels. statements.push(ts.createStatement(ts.createAssignment(ts.createPropertyAccess(state, "label"), ts.createLiteral(labelNumber + 1)))); } } clauses.push(ts.createCaseClause(ts.createLiteral(labelNumber), statements || [])); statements = undefined; } /** * Tries to enter into a new label at the current operation index. */ function tryEnterLabel(operationIndex) { if (!labelOffsets) { return; } for (var label = 0; label < labelOffsets.length; label++) { if (labelOffsets[label] === operationIndex) { flushLabel(); if (labelNumbers === undefined) { labelNumbers = []; } if (labelNumbers[labelNumber] === undefined) { labelNumbers[labelNumber] = [label]; } else { labelNumbers[labelNumber].push(label); } } } } /** * Updates literal expressions for labels with actual label numbers. */ function updateLabelExpressions() { if (labelExpressions !== undefined && labelNumbers !== undefined) { for (var labelNumber_1 = 0; labelNumber_1 < labelNumbers.length; labelNumber_1++) { var labels = labelNumbers[labelNumber_1]; if (labels !== undefined) { for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) { var label = labels_1[_i]; var expressions = labelExpressions[label]; if (expressions !== undefined) { for (var _a = 0, expressions_1 = expressions; _a < expressions_1.length; _a++) { var expression = expressions_1[_a]; expression.text = String(labelNumber_1); } } } } } } } /** * Tries to enter or leave a code block. */ function tryEnterOrLeaveBlock(operationIndex) { if (blocks) { for (; blockIndex < blockActions.length && blockOffsets[blockIndex] <= operationIndex; blockIndex++) { var block = blocks[blockIndex]; var blockAction = blockActions[blockIndex]; switch (block.kind) { case 0 /* Exception */: if (blockAction === 0 /* Open */) { if (!exceptionBlockStack) { exceptionBlockStack = []; } if (!statements) { statements = []; } exceptionBlockStack.push(currentExceptionBlock); currentExceptionBlock = block; } else if (blockAction === 1 /* Close */) { currentExceptionBlock = exceptionBlockStack.pop(); } break; case 1 /* With */: if (blockAction === 0 /* Open */) { if (!withBlockStack) { withBlockStack = []; } withBlockStack.push(block); } else if (blockAction === 1 /* Close */) { withBlockStack.pop(); } break; } } } } /** * Writes an operation as a statement to the current label's statement list. * * @param operation The OpCode of the operation */ function writeOperation(operationIndex) { tryEnterLabel(operationIndex); tryEnterOrLeaveBlock(operationIndex); // early termination, nothing else to process in this label if (lastOperationWasAbrupt) { return; } lastOperationWasAbrupt = false; lastOperationWasCompletion = false; var opcode = operations[operationIndex]; if (opcode === 0 /* Nop */) { return; } else if (opcode === 10 /* Endfinally */) { return writeEndfinally(); } var args = operationArguments[operationIndex]; if (opcode === 1 /* Statement */) { return writeStatement(args[0]); } var location = operationLocations[operationIndex]; switch (opcode) { case 2 /* Assign */: return writeAssign(args[0], args[1], location); case 3 /* Break */: return writeBreak(args[0], location); case 4 /* BreakWhenTrue */: return writeBreakWhenTrue(args[0], args[1], location); case 5 /* BreakWhenFalse */: return writeBreakWhenFalse(args[0], args[1], location); case 6 /* Yield */: return writeYield(args[0], location); case 7 /* YieldStar */: return writeYieldStar(args[0], location); case 8 /* Return */: return writeReturn(args[0], location); case 9 /* Throw */: return writeThrow(args[0], location); } } /** * Writes a statement to the current label's statement list. * * @param statement A statement to write. */ function writeStatement(statement) { if (statement) { if (!statements) { statements = [statement]; } else { statements.push(statement); } } } /** * Writes an Assign operation to the current label's statement list. * * @param left The left-hand side of the assignment. * @param right The right-hand side of the assignment. * @param operationLocation The source map location for the operation. */ function writeAssign(left, right, operationLocation) { writeStatement(ts.setTextRange(ts.createStatement(ts.createAssignment(left, right)), operationLocation)); } /** * Writes a Throw operation to the current label's statement list. * * @param expression The value to throw. * @param operationLocation The source map location for the operation. */ function writeThrow(expression, operationLocation) { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; writeStatement(ts.setTextRange(ts.createThrow(expression), operationLocation)); } /** * Writes a Return operation to the current label's statement list. * * @param expression The value to return. * @param operationLocation The source map location for the operation. */ function writeReturn(expression, operationLocation) { lastOperationWasAbrupt = true; lastOperationWasCompletion = true; writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression ? [createInstruction(2 /* Return */), expression] : [createInstruction(2 /* Return */)])), operationLocation), 384 /* NoTokenSourceMaps */)); } /** * Writes a Break operation to the current label's statement list. * * @param label The label for the Break. * @param operationLocation The source map location for the operation. */ function writeBreak(label, operationLocation) { lastOperationWasAbrupt = true; writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) ])), operationLocation), 384 /* NoTokenSourceMaps */)); } /** * Writes a BreakWhenTrue operation to the current label's statement list. * * @param label The label for the Break. * @param condition The condition for the Break. * @param operationLocation The source map location for the operation. */ function writeBreakWhenTrue(label, condition, operationLocation) { writeStatement(ts.setEmitFlags(ts.createIf(condition, ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */)); } /** * Writes a BreakWhenFalse operation to the current label's statement list. * * @param label The label for the Break. * @param condition The condition for the Break. * @param operationLocation The source map location for the operation. */ function writeBreakWhenFalse(label, condition, operationLocation) { writeStatement(ts.setEmitFlags(ts.createIf(ts.createLogicalNot(condition), ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(3 /* Break */), createLabel(label) ])), operationLocation), 384 /* NoTokenSourceMaps */)), 1 /* SingleLine */)); } /** * Writes a Yield operation to the current label's statement list. * * @param expression The expression to yield. * @param operationLocation The source map location for the operation. */ function writeYield(expression, operationLocation) { lastOperationWasAbrupt = true; writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral(expression ? [createInstruction(4 /* Yield */), expression] : [createInstruction(4 /* Yield */)])), operationLocation), 384 /* NoTokenSourceMaps */)); } /** * Writes a YieldStar instruction to the current label's statement list. * * @param expression The expression to yield. * @param operationLocation The source map location for the operation. */ function writeYieldStar(expression, operationLocation) { lastOperationWasAbrupt = true; writeStatement(ts.setEmitFlags(ts.setTextRange(ts.createReturn(ts.createArrayLiteral([ createInstruction(5 /* YieldStar */), expression ])), operationLocation), 384 /* NoTokenSourceMaps */)); } /** * Writes an Endfinally instruction to the current label's statement list. */ function writeEndfinally() { lastOperationWasAbrupt = true; writeStatement(ts.createReturn(ts.createArrayLiteral([ createInstruction(7 /* Endfinally */) ]))); } } ts.transformGenerators = transformGenerators; function createGeneratorHelper(context, body) { context.requestEmitHelper(generatorHelper); return ts.createCall(ts.getHelperName("__generator"), /*typeArguments*/ undefined, [ts.createThis(), body]); } // The __generator helper is used by down-level transformations to emulate the runtime // semantics of an ES2015 generator function. When called, this helper returns an // object that implements the Iterator protocol, in that it has `next`, `return`, and // `throw` methods that step through the generator when invoked. // // parameters: // thisArg The value to use as the `this` binding for the transformed generator body. // body A function that acts as the transformed generator body. // // variables: // _ Persistent state for the generator that is shared between the helper and the // generator body. The state object has the following members: // sent() - A method that returns or throws the current completion value. // label - The next point at which to resume evaluation of the generator body. // trys - A stack of protected regions (try/catch/finally blocks). // ops - A stack of pending instructions when inside of a finally block. // f A value indicating whether the generator is executing. // y An iterator to delegate for a yield*. // t A temporary variable that holds one of the following values (note that these // cases do not overlap): // - The completion value when resuming from a `yield` or `yield*`. // - The error value for a catch block. // - The current protected region (array of try/catch/finally/end labels). // - The verb (`next`, `throw`, or `return` method) to delegate to the expression // of a `yield*`. // - The result of evaluating the verb delegated to the expression of a `yield*`. // // functions: // verb(n) Creates a bound callback to the `step` function for opcode `n`. // step(op) Evaluates opcodes in a generator body until execution is suspended or // completed. // // The __generator helper understands a limited set of instructions: // 0: next(value?) - Start or resume the generator with the specified value. // 1: throw(error) - Resume the generator with an exception. If the generator is // suspended inside of one or more protected regions, evaluates // any intervening finally blocks between the current label and // the nearest catch block or function boundary. If uncaught, the // exception is thrown to the caller. // 2: return(value?) - Resume the generator as if with a return. If the generator is // suspended inside of one or more protected regions, evaluates any // intervening finally blocks. // 3: break(label) - Jump to the specified label. If the label is outside of the // current protected region, evaluates any intervening finally // blocks. // 4: yield(value?) - Yield execution to the caller with an optional value. When // resumed, the generator will continue at the next label. // 5: yield*(value) - Delegates evaluation to the supplied iterator. When // delegation completes, the generator will continue at the next // label. // 6: catch(error) - Handles an exception thrown from within the generator body. If // the current label is inside of one or more protected regions, // evaluates any intervening finally blocks between the current // label and the nearest catch block or function boundary. If // uncaught, the exception is thrown to the caller. // 7: endfinally - Ends a finally block, resuming the last instruction prior to // entering a finally block. // // For examples of how these are used, see the comments in ./transformers/generators.ts var generatorHelper = { name: "typescript:generator", scoped: false, priority: 6, text: "\n var __generator = (this && this.__generator) || function (thisArg, body) {\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\n function verb(n) { return function (v) { return step([n, v]); }; }\n function step(op) {\n if (f) throw new TypeError(\"Generator is already executing.\");\n while (_) try {\n if (f = 1, y && (t = y[op[0] & 2 ? \"return\" : op[0] ? \"throw\" : \"next\"]) && !(t = t.call(y, op[1])).done) return t;\n if (y = 0, t) op = [0, t.value];\n switch (op[0]) {\n case 0: case 1: t = op; break;\n case 4: _.label++; return { value: op[1], done: false };\n case 5: _.label++; y = op[1]; op = [0]; continue;\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\n default:\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n if (t[2]) _.ops.pop();\n _.trys.pop(); continue;\n }\n op = body.call(thisArg, _);\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\n }\n };" }; })(ts || (ts = {})); /// /// /*@internal*/ var ts; (function (ts) { /** * Transforms ES5 syntax into ES3 syntax. * * @param context Context and state information for the transformation. */ function transformES5(context) { var compilerOptions = context.getCompilerOptions(); // enable emit notification only if using --jsx preserve or react-native var previousOnEmitNode; var noSubstitution; if (compilerOptions.jsx === 1 /* Preserve */ || compilerOptions.jsx === 3 /* ReactNative */) { previousOnEmitNode = context.onEmitNode; context.onEmitNode = onEmitNode; context.enableEmitNotification(252 /* JsxOpeningElement */); context.enableEmitNotification(253 /* JsxClosingElement */); context.enableEmitNotification(251 /* JsxSelfClosingElement */); noSubstitution = []; } var previousOnSubstituteNode = context.onSubstituteNode; context.onSubstituteNode = onSubstituteNode; context.enableSubstitution(180 /* PropertyAccessExpression */); context.enableSubstitution(265 /* PropertyAssignment */); return transformSourceFile; /** * Transforms an ES5 source file to ES3. * * @param node A SourceFile */ function transformSourceFile(node) { return node; } /** * Called by the printer just before a node is printed. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback A callback used to emit the node. */ function onEmitNode(hint, node, emitCallback) { switch (node.kind) { case 252 /* JsxOpeningElement */: case 253 /* JsxClosingElement */: case 251 /* JsxSelfClosingElement */: var tagName = node.tagName; noSubstitution[ts.getOriginalNodeId(tagName)] = true; break; } previousOnEmitNode(hint, node, emitCallback); } /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { if (node.id && noSubstitution && noSubstitution[node.id]) { return previousOnSubstituteNode(hint, node); } node = previousOnSubstituteNode(hint, node); if (ts.isPropertyAccessExpression(node)) { return substitutePropertyAccessExpression(node); } else if (ts.isPropertyAssignment(node)) { return substitutePropertyAssignment(node); } return node; } /** * Substitutes a PropertyAccessExpression whose name is a reserved word. * * @param node A PropertyAccessExpression */ function substitutePropertyAccessExpression(node) { var literalName = trySubstituteReservedName(node.name); if (literalName) { return ts.setTextRange(ts.createElementAccess(node.expression, literalName), node); } return node; } /** * Substitutes a PropertyAssignment whose name is a reserved word. * * @param node A PropertyAssignment */ function substitutePropertyAssignment(node) { var literalName = ts.isIdentifier(node.name) && trySubstituteReservedName(node.name); if (literalName) { return ts.updatePropertyAssignment(node, literalName, node.initializer); } return node; } /** * If an identifier name is a reserved word, returns a string literal for the name. * * @param name An Identifier */ function trySubstituteReservedName(name) { var token = name.originalKeywordKind || (ts.nodeIsSynthesized(name) ? ts.stringToToken(ts.idText(name)) : undefined); if (token >= 72 /* FirstReservedWord */ && token <= 107 /* LastReservedWord */) { return ts.setTextRange(ts.createLiteral(name), name); } return undefined; } } ts.transformES5 = transformES5; })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { function transformModule(context) { function getTransformModuleDelegate(moduleKind) { switch (moduleKind) { case ts.ModuleKind.AMD: return transformAMDModule; case ts.ModuleKind.UMD: return transformUMDModule; default: return transformCommonJSModule; } } var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration; var compilerOptions = context.getCompilerOptions(); var resolver = context.getEmitResolver(); var host = context.getEmitHost(); var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); var previousOnSubstituteNode = context.onSubstituteNode; var previousOnEmitNode = context.onEmitNode; context.onSubstituteNode = onSubstituteNode; context.onEmitNode = onEmitNode; context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers with imported/exported symbols. context.enableSubstitution(195 /* BinaryExpression */); // Substitutes assignments to exported symbols. context.enableSubstitution(193 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols. context.enableSubstitution(194 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols. context.enableSubstitution(266 /* ShorthandPropertyAssignment */); // Substitutes shorthand property assignments for imported/exported symbols. context.enableEmitNotification(269 /* SourceFile */); // Restore state when substituting nodes in a file. var moduleInfoMap = []; // The ExternalModuleInfo for each file. var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found. var currentSourceFile; // The current file. var currentModuleInfo; // The ExternalModuleInfo for the current file. var noSubstitution; // Set of nodes for which substitution rules should be ignored. var needUMDDynamicImportHelper; return transformSourceFile; /** * Transforms the module aspects of a SourceFile. * * @param node The SourceFile node. */ function transformSourceFile(node) { if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 67108864 /* ContainsDynamicImport */)) { return node; } currentSourceFile = node; currentModuleInfo = ts.collectExternalModuleInfo(node, resolver, compilerOptions); moduleInfoMap[ts.getOriginalNodeId(node)] = currentModuleInfo; // Perform the transformation. var transformModule = getTransformModuleDelegate(moduleKind); var updated = transformModule(node); currentSourceFile = undefined; currentModuleInfo = undefined; needUMDDynamicImportHelper = false; return ts.aggregateTransformFlags(updated); } function shouldEmitUnderscoreUnderscoreESModule() { if (!currentModuleInfo.exportEquals && ts.isExternalModule(currentSourceFile)) { return true; } return false; } /** * Transforms a SourceFile into a CommonJS module. * * @param node The SourceFile node. */ function transformCommonJSModule(node) { startLexicalEnvironment(); var statements = []; var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile)); var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor); if (shouldEmitUnderscoreUnderscoreESModule()) { ts.append(statements, createUnderscoreUnderscoreESModule()); } ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement)); ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset)); addExportEqualsIfNeeded(statements, /*emitAsReturn*/ false); ts.addRange(statements, endLexicalEnvironment()); var updated = ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements)); if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. ts.addEmitHelper(updated, exportStarHelper); } ts.addEmitHelpers(updated, context.readEmitHelpers()); return updated; } /** * Transforms a SourceFile into an AMD module. * * @param node The SourceFile node. */ function transformAMDModule(node) { var define = ts.createIdentifier("define"); var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions); // An AMD define function has the following shape: // // define(id?, dependencies?, factory); // // This has the shape of the following: // // define(name, ["module1", "module2"], function (module1Alias) { ... } // // The location of the alias in the parameter list in the factory function needs to // match the position of the module name in the dependency list. // // To ensure this is true in cases of modules with no aliases, e.g.: // // import "module" // // or // // /// // // we need to add modules without alias names to the end of the dependencies list var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ true), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames; // Create an updated SourceFile: // // define(moduleName?, ["module1", "module2"], function ... return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([ ts.createStatement(ts.createCall(define, /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([ // Add the dependency array argument: // // ["require", "exports", module1", "module2", ...] ts.createArrayLiteral([ ts.createLiteral("require"), ts.createLiteral("exports") ].concat(aliasedModuleNames, unaliasedModuleNames)), // Add the module body function argument: // // function (require, exports, module1, module2) ... ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports") ].concat(importAliasNames), /*type*/ undefined, transformAsynchronousModuleBody(node)) ]))) ]), /*location*/ node.statements)); } /** * Transforms a SourceFile into a UMD module. * * @param node The SourceFile node. */ function transformUMDModule(node) { var _a = collectAsynchronousDependencies(node, /*includeNonAmdDependencies*/ false), aliasedModuleNames = _a.aliasedModuleNames, unaliasedModuleNames = _a.unaliasedModuleNames, importAliasNames = _a.importAliasNames; var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions); var umdHeader = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "factory")], /*type*/ undefined, ts.setTextRange(ts.createBlock([ ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("module"), "object"), ts.createTypeCheck(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), "object")), ts.createBlock([ ts.createVariableStatement( /*modifiers*/ undefined, [ ts.createVariableDeclaration("v", /*type*/ undefined, ts.createCall(ts.createIdentifier("factory"), /*typeArguments*/ undefined, [ ts.createIdentifier("require"), ts.createIdentifier("exports") ])) ]), ts.setEmitFlags(ts.createIf(ts.createStrictInequality(ts.createIdentifier("v"), ts.createIdentifier("undefined")), ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), ts.createIdentifier("v")))), 1 /* SingleLine */) ]), ts.createIf(ts.createLogicalAnd(ts.createTypeCheck(ts.createIdentifier("define"), "function"), ts.createPropertyAccess(ts.createIdentifier("define"), "amd")), ts.createBlock([ ts.createStatement(ts.createCall(ts.createIdentifier("define"), /*typeArguments*/ undefined, (moduleName ? [moduleName] : []).concat([ ts.createArrayLiteral([ ts.createLiteral("require"), ts.createLiteral("exports") ].concat(aliasedModuleNames, unaliasedModuleNames)), ts.createIdentifier("factory") ]))) ]))) ], /*multiLine*/ true), /*location*/ undefined)); // Create an updated SourceFile: // // (function (factory) { // if (typeof module === "object" && typeof module.exports === "object") { // var v = factory(require, exports); // if (v !== undefined) module.exports = v; // } // else if (typeof define === 'function' && define.amd) { // define(["require", "exports"], factory); // } // })(function ...) return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([ ts.createStatement(ts.createCall(umdHeader, /*typeArguments*/ undefined, [ // Add the module body function argument: // // function (require, exports) ... ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "require"), ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "exports") ].concat(importAliasNames), /*type*/ undefined, transformAsynchronousModuleBody(node)) ])) ]), /*location*/ node.statements)); } /** * Collect the additional asynchronous dependencies for the module. * * @param node The source file. * @param includeNonAmdDependencies A value indicating whether to include non-AMD dependencies. */ function collectAsynchronousDependencies(node, includeNonAmdDependencies) { // names of modules with corresponding parameter in the factory function var aliasedModuleNames = []; // names of modules with no corresponding parameters in factory function var unaliasedModuleNames = []; // names of the parameters in the factory function; these // parameters need to match the indexes of the corresponding // module names in aliasedModuleNames. var importAliasNames = []; // Fill in amd-dependency tags for (var _i = 0, _a = node.amdDependencies; _i < _a.length; _i++) { var amdDependency = _a[_i]; if (amdDependency.name) { aliasedModuleNames.push(ts.createLiteral(amdDependency.path)); importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, amdDependency.name)); } else { unaliasedModuleNames.push(ts.createLiteral(amdDependency.path)); } } for (var _b = 0, _c = currentModuleInfo.externalImports; _b < _c.length; _b++) { var importNode = _c[_b]; // Find the name of the external module var externalModuleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); // Find the name of the module alias, if there is one var importAliasName = ts.getLocalNameForExternalImport(importNode, currentSourceFile); // It is possible that externalModuleName is undefined if it is not string literal. // This can happen in the invalid import syntax. // E.g : "import * from alias from 'someLib';" if (externalModuleName) { if (includeNonAmdDependencies && importAliasName) { // Set emitFlags on the name of the classDeclaration // This is so that when printer will not substitute the identifier ts.setEmitFlags(importAliasName, 4 /* NoSubstitution */); aliasedModuleNames.push(externalModuleName); importAliasNames.push(ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, importAliasName)); } else { unaliasedModuleNames.push(externalModuleName); } } } return { aliasedModuleNames: aliasedModuleNames, unaliasedModuleNames: unaliasedModuleNames, importAliasNames: importAliasNames }; } /** * Transforms a SourceFile into an AMD or UMD module body. * * @param node The SourceFile node. */ function transformAsynchronousModuleBody(node) { startLexicalEnvironment(); var statements = []; var statementOffset = ts.addPrologue(statements, node.statements, /*ensureUseStrict*/ !compilerOptions.noImplicitUseStrict, sourceElementVisitor); if (shouldEmitUnderscoreUnderscoreESModule()) { ts.append(statements, createUnderscoreUnderscoreESModule()); } // Visit each statement of the module body. ts.append(statements, ts.visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement)); ts.addRange(statements, ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset)); // Append the 'export =' statement if provided. addExportEqualsIfNeeded(statements, /*emitAsReturn*/ true); // End the lexical environment for the module body // and merge any new lexical declarations. ts.addRange(statements, endLexicalEnvironment()); var body = ts.createBlock(statements, /*multiLine*/ true); if (currentModuleInfo.hasExportStarsToExportValues && !compilerOptions.importHelpers) { // If we have any `export * from ...` declarations // we need to inform the emitter to add the __export helper. ts.addEmitHelper(body, exportStarHelper); } if (needUMDDynamicImportHelper) { ts.addEmitHelper(body, dynamicImportUMDHelper); } return body; } /** * Adds the down-level representation of `export=` to the statement list if one exists * in the source file. * * @param statements The Statement list to modify. * @param emitAsReturn A value indicating whether to emit the `export=` statement as a * return statement. */ function addExportEqualsIfNeeded(statements, emitAsReturn) { if (currentModuleInfo.exportEquals) { var expressionResult = ts.visitNode(currentModuleInfo.exportEquals.expression, importCallExpressionVisitor); if (expressionResult) { if (emitAsReturn) { var statement = ts.createReturn(expressionResult); ts.setTextRange(statement, currentModuleInfo.exportEquals); ts.setEmitFlags(statement, 384 /* NoTokenSourceMaps */ | 1536 /* NoComments */); statements.push(statement); } else { var statement = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("module"), "exports"), expressionResult)); ts.setTextRange(statement, currentModuleInfo.exportEquals); ts.setEmitFlags(statement, 1536 /* NoComments */); statements.push(statement); } } } } // // Top-Level Source Element Visitors // /** * Visits a node at the top level of the source file. * * @param node The node to visit. */ function sourceElementVisitor(node) { switch (node.kind) { case 239 /* ImportDeclaration */: return visitImportDeclaration(node); case 238 /* ImportEqualsDeclaration */: return visitImportEqualsDeclaration(node); case 245 /* ExportDeclaration */: return visitExportDeclaration(node); case 244 /* ExportAssignment */: return visitExportAssignment(node); case 209 /* VariableStatement */: return visitVariableStatement(node); case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 230 /* ClassDeclaration */: return visitClassDeclaration(node); case 294 /* MergeDeclarationMarker */: return visitMergeDeclarationMarker(node); case 295 /* EndOfDeclarationMarker */: return visitEndOfDeclarationMarker(node); default: return ts.visitEachChild(node, importCallExpressionVisitor, context); } } function importCallExpressionVisitor(node) { // This visitor does not need to descend into the tree if there is no dynamic import, // as export/import statements are only transformed at the top level of a file. if (!(node.transformFlags & 67108864 /* ContainsDynamicImport */)) { return node; } if (ts.isImportCall(node)) { return visitImportCallExpression(node); } else { return ts.visitEachChild(node, importCallExpressionVisitor, context); } } function visitImportCallExpression(node) { var argument = ts.visitNode(ts.firstOrUndefined(node.arguments), importCallExpressionVisitor); var containsLexicalThis = !!(node.transformFlags & 16384 /* ContainsLexicalThis */); switch (compilerOptions.module) { case ts.ModuleKind.AMD: return createImportCallExpressionAMD(argument, containsLexicalThis); case ts.ModuleKind.UMD: return createImportCallExpressionUMD(argument, containsLexicalThis); case ts.ModuleKind.CommonJS: default: return createImportCallExpressionCommonJS(argument, containsLexicalThis); } } function createImportCallExpressionUMD(arg, containsLexicalThis) { // (function (factory) { // ... (regular UMD) // } // })(function (require, exports, useSyncRequire) { // "use strict"; // Object.defineProperty(exports, "__esModule", { value: true }); // var __syncRequire = typeof module === "object" && typeof module.exports === "object"; // var __resolved = new Promise(function (resolve) { resolve(); }); // ..... // __syncRequire // ? __resolved.then(function () { return require(x); }) /*CommonJs Require*/ // : new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/ // }); needUMDDynamicImportHelper = true; if (ts.isSimpleCopiableExpression(arg)) { var argClone = ts.isGeneratedIdentifier(arg) ? arg : ts.isStringLiteral(arg) ? ts.createLiteral(arg) : ts.setEmitFlags(ts.setTextRange(ts.getSynthesizedClone(arg), arg), 1536 /* NoComments */); return ts.createConditional( /*condition*/ ts.createIdentifier("__syncRequire"), /*whenTrue*/ createImportCallExpressionCommonJS(arg, containsLexicalThis), /*whenFalse*/ createImportCallExpressionAMD(argClone, containsLexicalThis)); } else { var temp = ts.createTempVariable(hoistVariableDeclaration); return ts.createComma(ts.createAssignment(temp, arg), ts.createConditional( /*condition*/ ts.createIdentifier("__syncRequire"), /*whenTrue*/ createImportCallExpressionCommonJS(temp, containsLexicalThis), /*whenFalse*/ createImportCallExpressionAMD(temp, containsLexicalThis))); } } function createImportCallExpressionAMD(arg, containsLexicalThis) { // improt("./blah") // emit as // define(["require", "exports", "blah"], function (require, exports) { // ... // new Promise(function (_a, _b) { require([x], _a, _b); }); /*Amd Require*/ // }); var resolve = ts.createUniqueName("resolve"); var reject = ts.createUniqueName("reject"); var parameters = [ ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ resolve), ts.createParameter(/*decorator*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ reject) ]; var body = ts.createBlock([ ts.createStatement(ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, [ts.createArrayLiteral([arg || ts.createOmittedExpression()]), resolve, reject])) ]); var func; if (languageVersion >= 2 /* ES2015 */) { func = ts.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, parameters, /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, body); } else { func = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, parameters, /*type*/ undefined, body); // if there is a lexical 'this' in the import call arguments, ensure we indicate // that this new function expression indicates it captures 'this' so that the // es2015 transformer will properly substitute 'this' with '_this'. if (containsLexicalThis) { ts.setEmitFlags(func, 8 /* CapturesThis */); } } return ts.createNew(ts.createIdentifier("Promise"), /*typeArguments*/ undefined, [func]); } function createImportCallExpressionCommonJS(arg, containsLexicalThis) { // import("./blah") // emit as // Promise.resolve().then(function () { return require(x); }) /*CommonJs Require*/ // We have to wrap require in then callback so that require is done in asynchronously // if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately var promiseResolveCall = ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []); var requireCall = ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []); var func; if (languageVersion >= 2 /* ES2015 */) { func = ts.createArrowFunction( /*modifiers*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, /*equalsGreaterThanToken*/ undefined, requireCall); } else { func = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, ts.createBlock([ts.createReturn(requireCall)])); // if there is a lexical 'this' in the import call arguments, ensure we indicate // that this new function expression indicates it captures 'this' so that the // es2015 transformer will properly substitute 'this' with '_this'. if (containsLexicalThis) { ts.setEmitFlags(func, 8 /* CapturesThis */); } } return ts.createCall(ts.createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]); } /** * Visits an ImportDeclaration node. * * @param node The node to visit. */ function visitImportDeclaration(node) { var statements; var namespaceDeclaration = ts.getNamespaceDeclarationNode(node); if (moduleKind !== ts.ModuleKind.AMD) { if (!node.importClause) { // import "mod"; return ts.setTextRange(ts.createStatement(createRequireCall(node)), node); } else { var variables = []; if (namespaceDeclaration && !ts.isDefaultImport(node)) { // import * as n from "mod"; variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, createRequireCall(node))); } else { // import d from "mod"; // import { x, y } from "mod"; // import d, { x, y } from "mod"; // import d, * as n from "mod"; variables.push(ts.createVariableDeclaration(ts.getGeneratedNameForNode(node), /*type*/ undefined, createRequireCall(node))); if (namespaceDeclaration && ts.isDefaultImport(node)) { variables.push(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, ts.getGeneratedNameForNode(node))); } } statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList(variables, languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), /*location*/ node)); } } else if (namespaceDeclaration && ts.isDefaultImport(node)) { // import d, * as n from "mod"; statements = ts.append(statements, ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.setTextRange(ts.createVariableDeclaration(ts.getSynthesizedClone(namespaceDeclaration.name), /*type*/ undefined, ts.getGeneratedNameForNode(node)), /*location*/ node) ], languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */))); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node); } else { statements = appendExportsOfImportDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Creates a `require()` call to import an external module. * * @param importNode The declararation to import. */ function createRequireCall(importNode) { var moduleName = ts.getExternalModuleNameLiteral(importNode, currentSourceFile, host, resolver, compilerOptions); var args = []; if (moduleName) { args.push(moduleName); } return ts.createCall(ts.createIdentifier("require"), /*typeArguments*/ undefined, args); } /** * Visits an ImportEqualsDeclaration node. * * @param node The node to visit. */ function visitImportEqualsDeclaration(node) { ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); var statements; if (moduleKind !== ts.ModuleKind.AMD) { if (ts.hasModifier(node, 1 /* Export */)) { statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(node.name, createRequireCall(node))), node)); } else { statements = ts.append(statements, ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(ts.getSynthesizedClone(node.name), /*type*/ undefined, createRequireCall(node)) ], /*flags*/ languageVersion >= 2 /* ES2015 */ ? 2 /* Const */ : 0 /* None */)), node)); } } else { if (ts.hasModifier(node, 1 /* Export */)) { statements = ts.append(statements, ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(node), ts.getLocalName(node))), node)); } } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node); } else { statements = appendExportsOfImportEqualsDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits an ExportDeclaration node. * * @param The node to visit. */ function visitExportDeclaration(node) { if (!node.moduleSpecifier) { // Elide export declarations with no module specifier as they are handled // elsewhere. return undefined; } var generatedName = ts.getGeneratedNameForNode(node); if (node.exportClause) { var statements = []; // export { x, y } from "mod"; if (moduleKind !== ts.ModuleKind.AMD) { statements.push(ts.setTextRange(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(generatedName, /*type*/ undefined, createRequireCall(node)) ])), /*location*/ node)); } for (var _i = 0, _a = node.exportClause.elements; _i < _a.length; _i++) { var specifier = _a[_i]; var exportedValue = ts.createPropertyAccess(generatedName, specifier.propertyName || specifier.name); statements.push(ts.setTextRange(ts.createStatement(createExportExpression(ts.getExportName(specifier), exportedValue)), specifier)); } return ts.singleOrMany(statements); } else { // export * from "mod"; return ts.setTextRange(ts.createStatement(createExportStarHelper(context, moduleKind !== ts.ModuleKind.AMD ? createRequireCall(node) : generatedName)), node); } } /** * Visits an ExportAssignment node. * * @param node The node to visit. */ function visitExportAssignment(node) { if (node.isExportEquals) { return undefined; } var statements; var original = node.original; if (original && hasAssociatedEndOfDeclarationMarker(original)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true); } else { statements = appendExportStatement(statements, ts.createIdentifier("default"), ts.visitNode(node.expression, importCallExpressionVisitor), /*location*/ node, /*allowComments*/ true); } return ts.singleOrMany(statements); } /** * Visits a FunctionDeclaration node. * * @param node The node to visit. */ function visitFunctionDeclaration(node) { var statements; if (ts.hasModifier(node, 1 /* Export */)) { statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createFunctionDeclaration( /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, ts.visitNodes(node.parameters, importCallExpressionVisitor), /*type*/ undefined, ts.visitEachChild(node.body, importCallExpressionVisitor, context)), /*location*/ node), /*original*/ node)); } else { statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context)); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node); } else { statements = appendExportsOfHoistedDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits a ClassDeclaration node. * * @param node The node to visit. */ function visitClassDeclaration(node) { var statements; if (ts.hasModifier(node, 1 /* Export */)) { statements = ts.append(statements, ts.setOriginalNode(ts.setTextRange(ts.createClassDeclaration( /*decorators*/ undefined, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, importCallExpressionVisitor), ts.visitNodes(node.members, importCallExpressionVisitor)), node), node)); } else { statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context)); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node); } else { statements = appendExportsOfHoistedDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits a VariableStatement node. * * @param node The node to visit. */ function visitVariableStatement(node) { var statements; var variables; var expressions; if (ts.hasModifier(node, 1 /* Export */)) { var modifiers = void 0; // If we're exporting these variables, then these just become assignments to 'exports.x'. // We only want to emit assignments for variables with initializers. for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var variable = _a[_i]; if (ts.isIdentifier(variable.name) && ts.isLocalName(variable.name)) { if (!modifiers) { modifiers = ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier); } variables = ts.append(variables, variable); } else if (variable.initializer) { expressions = ts.append(expressions, transformInitializedVariable(variable)); } } if (variables) { statements = ts.append(statements, ts.updateVariableStatement(node, modifiers, ts.updateVariableDeclarationList(node.declarationList, variables))); } if (expressions) { statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node)); } } else { statements = ts.append(statements, ts.visitEachChild(node, importCallExpressionVisitor, context)); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node); } else { statements = appendExportsOfVariableStatement(statements, node); } return ts.singleOrMany(statements); } /** * Transforms an exported variable with an initializer into an expression. * * @param node The node to transform. */ function transformInitializedVariable(node) { if (ts.isBindingPattern(node.name)) { return ts.flattenDestructuringAssignment(ts.visitNode(node, importCallExpressionVisitor), /*visitor*/ undefined, context, 0 /* All */, /*needsValue*/ false, createExportExpression); } else { return ts.createAssignment(ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), node.name), /*location*/ node.name), ts.visitNode(node.initializer, importCallExpressionVisitor)); } } /** * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged * and transformed declaration. * * @param node The node to visit. */ function visitMergeDeclarationMarker(node) { // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding // declaration we do not emit a leading variable declaration. To preserve the // begin/end semantics of the declararation and to properly handle exports // we wrapped the leading variable declaration in a `MergeDeclarationMarker`. // // To balance the declaration, add the exports of the elided variable // statement. if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 209 /* VariableStatement */) { var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original); } return node; } /** * Determines whether a node has an associated EndOfDeclarationMarker. * * @param node The node to test. */ function hasAssociatedEndOfDeclarationMarker(node) { return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0; } /** * Visits a DeclarationMarker used as a placeholder for the end of a transformed * declaration. * * @param node The node to visit. */ function visitEndOfDeclarationMarker(node) { // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual // end of the transformed declaration. We use this marker to emit any deferred exports // of the declaration. var id = ts.getOriginalNodeId(node); var statements = deferredExports[id]; if (statements) { delete deferredExports[id]; return ts.append(statements, node); } return node; } /** * Appends the exports of an ImportDeclaration to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfImportDeclaration(statements, decl) { if (currentModuleInfo.exportEquals) { return statements; } var importClause = decl.importClause; if (!importClause) { return statements; } if (importClause.name) { statements = appendExportsOfDeclaration(statements, importClause); } var namedBindings = importClause.namedBindings; if (namedBindings) { switch (namedBindings.kind) { case 241 /* NamespaceImport */: statements = appendExportsOfDeclaration(statements, namedBindings); break; case 242 /* NamedImports */: for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) { var importBinding = _a[_i]; statements = appendExportsOfDeclaration(statements, importBinding); } break; } } return statements; } /** * Appends the exports of an ImportEqualsDeclaration to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfImportEqualsDeclaration(statements, decl) { if (currentModuleInfo.exportEquals) { return statements; } return appendExportsOfDeclaration(statements, decl); } /** * Appends the exports of a VariableStatement to a statement list, returning the statement * list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param node The VariableStatement whose exports are to be recorded. */ function appendExportsOfVariableStatement(statements, node) { if (currentModuleInfo.exportEquals) { return statements; } for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var decl = _a[_i]; statements = appendExportsOfBindingElement(statements, decl); } return statements; } /** * Appends the exports of a VariableDeclaration or BindingElement to a statement list, * returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfBindingElement(statements, decl) { if (currentModuleInfo.exportEquals) { return statements; } if (ts.isBindingPattern(decl.name)) { for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { statements = appendExportsOfBindingElement(statements, element); } } } else if (!ts.isGeneratedIdentifier(decl.name)) { statements = appendExportsOfDeclaration(statements, decl); } return statements; } /** * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list, * returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfHoistedDeclaration(statements, decl) { if (currentModuleInfo.exportEquals) { return statements; } if (ts.hasModifier(decl, 1 /* Export */)) { var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createIdentifier("default") : ts.getDeclarationName(decl); statements = appendExportStatement(statements, exportName, ts.getLocalName(decl), /*location*/ decl); } if (decl.name) { statements = appendExportsOfDeclaration(statements, decl); } return statements; } /** * Appends the exports of a declaration to a statement list, returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration to export. */ function appendExportsOfDeclaration(statements, decl) { var name = ts.getDeclarationName(decl); var exportSpecifiers = currentModuleInfo.exportSpecifiers.get(ts.idText(name)); if (exportSpecifiers) { for (var _i = 0, exportSpecifiers_1 = exportSpecifiers; _i < exportSpecifiers_1.length; _i++) { var exportSpecifier = exportSpecifiers_1[_i]; statements = appendExportStatement(statements, exportSpecifier.name, name, /*location*/ exportSpecifier.name); } } return statements; } /** * Appends the down-level representation of an export to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param exportName The name of the export. * @param expression The expression to export. * @param location The location to use for source maps and comments for the export. * @param allowComments Whether to allow comments on the export. */ function appendExportStatement(statements, exportName, expression, location, allowComments) { statements = ts.append(statements, createExportStatement(exportName, expression, location, allowComments)); return statements; } function createUnderscoreUnderscoreESModule() { var statement; if (languageVersion === 0 /* ES3 */) { statement = ts.createStatement(createExportExpression(ts.createIdentifier("__esModule"), ts.createLiteral(/*value*/ true))); } else { statement = ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("Object"), "defineProperty"), /*typeArguments*/ undefined, [ ts.createIdentifier("exports"), ts.createLiteral("__esModule"), ts.createObjectLiteral([ ts.createPropertyAssignment("value", ts.createLiteral(/*value*/ true)) ]) ])); } ts.setEmitFlags(statement, 1048576 /* CustomPrologue */); return statement; } /** * Creates a call to the current file's export function to export a value. * * @param name The bound name of the export. * @param value The exported value. * @param location The location to use for source maps and comments for the export. * @param allowComments An optional value indicating whether to emit comments for the statement. */ function createExportStatement(name, value, location, allowComments) { var statement = ts.setTextRange(ts.createStatement(createExportExpression(name, value)), location); ts.startOnNewLine(statement); if (!allowComments) { ts.setEmitFlags(statement, 1536 /* NoComments */); } return statement; } /** * Creates a call to the current file's export function to export a value. * * @param name The bound name of the export. * @param value The exported value. * @param location The location to use for source maps and comments for the export. */ function createExportExpression(name, value, location) { return ts.setTextRange(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(name)), value), location); } // // Modifier Visitors // /** * Visit nodes to elide module-specific modifiers. * * @param node The node to visit. */ function modifierVisitor(node) { // Elide module-specific modifiers. switch (node.kind) { case 84 /* ExportKeyword */: case 79 /* DefaultKeyword */: return undefined; } return node; } // // Emit Notification // /** * Hook for node emit notifications. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ function onEmitNode(hint, node, emitCallback) { if (node.kind === 269 /* SourceFile */) { currentSourceFile = node; currentModuleInfo = moduleInfoMap[ts.getOriginalNodeId(currentSourceFile)]; noSubstitution = []; previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; currentModuleInfo = undefined; noSubstitution = undefined; } else { previousOnEmitNode(hint, node, emitCallback); } } // // Substitutions // /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (node.id && noSubstitution[node.id]) { return node; } if (hint === 1 /* Expression */) { return substituteExpression(node); } else if (ts.isShorthandPropertyAssignment(node)) { return substituteShorthandPropertyAssignment(node); } return node; } /** * Substitution for a ShorthandPropertyAssignment whose declaration name is an imported * or exported symbol. * * @param node The node to substitute. */ function substituteShorthandPropertyAssignment(node) { var name = node.name; var exportedOrImportedName = substituteExpressionIdentifier(name); if (exportedOrImportedName !== name) { // A shorthand property with an assignment initializer is probably part of a // destructuring assignment if (node.objectAssignmentInitializer) { var initializer = ts.createAssignment(exportedOrImportedName, node.objectAssignmentInitializer); return ts.setTextRange(ts.createPropertyAssignment(name, initializer), node); } return ts.setTextRange(ts.createPropertyAssignment(name, exportedOrImportedName), node); } return node; } /** * Substitution for an Expression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteExpression(node) { switch (node.kind) { case 71 /* Identifier */: return substituteExpressionIdentifier(node); case 195 /* BinaryExpression */: return substituteBinaryExpression(node); case 194 /* PostfixUnaryExpression */: case 193 /* PrefixUnaryExpression */: return substituteUnaryExpression(node); } return node; } /** * Substitution for an Identifier expression that may contain an imported or exported * symbol. * * @param node The node to substitute. */ function substituteExpressionIdentifier(node) { if (ts.getEmitFlags(node) & 4096 /* HelperName */) { var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile); if (externalHelpersModuleName) { return ts.createPropertyAccess(externalHelpersModuleName, node); } return node; } if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) { var exportContainer = resolver.getReferencedExportContainer(node, ts.isExportName(node)); if (exportContainer && exportContainer.kind === 269 /* SourceFile */) { return ts.setTextRange(ts.createPropertyAccess(ts.createIdentifier("exports"), ts.getSynthesizedClone(node)), /*location*/ node); } var importDeclaration = resolver.getReferencedImportDeclaration(node); if (importDeclaration) { if (ts.isImportClause(importDeclaration)) { return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), /*location*/ node); } else if (ts.isImportSpecifier(importDeclaration)) { var name = importDeclaration.propertyName || importDeclaration.name; return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(name)), /*location*/ node); } } } return node; } /** * Substitution for a BinaryExpression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteBinaryExpression(node) { // When we see an assignment expression whose left-hand side is an exported symbol, // we should ensure all exports of that symbol are updated with the correct value. // // - We do not substitute generated identifiers for any reason. // - We do not substitute identifiers tagged with the LocalName flag. // - We do not substitute identifiers that were originally the name of an enum or // namespace due to how they are transformed in TypeScript. // - We only substitute identifiers that are exported at the top level. if (ts.isAssignmentOperator(node.operatorToken.kind) && ts.isIdentifier(node.left) && !ts.isGeneratedIdentifier(node.left) && !ts.isLocalName(node.left) && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) { var exportedNames = getExports(node.left); if (exportedNames) { // For each additional export of the declaration, apply an export assignment. var expression = node; for (var _i = 0, exportedNames_1 = exportedNames; _i < exportedNames_1.length; _i++) { var exportName = exportedNames_1[_i]; // Mark the node to prevent triggering this rule again. noSubstitution[ts.getNodeId(expression)] = true; expression = createExportExpression(exportName, expression, /*location*/ node); } return expression; } } return node; } /** * Substitution for a UnaryExpression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteUnaryExpression(node) { // When we see a prefix or postfix increment expression whose operand is an exported // symbol, we should ensure all exports of that symbol are updated with the correct // value. // // - We do not substitute generated identifiers for any reason. // - We do not substitute identifiers tagged with the LocalName flag. // - We do not substitute identifiers that were originally the name of an enum or // namespace due to how they are transformed in TypeScript. // - We only substitute identifiers that are exported at the top level. if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) && ts.isIdentifier(node.operand) && !ts.isGeneratedIdentifier(node.operand) && !ts.isLocalName(node.operand) && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) { var exportedNames = getExports(node.operand); if (exportedNames) { var expression = node.kind === 194 /* PostfixUnaryExpression */ ? ts.setTextRange(ts.createBinary(node.operand, ts.createToken(node.operator === 43 /* PlusPlusToken */ ? 59 /* PlusEqualsToken */ : 60 /* MinusEqualsToken */), ts.createLiteral(1)), /*location*/ node) : node; for (var _i = 0, exportedNames_2 = exportedNames; _i < exportedNames_2.length; _i++) { var exportName = exportedNames_2[_i]; // Mark the node to prevent triggering this rule again. noSubstitution[ts.getNodeId(expression)] = true; expression = createExportExpression(exportName, expression); } return expression; } } return node; } /** * Gets the additional exports of a name. * * @param name The name. */ function getExports(name) { if (!ts.isGeneratedIdentifier(name)) { var valueDeclaration = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name); if (valueDeclaration) { return currentModuleInfo && currentModuleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]; } } } } ts.transformModule = transformModule; // emit output for the __export helper function var exportStarHelper = { name: "typescript:export-star", scoped: true, text: "\n function __export(m) {\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\n }\n " }; function createExportStarHelper(context, module) { var compilerOptions = context.getCompilerOptions(); return compilerOptions.importHelpers ? ts.createCall(ts.getHelperName("__exportStar"), /*typeArguments*/ undefined, [module, ts.createIdentifier("exports")]) : ts.createCall(ts.createIdentifier("__export"), /*typeArguments*/ undefined, [module]); } // emit helper for dynamic import var dynamicImportUMDHelper = { name: "typescript:dynamicimport-sync-require", scoped: true, text: "\n var __syncRequire = typeof module === \"object\" && typeof module.exports === \"object\";" }; })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { function transformSystemModule(context) { var startLexicalEnvironment = context.startLexicalEnvironment, endLexicalEnvironment = context.endLexicalEnvironment, hoistVariableDeclaration = context.hoistVariableDeclaration; var compilerOptions = context.getCompilerOptions(); var resolver = context.getEmitResolver(); var host = context.getEmitHost(); var previousOnSubstituteNode = context.onSubstituteNode; var previousOnEmitNode = context.onEmitNode; context.onSubstituteNode = onSubstituteNode; context.onEmitNode = onEmitNode; context.enableSubstitution(71 /* Identifier */); // Substitutes expression identifiers for imported symbols. context.enableSubstitution(195 /* BinaryExpression */); // Substitutes assignments to exported symbols. context.enableSubstitution(193 /* PrefixUnaryExpression */); // Substitutes updates to exported symbols. context.enableSubstitution(194 /* PostfixUnaryExpression */); // Substitutes updates to exported symbols. context.enableEmitNotification(269 /* SourceFile */); // Restore state when substituting nodes in a file. var moduleInfoMap = []; // The ExternalModuleInfo for each file. var deferredExports = []; // Exports to defer until an EndOfDeclarationMarker is found. var exportFunctionsMap = []; // The export function associated with a source file. var noSubstitutionMap = []; // Set of nodes for which substitution rules should be ignored for each file. var currentSourceFile; // The current file. var moduleInfo; // ExternalModuleInfo for the current file. var exportFunction; // The export function for the current file. var contextObject; // The context object for the current file. var hoistedStatements; var enclosingBlockScopedContainer; var noSubstitution; // Set of nodes for which substitution rules should be ignored. return transformSourceFile; /** * Transforms the module aspects of a SourceFile. * * @param node The SourceFile node. */ function transformSourceFile(node) { if (node.isDeclarationFile || !(ts.isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & 67108864 /* ContainsDynamicImport */)) { return node; } var id = ts.getOriginalNodeId(node); currentSourceFile = node; enclosingBlockScopedContainer = node; // System modules have the following shape: // // System.register(['dep-1', ... 'dep-n'], function(exports) {/* module body function */}) // // The parameter 'exports' here is a callback '(name: string, value: T) => T' that // is used to publish exported values. 'exports' returns its 'value' argument so in // most cases expressions that mutate exported values can be rewritten as: // // expr -> exports('name', expr) // // The only exception in this rule is postfix unary operators, // see comment to 'substitutePostfixUnaryExpression' for more details // Collect information about the external module and dependency groups. moduleInfo = moduleInfoMap[id] = ts.collectExternalModuleInfo(node, resolver, compilerOptions); // Make sure that the name of the 'exports' function does not conflict with // existing identifiers. exportFunction = ts.createUniqueName("exports"); exportFunctionsMap[id] = exportFunction; contextObject = ts.createUniqueName("context"); // Add the body of the module. var dependencyGroups = collectDependencyGroups(moduleInfo.externalImports); var moduleBodyBlock = createSystemModuleBody(node, dependencyGroups); var moduleBodyFunction = ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, exportFunction), ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, contextObject) ], /*type*/ undefined, moduleBodyBlock); // Write the call to `System.register` // Clear the emit-helpers flag for later passes since we'll have already used it in the module body // So the helper will be emit at the correct position instead of at the top of the source-file var moduleName = ts.tryGetModuleNameFromFile(node, host, compilerOptions); var dependencies = ts.createArrayLiteral(ts.map(dependencyGroups, function (dependencyGroup) { return dependencyGroup.name; })); var updated = ts.setEmitFlags(ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray([ ts.createStatement(ts.createCall(ts.createPropertyAccess(ts.createIdentifier("System"), "register"), /*typeArguments*/ undefined, moduleName ? [moduleName, dependencies, moduleBodyFunction] : [dependencies, moduleBodyFunction])) ]), node.statements)), 1024 /* NoTrailingComments */); if (!(compilerOptions.outFile || compilerOptions.out)) { ts.moveEmitHelpers(updated, moduleBodyBlock, function (helper) { return !helper.scoped; }); } if (noSubstitution) { noSubstitutionMap[id] = noSubstitution; noSubstitution = undefined; } currentSourceFile = undefined; moduleInfo = undefined; exportFunction = undefined; contextObject = undefined; hoistedStatements = undefined; enclosingBlockScopedContainer = undefined; return ts.aggregateTransformFlags(updated); } /** * Collects the dependency groups for this files imports. * * @param externalImports The imports for the file. */ function collectDependencyGroups(externalImports) { var groupIndices = ts.createMap(); var dependencyGroups = []; for (var _i = 0, externalImports_1 = externalImports; _i < externalImports_1.length; _i++) { var externalImport = externalImports_1[_i]; var externalModuleName = ts.getExternalModuleNameLiteral(externalImport, currentSourceFile, host, resolver, compilerOptions); if (externalModuleName) { var text = externalModuleName.text; var groupIndex = groupIndices.get(text); if (groupIndex !== undefined) { // deduplicate/group entries in dependency list by the dependency name dependencyGroups[groupIndex].externalImports.push(externalImport); } else { groupIndices.set(text, dependencyGroups.length); dependencyGroups.push({ name: externalModuleName, externalImports: [externalImport] }); } } } return dependencyGroups; } /** * Adds the statements for the module body function for the source file. * * @param node The source file for the module. * @param dependencyGroups The grouped dependencies of the module. */ function createSystemModuleBody(node, dependencyGroups) { // Shape of the body in system modules: // // function (exports) { // // // // return { // setters: [ // // ], // execute: function() { // // } // } // // } // // i.e: // // import {x} from 'file1' // var y = 1; // export function foo() { return y + x(); } // console.log(y); // // Will be transformed to: // // function(exports) { // function foo() { return y + file_1.x(); } // exports("foo", foo); // var file_1, y; // return { // setters: [ // function(v) { file_1 = v } // ], // execute(): function() { // y = 1; // console.log(y); // } // }; // } var statements = []; // We start a new lexical environment in this function body, but *not* in the // body of the execute function. This allows us to emit temporary declarations // only in the outer module body and not in the inner one. startLexicalEnvironment(); // Add any prologue directives. var ensureUseStrict = ts.getStrictOptionValue(compilerOptions, "alwaysStrict") || (!compilerOptions.noImplicitUseStrict && ts.isExternalModule(currentSourceFile)); var statementOffset = ts.addPrologue(statements, node.statements, ensureUseStrict, sourceElementVisitor); // var __moduleName = context_1 && context_1.id; statements.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration("__moduleName", /*type*/ undefined, ts.createLogicalAnd(contextObject, ts.createPropertyAccess(contextObject, "id"))) ]))); // Visit the synthetic external helpers import declaration if present ts.visitNode(moduleInfo.externalHelpersImportDeclaration, sourceElementVisitor, ts.isStatement); // Visit the statements of the source file, emitting any transformations into // the `executeStatements` array. We do this *before* we fill the `setters` array // as we both emit transformations as well as aggregate some data used when creating // setters. This allows us to reduce the number of times we need to loop through the // statements of the source file. var executeStatements = ts.visitNodes(node.statements, sourceElementVisitor, ts.isStatement, statementOffset); // Emit early exports for function declarations. ts.addRange(statements, hoistedStatements); // We emit hoisted variables early to align roughly with our previous emit output. // Two key differences in this approach are: // - Temporary variables will appear at the top rather than at the bottom of the file ts.addRange(statements, endLexicalEnvironment()); var exportStarFunction = addExportStarIfNeeded(statements); var moduleObject = ts.createObjectLiteral([ ts.createPropertyAssignment("setters", createSettersArray(exportStarFunction, dependencyGroups)), ts.createPropertyAssignment("execute", ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, /*parameters*/ [], /*type*/ undefined, ts.createBlock(executeStatements, /*multiLine*/ true))) ]); moduleObject.multiLine = true; statements.push(ts.createReturn(moduleObject)); return ts.createBlock(statements, /*multiLine*/ true); } /** * Adds an exportStar function to a statement list if it is needed for the file. * * @param statements A statement list. */ function addExportStarIfNeeded(statements) { if (!moduleInfo.hasExportStarsToExportValues) { return; } // when resolving exports local exported entries/indirect exported entries in the module // should always win over entries with similar names that were added via star exports // to support this we store names of local/indirect exported entries in a set. // this set is used to filter names brought by star expors. // local names set should only be added if we have anything exported if (!moduleInfo.exportedNames && moduleInfo.exportSpecifiers.size === 0) { // no exported declarations (export var ...) or export specifiers (export {x}) // check if we have any non star export declarations. var hasExportDeclarationWithExportClause = false; for (var _i = 0, _a = moduleInfo.externalImports; _i < _a.length; _i++) { var externalImport = _a[_i]; if (externalImport.kind === 245 /* ExportDeclaration */ && externalImport.exportClause) { hasExportDeclarationWithExportClause = true; break; } } if (!hasExportDeclarationWithExportClause) { // we still need to emit exportStar helper var exportStarFunction_1 = createExportStarFunction(/*localNames*/ undefined); statements.push(exportStarFunction_1); return exportStarFunction_1.name; } } var exportedNames = []; if (moduleInfo.exportedNames) { for (var _b = 0, _c = moduleInfo.exportedNames; _b < _c.length; _b++) { var exportedLocalName = _c[_b]; if (exportedLocalName.escapedText === "default") { continue; } // write name of exported declaration, i.e 'export var x...' exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(exportedLocalName), ts.createTrue())); } } for (var _d = 0, _e = moduleInfo.externalImports; _d < _e.length; _d++) { var externalImport = _e[_d]; if (externalImport.kind !== 245 /* ExportDeclaration */) { continue; } var exportDecl = externalImport; if (!exportDecl.exportClause) { // export * from ... continue; } for (var _f = 0, _g = exportDecl.exportClause.elements; _f < _g.length; _f++) { var element = _g[_f]; // write name of indirectly exported entry, i.e. 'export {x} from ...' exportedNames.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(element.name || element.propertyName)), ts.createTrue())); } } var exportedNamesStorageRef = ts.createUniqueName("exportedNames"); statements.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(exportedNamesStorageRef, /*type*/ undefined, ts.createObjectLiteral(exportedNames, /*multiline*/ true)) ]))); var exportStarFunction = createExportStarFunction(exportedNamesStorageRef); statements.push(exportStarFunction); return exportStarFunction.name; } /** * Creates an exportStar function for the file, with an optional set of excluded local * names. * * @param localNames An optional reference to an object containing a set of excluded local * names. */ function createExportStarFunction(localNames) { var exportStarFunction = ts.createUniqueName("exportStar"); var m = ts.createIdentifier("m"); var n = ts.createIdentifier("n"); var exports = ts.createIdentifier("exports"); var condition = ts.createStrictInequality(n, ts.createLiteral("default")); if (localNames) { condition = ts.createLogicalAnd(condition, ts.createLogicalNot(ts.createCall(ts.createPropertyAccess(localNames, "hasOwnProperty"), /*typeArguments*/ undefined, [n]))); } return ts.createFunctionDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, /*asteriskToken*/ undefined, exportStarFunction, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, m)], /*type*/ undefined, ts.createBlock([ ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ ts.createVariableDeclaration(exports, /*type*/ undefined, ts.createObjectLiteral([])) ])), ts.createForIn(ts.createVariableDeclarationList([ ts.createVariableDeclaration(n, /*type*/ undefined) ]), m, ts.createBlock([ ts.setEmitFlags(ts.createIf(condition, ts.createStatement(ts.createAssignment(ts.createElementAccess(exports, n), ts.createElementAccess(m, n)))), 1 /* SingleLine */) ])), ts.createStatement(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exports])) ], /*multiline*/ true)); } /** * Creates an array setter callbacks for each dependency group. * * @param exportStarFunction A reference to an exportStarFunction for the file. * @param dependencyGroups An array of grouped dependencies. */ function createSettersArray(exportStarFunction, dependencyGroups) { var setters = []; for (var _i = 0, dependencyGroups_1 = dependencyGroups; _i < dependencyGroups_1.length; _i++) { var group = dependencyGroups_1[_i]; // derive a unique name for parameter from the first named entry in the group var localName = ts.forEach(group.externalImports, function (i) { return ts.getLocalNameForExternalImport(i, currentSourceFile); }); var parameterName = localName ? ts.getGeneratedNameForNode(localName) : ts.createUniqueName(""); var statements = []; for (var _a = 0, _b = group.externalImports; _a < _b.length; _a++) { var entry = _b[_a]; var importVariableName = ts.getLocalNameForExternalImport(entry, currentSourceFile); switch (entry.kind) { case 239 /* ImportDeclaration */: if (!entry.importClause) { // 'import "..."' case // module is imported only for side-effects, no emit required break; } // falls through case 238 /* ImportEqualsDeclaration */: ts.Debug.assert(importVariableName !== undefined); // save import into the local statements.push(ts.createStatement(ts.createAssignment(importVariableName, parameterName))); break; case 245 /* ExportDeclaration */: ts.Debug.assert(importVariableName !== undefined); if (entry.exportClause) { // export {a, b as c} from 'foo' // // emit as: // // exports_({ // "a": _["a"], // "c": _["b"] // }); var properties = []; for (var _c = 0, _d = entry.exportClause.elements; _c < _d.length; _c++) { var e = _d[_c]; properties.push(ts.createPropertyAssignment(ts.createLiteral(ts.idText(e.name)), ts.createElementAccess(parameterName, ts.createLiteral(ts.idText(e.propertyName || e.name))))); } statements.push(ts.createStatement(ts.createCall(exportFunction, /*typeArguments*/ undefined, [ts.createObjectLiteral(properties, /*multiline*/ true)]))); } else { // export * from 'foo' // // emit as: // // exportStar(foo_1_1); statements.push(ts.createStatement(ts.createCall(exportStarFunction, /*typeArguments*/ undefined, [parameterName]))); } break; } } setters.push(ts.createFunctionExpression( /*modifiers*/ undefined, /*asteriskToken*/ undefined, /*name*/ undefined, /*typeParameters*/ undefined, [ts.createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, parameterName)], /*type*/ undefined, ts.createBlock(statements, /*multiLine*/ true))); } return ts.createArrayLiteral(setters, /*multiLine*/ true); } // // Top-level Source Element Visitors // /** * Visit source elements at the top-level of a module. * * @param node The node to visit. */ function sourceElementVisitor(node) { switch (node.kind) { case 239 /* ImportDeclaration */: return visitImportDeclaration(node); case 238 /* ImportEqualsDeclaration */: return visitImportEqualsDeclaration(node); case 245 /* ExportDeclaration */: // ExportDeclarations are elided as they are handled via // `appendExportsOfDeclaration`. return undefined; case 244 /* ExportAssignment */: return visitExportAssignment(node); default: return nestedElementVisitor(node); } } /** * Visits an ImportDeclaration node. * * @param node The node to visit. */ function visitImportDeclaration(node) { var statements; if (node.importClause) { hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfImportDeclaration(deferredExports[id], node); } else { statements = appendExportsOfImportDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits an ImportEqualsDeclaration node. * * @param node The node to visit. */ function visitImportEqualsDeclaration(node) { ts.Debug.assert(ts.isExternalModuleImportEqualsDeclaration(node), "import= for internal module references should be handled in an earlier transformer."); var statements; hoistVariableDeclaration(ts.getLocalNameForExternalImport(node, currentSourceFile)); if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfImportEqualsDeclaration(deferredExports[id], node); } else { statements = appendExportsOfImportEqualsDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits an ExportAssignment node. * * @param node The node to visit. */ function visitExportAssignment(node) { if (node.isExportEquals) { // Elide `export=` as it is illegal in a SystemJS module. return undefined; } var expression = ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression); var original = node.original; if (original && hasAssociatedEndOfDeclarationMarker(original)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportStatement(deferredExports[id], ts.createIdentifier("default"), expression, /*allowComments*/ true); } else { return createExportStatement(ts.createIdentifier("default"), expression, /*allowComments*/ true); } } /** * Visits a FunctionDeclaration, hoisting it to the outer module body function. * * @param node The node to visit. */ function visitFunctionDeclaration(node) { if (ts.hasModifier(node, 1 /* Export */)) { hoistedStatements = ts.append(hoistedStatements, ts.updateFunctionDeclaration(node, node.decorators, ts.visitNodes(node.modifiers, modifierVisitor, ts.isModifier), node.asteriskToken, ts.getDeclarationName(node, /*allowComments*/ true, /*allowSourceMaps*/ true), /*typeParameters*/ undefined, ts.visitNodes(node.parameters, destructuringAndImportCallVisitor, ts.isParameterDeclaration), /*type*/ undefined, ts.visitNode(node.body, destructuringAndImportCallVisitor, ts.isBlock))); } else { hoistedStatements = ts.append(hoistedStatements, ts.visitEachChild(node, destructuringAndImportCallVisitor, context)); } if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node); } else { hoistedStatements = appendExportsOfHoistedDeclaration(hoistedStatements, node); } return undefined; } /** * Visits a ClassDeclaration, hoisting its name to the outer module body function. * * @param node The node to visit. */ function visitClassDeclaration(node) { var statements; // Hoist the name of the class declaration to the outer module body function. var name = ts.getLocalName(node); hoistVariableDeclaration(name); // Rewrite the class declaration into an assignment of a class expression. statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.createAssignment(name, ts.setTextRange(ts.createClassExpression( /*modifiers*/ undefined, node.name, /*typeParameters*/ undefined, ts.visitNodes(node.heritageClauses, destructuringAndImportCallVisitor, ts.isHeritageClause), ts.visitNodes(node.members, destructuringAndImportCallVisitor, ts.isClassElement)), node))), node)); if (hasAssociatedEndOfDeclarationMarker(node)) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfHoistedDeclaration(deferredExports[id], node); } else { statements = appendExportsOfHoistedDeclaration(statements, node); } return ts.singleOrMany(statements); } /** * Visits a variable statement, hoisting declared names to the top-level module body. * Each declaration is rewritten into an assignment expression. * * @param node The node to visit. */ function visitVariableStatement(node) { if (!shouldHoistVariableDeclarationList(node.declarationList)) { return ts.visitNode(node, destructuringAndImportCallVisitor, ts.isStatement); } var expressions; var isExportedDeclaration = ts.hasModifier(node, 1 /* Export */); var isMarkedDeclaration = hasAssociatedEndOfDeclarationMarker(node); for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var variable = _a[_i]; if (variable.initializer) { expressions = ts.append(expressions, transformInitializedVariable(variable, isExportedDeclaration && !isMarkedDeclaration)); } else { hoistBindingElement(variable); } } var statements; if (expressions) { statements = ts.append(statements, ts.setTextRange(ts.createStatement(ts.inlineExpressions(expressions)), node)); } if (isMarkedDeclaration) { // Defer exports until we encounter an EndOfDeclarationMarker node var id = ts.getOriginalNodeId(node); deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node, isExportedDeclaration); } else { statements = appendExportsOfVariableStatement(statements, node, /*exportSelf*/ false); } return ts.singleOrMany(statements); } /** * Hoists the declared names of a VariableDeclaration or BindingElement. * * @param node The declaration to hoist. */ function hoistBindingElement(node) { if (ts.isBindingPattern(node.name)) { for (var _i = 0, _a = node.name.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { hoistBindingElement(element); } } } else { hoistVariableDeclaration(ts.getSynthesizedClone(node.name)); } } /** * Determines whether a VariableDeclarationList should be hoisted. * * @param node The node to test. */ function shouldHoistVariableDeclarationList(node) { // hoist only non-block scoped declarations or block scoped declarations parented by source file return (ts.getEmitFlags(node) & 2097152 /* NoHoisting */) === 0 && (enclosingBlockScopedContainer.kind === 269 /* SourceFile */ || (ts.getOriginalNode(node).flags & 3 /* BlockScoped */) === 0); } /** * Transform an initialized variable declaration into an expression. * * @param node The node to transform. * @param isExportedDeclaration A value indicating whether the variable is exported. */ function transformInitializedVariable(node, isExportedDeclaration) { var createAssignment = isExportedDeclaration ? createExportedVariableAssignment : createNonExportedVariableAssignment; return ts.isBindingPattern(node.name) ? ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, /*needsValue*/ false, createAssignment) : node.initializer ? createAssignment(node.name, ts.visitNode(node.initializer, destructuringAndImportCallVisitor, ts.isExpression)) : node.name; } /** * Creates an assignment expression for an exported variable declaration. * * @param name The name of the variable. * @param value The value of the variable's initializer. * @param location The source map location for the assignment. */ function createExportedVariableAssignment(name, value, location) { return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ true); } /** * Creates an assignment expression for a non-exported variable declaration. * * @param name The name of the variable. * @param value The value of the variable's initializer. * @param location The source map location for the assignment. */ function createNonExportedVariableAssignment(name, value, location) { return createVariableAssignment(name, value, location, /*isExportedDeclaration*/ false); } /** * Creates an assignment expression for a variable declaration. * * @param name The name of the variable. * @param value The value of the variable's initializer. * @param location The source map location for the assignment. * @param isExportedDeclaration A value indicating whether the variable is exported. */ function createVariableAssignment(name, value, location, isExportedDeclaration) { hoistVariableDeclaration(ts.getSynthesizedClone(name)); return isExportedDeclaration ? createExportExpression(name, preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location))) : preventSubstitution(ts.setTextRange(ts.createAssignment(name, value), location)); } /** * Visits a MergeDeclarationMarker used as a placeholder for the beginning of a merged * and transformed declaration. * * @param node The node to visit. */ function visitMergeDeclarationMarker(node) { // For an EnumDeclaration or ModuleDeclaration that merges with a preceeding // declaration we do not emit a leading variable declaration. To preserve the // begin/end semantics of the declararation and to properly handle exports // we wrapped the leading variable declaration in a `MergeDeclarationMarker`. // // To balance the declaration, we defer the exports of the elided variable // statement until we visit this declaration's `EndOfDeclarationMarker`. if (hasAssociatedEndOfDeclarationMarker(node) && node.original.kind === 209 /* VariableStatement */) { var id = ts.getOriginalNodeId(node); var isExportedDeclaration = ts.hasModifier(node.original, 1 /* Export */); deferredExports[id] = appendExportsOfVariableStatement(deferredExports[id], node.original, isExportedDeclaration); } return node; } /** * Determines whether a node has an associated EndOfDeclarationMarker. * * @param node The node to test. */ function hasAssociatedEndOfDeclarationMarker(node) { return (ts.getEmitFlags(node) & 4194304 /* HasEndOfDeclarationMarker */) !== 0; } /** * Visits a DeclarationMarker used as a placeholder for the end of a transformed * declaration. * * @param node The node to visit. */ function visitEndOfDeclarationMarker(node) { // For some transformations we emit an `EndOfDeclarationMarker` to mark the actual // end of the transformed declaration. We use this marker to emit any deferred exports // of the declaration. var id = ts.getOriginalNodeId(node); var statements = deferredExports[id]; if (statements) { delete deferredExports[id]; return ts.append(statements, node); } return node; } /** * Appends the exports of an ImportDeclaration to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfImportDeclaration(statements, decl) { if (moduleInfo.exportEquals) { return statements; } var importClause = decl.importClause; if (!importClause) { return statements; } if (importClause.name) { statements = appendExportsOfDeclaration(statements, importClause); } var namedBindings = importClause.namedBindings; if (namedBindings) { switch (namedBindings.kind) { case 241 /* NamespaceImport */: statements = appendExportsOfDeclaration(statements, namedBindings); break; case 242 /* NamedImports */: for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) { var importBinding = _a[_i]; statements = appendExportsOfDeclaration(statements, importBinding); } break; } } return statements; } /** * Appends the export of an ImportEqualsDeclaration to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfImportEqualsDeclaration(statements, decl) { if (moduleInfo.exportEquals) { return statements; } return appendExportsOfDeclaration(statements, decl); } /** * Appends the exports of a VariableStatement to a statement list, returning the statement * list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param node The VariableStatement whose exports are to be recorded. * @param exportSelf A value indicating whether to also export each VariableDeclaration of * `nodes` declaration list. */ function appendExportsOfVariableStatement(statements, node, exportSelf) { if (moduleInfo.exportEquals) { return statements; } for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var decl = _a[_i]; if (decl.initializer || exportSelf) { statements = appendExportsOfBindingElement(statements, decl, exportSelf); } } return statements; } /** * Appends the exports of a VariableDeclaration or BindingElement to a statement list, * returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. * @param exportSelf A value indicating whether to also export the declaration itself. */ function appendExportsOfBindingElement(statements, decl, exportSelf) { if (moduleInfo.exportEquals) { return statements; } if (ts.isBindingPattern(decl.name)) { for (var _i = 0, _a = decl.name.elements; _i < _a.length; _i++) { var element = _a[_i]; if (!ts.isOmittedExpression(element)) { statements = appendExportsOfBindingElement(statements, element, exportSelf); } } } else if (!ts.isGeneratedIdentifier(decl.name)) { var excludeName = void 0; if (exportSelf) { statements = appendExportStatement(statements, decl.name, ts.getLocalName(decl)); excludeName = ts.idText(decl.name); } statements = appendExportsOfDeclaration(statements, decl, excludeName); } return statements; } /** * Appends the exports of a ClassDeclaration or FunctionDeclaration to a statement list, * returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration whose exports are to be recorded. */ function appendExportsOfHoistedDeclaration(statements, decl) { if (moduleInfo.exportEquals) { return statements; } var excludeName; if (ts.hasModifier(decl, 1 /* Export */)) { var exportName = ts.hasModifier(decl, 512 /* Default */) ? ts.createLiteral("default") : decl.name; statements = appendExportStatement(statements, exportName, ts.getLocalName(decl)); excludeName = ts.getTextOfIdentifierOrLiteral(exportName); } if (decl.name) { statements = appendExportsOfDeclaration(statements, decl, excludeName); } return statements; } /** * Appends the exports of a declaration to a statement list, returning the statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param decl The declaration to export. * @param excludeName An optional name to exclude from exports. */ function appendExportsOfDeclaration(statements, decl, excludeName) { if (moduleInfo.exportEquals) { return statements; } var name = ts.getDeclarationName(decl); var exportSpecifiers = moduleInfo.exportSpecifiers.get(ts.idText(name)); if (exportSpecifiers) { for (var _i = 0, exportSpecifiers_2 = exportSpecifiers; _i < exportSpecifiers_2.length; _i++) { var exportSpecifier = exportSpecifiers_2[_i]; if (exportSpecifier.name.escapedText !== excludeName) { statements = appendExportStatement(statements, exportSpecifier.name, name); } } } return statements; } /** * Appends the down-level representation of an export to a statement list, returning the * statement list. * * @param statements A statement list to which the down-level export statements are to be * appended. If `statements` is `undefined`, a new array is allocated if statements are * appended. * @param exportName The name of the export. * @param expression The expression to export. * @param allowComments Whether to allow comments on the export. */ function appendExportStatement(statements, exportName, expression, allowComments) { statements = ts.append(statements, createExportStatement(exportName, expression, allowComments)); return statements; } /** * Creates a call to the current file's export function to export a value. * * @param name The bound name of the export. * @param value The exported value. * @param allowComments An optional value indicating whether to emit comments for the statement. */ function createExportStatement(name, value, allowComments) { var statement = ts.createStatement(createExportExpression(name, value)); ts.startOnNewLine(statement); if (!allowComments) { ts.setEmitFlags(statement, 1536 /* NoComments */); } return statement; } /** * Creates a call to the current file's export function to export a value. * * @param name The bound name of the export. * @param value The exported value. */ function createExportExpression(name, value) { var exportName = ts.isIdentifier(name) ? ts.createLiteral(name) : name; ts.setEmitFlags(value, ts.getEmitFlags(value) | 1536 /* NoComments */); return ts.setCommentRange(ts.createCall(exportFunction, /*typeArguments*/ undefined, [exportName, value]), value); } // // Top-Level or Nested Source Element Visitors // /** * Visit nested elements at the top-level of a module. * * @param node The node to visit. */ function nestedElementVisitor(node) { switch (node.kind) { case 209 /* VariableStatement */: return visitVariableStatement(node); case 229 /* FunctionDeclaration */: return visitFunctionDeclaration(node); case 230 /* ClassDeclaration */: return visitClassDeclaration(node); case 215 /* ForStatement */: return visitForStatement(node); case 216 /* ForInStatement */: return visitForInStatement(node); case 217 /* ForOfStatement */: return visitForOfStatement(node); case 213 /* DoStatement */: return visitDoStatement(node); case 214 /* WhileStatement */: return visitWhileStatement(node); case 223 /* LabeledStatement */: return visitLabeledStatement(node); case 221 /* WithStatement */: return visitWithStatement(node); case 222 /* SwitchStatement */: return visitSwitchStatement(node); case 236 /* CaseBlock */: return visitCaseBlock(node); case 261 /* CaseClause */: return visitCaseClause(node); case 262 /* DefaultClause */: return visitDefaultClause(node); case 225 /* TryStatement */: return visitTryStatement(node); case 264 /* CatchClause */: return visitCatchClause(node); case 208 /* Block */: return visitBlock(node); case 294 /* MergeDeclarationMarker */: return visitMergeDeclarationMarker(node); case 295 /* EndOfDeclarationMarker */: return visitEndOfDeclarationMarker(node); default: return destructuringAndImportCallVisitor(node); } } /** * Visits the body of a ForStatement to hoist declarations. * * @param node The node to visit. */ function visitForStatement(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.updateFor(node, visitForInitializer(node.initializer), ts.visitNode(node.condition, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.incrementor, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement)); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } /** * Visits the body of a ForInStatement to hoist declarations. * * @param node The node to visit. */ function visitForInStatement(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.updateForIn(node, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock)); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } /** * Visits the body of a ForOfStatement to hoist declarations. * * @param node The node to visit. */ function visitForOfStatement(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.updateForOf(node, node.awaitModifier, visitForInitializer(node.initializer), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock)); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } /** * Determines whether to hoist the initializer of a ForStatement, ForInStatement, or * ForOfStatement. * * @param node The node to test. */ function shouldHoistForInitializer(node) { return ts.isVariableDeclarationList(node) && shouldHoistVariableDeclarationList(node); } /** * Visits the initializer of a ForStatement, ForInStatement, or ForOfStatement * * @param node The node to visit. */ function visitForInitializer(node) { if (!node) { return node; } if (shouldHoistForInitializer(node)) { var expressions = void 0; for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) { var variable = _a[_i]; expressions = ts.append(expressions, transformInitializedVariable(variable, /*isExportedDeclaration*/ false)); if (!variable.initializer) { hoistBindingElement(variable); } } return expressions ? ts.inlineExpressions(expressions) : ts.createOmittedExpression(); } else { return ts.visitEachChild(node, nestedElementVisitor, context); } } /** * Visits the body of a DoStatement to hoist declarations. * * @param node The node to visit. */ function visitDoStatement(node) { return ts.updateDo(node, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock), ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression)); } /** * Visits the body of a WhileStatement to hoist declarations. * * @param node The node to visit. */ function visitWhileStatement(node) { return ts.updateWhile(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock)); } /** * Visits the body of a LabeledStatement to hoist declarations. * * @param node The node to visit. */ function visitLabeledStatement(node) { return ts.updateLabel(node, node.label, ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock)); } /** * Visits the body of a WithStatement to hoist declarations. * * @param node The node to visit. */ function visitWithStatement(node) { return ts.updateWith(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.statement, nestedElementVisitor, ts.isStatement, ts.liftToBlock)); } /** * Visits the body of a SwitchStatement to hoist declarations. * * @param node The node to visit. */ function visitSwitchStatement(node) { return ts.updateSwitch(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNode(node.caseBlock, nestedElementVisitor, ts.isCaseBlock)); } /** * Visits the body of a CaseBlock to hoist declarations. * * @param node The node to visit. */ function visitCaseBlock(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.updateCaseBlock(node, ts.visitNodes(node.clauses, nestedElementVisitor, ts.isCaseOrDefaultClause)); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } /** * Visits the body of a CaseClause to hoist declarations. * * @param node The node to visit. */ function visitCaseClause(node) { return ts.updateCaseClause(node, ts.visitNode(node.expression, destructuringAndImportCallVisitor, ts.isExpression), ts.visitNodes(node.statements, nestedElementVisitor, ts.isStatement)); } /** * Visits the body of a DefaultClause to hoist declarations. * * @param node The node to visit. */ function visitDefaultClause(node) { return ts.visitEachChild(node, nestedElementVisitor, context); } /** * Visits the body of a TryStatement to hoist declarations. * * @param node The node to visit. */ function visitTryStatement(node) { return ts.visitEachChild(node, nestedElementVisitor, context); } /** * Visits the body of a CatchClause to hoist declarations. * * @param node The node to visit. */ function visitCatchClause(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.updateCatchClause(node, node.variableDeclaration, ts.visitNode(node.block, nestedElementVisitor, ts.isBlock)); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } /** * Visits the body of a Block to hoist declarations. * * @param node The node to visit. */ function visitBlock(node) { var savedEnclosingBlockScopedContainer = enclosingBlockScopedContainer; enclosingBlockScopedContainer = node; node = ts.visitEachChild(node, nestedElementVisitor, context); enclosingBlockScopedContainer = savedEnclosingBlockScopedContainer; return node; } // // Destructuring Assignment Visitors // /** * Visit nodes to flatten destructuring assignments to exported symbols. * * @param node The node to visit. */ function destructuringAndImportCallVisitor(node) { if (node.transformFlags & 1024 /* DestructuringAssignment */ && node.kind === 195 /* BinaryExpression */) { return visitDestructuringAssignment(node); } else if (ts.isImportCall(node)) { return visitImportCallExpression(node); } else if ((node.transformFlags & 2048 /* ContainsDestructuringAssignment */) || (node.transformFlags & 67108864 /* ContainsDynamicImport */)) { return ts.visitEachChild(node, destructuringAndImportCallVisitor, context); } else { return node; } } function visitImportCallExpression(node) { // import("./blah") // emit as // System.register([], function (_export, _context) { // return { // setters: [], // execute: () => { // _context.import('./blah'); // } // }; // }); return ts.createCall(ts.createPropertyAccess(contextObject, ts.createIdentifier("import")), /*typeArguments*/ undefined, ts.some(node.arguments) ? [ts.visitNode(node.arguments[0], destructuringAndImportCallVisitor)] : []); } /** * Visits a DestructuringAssignment to flatten destructuring to exported symbols. * * @param node The node to visit. */ function visitDestructuringAssignment(node) { if (hasExportedReferenceInDestructuringTarget(node.left)) { return ts.flattenDestructuringAssignment(node, destructuringAndImportCallVisitor, context, 0 /* All */, /*needsValue*/ true); } return ts.visitEachChild(node, destructuringAndImportCallVisitor, context); } /** * Determines whether the target of a destructuring assigment refers to an exported symbol. * * @param node The destructuring target. */ function hasExportedReferenceInDestructuringTarget(node) { if (ts.isAssignmentExpression(node, /*excludeCompoundAssignment*/ true)) { return hasExportedReferenceInDestructuringTarget(node.left); } else if (ts.isSpreadElement(node)) { return hasExportedReferenceInDestructuringTarget(node.expression); } else if (ts.isObjectLiteralExpression(node)) { return ts.some(node.properties, hasExportedReferenceInDestructuringTarget); } else if (ts.isArrayLiteralExpression(node)) { return ts.some(node.elements, hasExportedReferenceInDestructuringTarget); } else if (ts.isShorthandPropertyAssignment(node)) { return hasExportedReferenceInDestructuringTarget(node.name); } else if (ts.isPropertyAssignment(node)) { return hasExportedReferenceInDestructuringTarget(node.initializer); } else if (ts.isIdentifier(node)) { var container = resolver.getReferencedExportContainer(node); return container !== undefined && container.kind === 269 /* SourceFile */; } else { return false; } } // // Modifier Visitors // /** * Visit nodes to elide module-specific modifiers. * * @param node The node to visit. */ function modifierVisitor(node) { switch (node.kind) { case 84 /* ExportKeyword */: case 79 /* DefaultKeyword */: return undefined; } return node; } // // Emit Notification // /** * Hook for node emit notifications. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback A callback used to emit the node in the printer. */ function onEmitNode(hint, node, emitCallback) { if (node.kind === 269 /* SourceFile */) { var id = ts.getOriginalNodeId(node); currentSourceFile = node; moduleInfo = moduleInfoMap[id]; exportFunction = exportFunctionsMap[id]; noSubstitution = noSubstitutionMap[id]; if (noSubstitution) { delete noSubstitutionMap[id]; } previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; moduleInfo = undefined; exportFunction = undefined; noSubstitution = undefined; } else { previousOnEmitNode(hint, node, emitCallback); } } // // Substitutions // /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (isSubstitutionPrevented(node)) { return node; } if (hint === 1 /* Expression */) { return substituteExpression(node); } return node; } /** * Substitute the expression, if necessary. * * @param node The node to substitute. */ function substituteExpression(node) { switch (node.kind) { case 71 /* Identifier */: return substituteExpressionIdentifier(node); case 195 /* BinaryExpression */: return substituteBinaryExpression(node); case 193 /* PrefixUnaryExpression */: case 194 /* PostfixUnaryExpression */: return substituteUnaryExpression(node); } return node; } /** * Substitution for an Identifier expression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteExpressionIdentifier(node) { if (ts.getEmitFlags(node) & 4096 /* HelperName */) { var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile); if (externalHelpersModuleName) { return ts.createPropertyAccess(externalHelpersModuleName, node); } return node; } // When we see an identifier in an expression position that // points to an imported symbol, we should substitute a qualified // reference to the imported symbol if one is needed. // // - We do not substitute generated identifiers for any reason. // - We do not substitute identifiers tagged with the LocalName flag. if (!ts.isGeneratedIdentifier(node) && !ts.isLocalName(node)) { var importDeclaration = resolver.getReferencedImportDeclaration(node); if (importDeclaration) { if (ts.isImportClause(importDeclaration)) { return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent), ts.createIdentifier("default")), /*location*/ node); } else if (ts.isImportSpecifier(importDeclaration)) { return ts.setTextRange(ts.createPropertyAccess(ts.getGeneratedNameForNode(importDeclaration.parent.parent.parent), ts.getSynthesizedClone(importDeclaration.propertyName || importDeclaration.name)), /*location*/ node); } } } return node; } /** * Substitution for a BinaryExpression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteBinaryExpression(node) { // When we see an assignment expression whose left-hand side is an exported symbol, // we should ensure all exports of that symbol are updated with the correct value. // // - We do not substitute generated identifiers for any reason. // - We do not substitute identifiers tagged with the LocalName flag. // - We do not substitute identifiers that were originally the name of an enum or // namespace due to how they are transformed in TypeScript. // - We only substitute identifiers that are exported at the top level. if (ts.isAssignmentOperator(node.operatorToken.kind) && ts.isIdentifier(node.left) && !ts.isGeneratedIdentifier(node.left) && !ts.isLocalName(node.left) && !ts.isDeclarationNameOfEnumOrNamespace(node.left)) { var exportedNames = getExports(node.left); if (exportedNames) { // For each additional export of the declaration, apply an export assignment. var expression = node; for (var _i = 0, exportedNames_3 = exportedNames; _i < exportedNames_3.length; _i++) { var exportName = exportedNames_3[_i]; expression = createExportExpression(exportName, preventSubstitution(expression)); } return expression; } } return node; } /** * Substitution for a UnaryExpression that may contain an imported or exported symbol. * * @param node The node to substitute. */ function substituteUnaryExpression(node) { // When we see a prefix or postfix increment expression whose operand is an exported // symbol, we should ensure all exports of that symbol are updated with the correct // value. // // - We do not substitute generated identifiers for any reason. // - We do not substitute identifiers tagged with the LocalName flag. // - We do not substitute identifiers that were originally the name of an enum or // namespace due to how they are transformed in TypeScript. // - We only substitute identifiers that are exported at the top level. if ((node.operator === 43 /* PlusPlusToken */ || node.operator === 44 /* MinusMinusToken */) && ts.isIdentifier(node.operand) && !ts.isGeneratedIdentifier(node.operand) && !ts.isLocalName(node.operand) && !ts.isDeclarationNameOfEnumOrNamespace(node.operand)) { var exportedNames = getExports(node.operand); if (exportedNames) { var expression = node.kind === 194 /* PostfixUnaryExpression */ ? ts.setTextRange(ts.createPrefix(node.operator, node.operand), node) : node; for (var _i = 0, exportedNames_4 = exportedNames; _i < exportedNames_4.length; _i++) { var exportName = exportedNames_4[_i]; expression = createExportExpression(exportName, preventSubstitution(expression)); } if (node.kind === 194 /* PostfixUnaryExpression */) { expression = node.operator === 43 /* PlusPlusToken */ ? ts.createSubtract(preventSubstitution(expression), ts.createLiteral(1)) : ts.createAdd(preventSubstitution(expression), ts.createLiteral(1)); } return expression; } } return node; } /** * Gets the exports of a name. * * @param name The name. */ function getExports(name) { var exportedNames; if (!ts.isGeneratedIdentifier(name)) { var valueDeclaration = resolver.getReferencedImportDeclaration(name) || resolver.getReferencedValueDeclaration(name); if (valueDeclaration) { var exportContainer = resolver.getReferencedExportContainer(name, /*prefixLocals*/ false); if (exportContainer && exportContainer.kind === 269 /* SourceFile */) { exportedNames = ts.append(exportedNames, ts.getDeclarationName(valueDeclaration)); } exportedNames = ts.addRange(exportedNames, moduleInfo && moduleInfo.exportedBindings[ts.getOriginalNodeId(valueDeclaration)]); } } return exportedNames; } /** * Prevent substitution of a node for this transformer. * * @param node The node which should not be substituted. */ function preventSubstitution(node) { if (noSubstitution === undefined) noSubstitution = []; noSubstitution[ts.getNodeId(node)] = true; return node; } /** * Determines whether a node should not be substituted. * * @param node The node to test. */ function isSubstitutionPrevented(node) { return noSubstitution && node.id && noSubstitution[node.id]; } } ts.transformSystemModule = transformSystemModule; })(ts || (ts = {})); /// /// /*@internal*/ var ts; (function (ts) { function transformES2015Module(context) { var compilerOptions = context.getCompilerOptions(); var previousOnEmitNode = context.onEmitNode; var previousOnSubstituteNode = context.onSubstituteNode; context.onEmitNode = onEmitNode; context.onSubstituteNode = onSubstituteNode; context.enableEmitNotification(269 /* SourceFile */); context.enableSubstitution(71 /* Identifier */); var currentSourceFile; return transformSourceFile; function transformSourceFile(node) { if (node.isDeclarationFile) { return node; } if (ts.isExternalModule(node) || compilerOptions.isolatedModules) { var externalHelpersModuleName = ts.getOrCreateExternalHelpersModuleNameIfNeeded(node, compilerOptions); if (externalHelpersModuleName) { var statements = []; var statementOffset = ts.addPrologue(statements, node.statements); ts.append(statements, ts.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(externalHelpersModuleName)), ts.createLiteral(ts.externalHelpersModuleNameText))); ts.addRange(statements, ts.visitNodes(node.statements, visitor, ts.isStatement, statementOffset)); return ts.updateSourceFileNode(node, ts.setTextRange(ts.createNodeArray(statements), node.statements)); } else { return ts.visitEachChild(node, visitor, context); } } return node; } function visitor(node) { switch (node.kind) { case 238 /* ImportEqualsDeclaration */: // Elide `import=` as it is not legal with --module ES6 return undefined; case 244 /* ExportAssignment */: return visitExportAssignment(node); } return node; } function visitExportAssignment(node) { // Elide `export=` as it is not legal with --module ES6 return node.isExportEquals ? undefined : node; } // // Emit Notification // /** * Hook for node emit. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emit A callback used to emit the node in the printer. */ function onEmitNode(hint, node, emitCallback) { if (ts.isSourceFile(node)) { currentSourceFile = node; previousOnEmitNode(hint, node, emitCallback); currentSourceFile = undefined; } else { previousOnEmitNode(hint, node, emitCallback); } } // // Substitutions // /** * Hooks node substitutions. * * @param hint A hint as to the intended usage of the node. * @param node The node to substitute. */ function onSubstituteNode(hint, node) { node = previousOnSubstituteNode(hint, node); if (ts.isIdentifier(node) && hint === 1 /* Expression */) { return substituteExpressionIdentifier(node); } return node; } function substituteExpressionIdentifier(node) { if (ts.getEmitFlags(node) & 4096 /* HelperName */) { var externalHelpersModuleName = ts.getExternalHelpersModuleName(currentSourceFile); if (externalHelpersModuleName) { return ts.createPropertyAccess(externalHelpersModuleName, node); } } return node; } } ts.transformES2015Module = transformES2015Module; })(ts || (ts = {})); /// /// /// /// /// /// /// /// /// /// /// /// /// /* @internal */ var ts; (function (ts) { function getModuleTransformer(moduleKind) { switch (moduleKind) { case ts.ModuleKind.ESNext: case ts.ModuleKind.ES2015: return ts.transformES2015Module; case ts.ModuleKind.System: return ts.transformSystemModule; default: return ts.transformModule; } } var TransformationState; (function (TransformationState) { TransformationState[TransformationState["Uninitialized"] = 0] = "Uninitialized"; TransformationState[TransformationState["Initialized"] = 1] = "Initialized"; TransformationState[TransformationState["Completed"] = 2] = "Completed"; TransformationState[TransformationState["Disposed"] = 3] = "Disposed"; })(TransformationState || (TransformationState = {})); var SyntaxKindFeatureFlags; (function (SyntaxKindFeatureFlags) { SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["Substitution"] = 1] = "Substitution"; SyntaxKindFeatureFlags[SyntaxKindFeatureFlags["EmitNotifications"] = 2] = "EmitNotifications"; })(SyntaxKindFeatureFlags || (SyntaxKindFeatureFlags = {})); function getTransformers(compilerOptions, customTransformers) { var jsx = compilerOptions.jsx; var languageVersion = ts.getEmitScriptTarget(compilerOptions); var moduleKind = ts.getEmitModuleKind(compilerOptions); var transformers = []; ts.addRange(transformers, customTransformers && customTransformers.before); transformers.push(ts.transformTypeScript); if (jsx === 2 /* React */) { transformers.push(ts.transformJsx); } if (languageVersion < 6 /* ESNext */) { transformers.push(ts.transformESNext); } if (languageVersion < 4 /* ES2017 */) { transformers.push(ts.transformES2017); } if (languageVersion < 3 /* ES2016 */) { transformers.push(ts.transformES2016); } if (languageVersion < 2 /* ES2015 */) { transformers.push(ts.transformES2015); transformers.push(ts.transformGenerators); } transformers.push(getModuleTransformer(moduleKind)); // The ES5 transformer is last so that it can substitute expressions like `exports.default` // for ES3. if (languageVersion < 1 /* ES5 */) { transformers.push(ts.transformES5); } ts.addRange(transformers, customTransformers && customTransformers.after); return transformers; } ts.getTransformers = getTransformers; /** * Transforms an array of SourceFiles by passing them through each transformer. * * @param resolver The emit resolver provided by the checker. * @param host The emit host object used to interact with the file system. * @param options Compiler options to surface in the `TransformationContext`. * @param nodes An array of nodes to transform. * @param transforms An array of `TransformerFactory` callbacks. * @param allowDtsFiles A value indicating whether to allow the transformation of .d.ts files. */ function transformNodes(resolver, host, options, nodes, transformers, allowDtsFiles) { var enabledSyntaxKindFeatures = new Array(296 /* Count */); var lexicalEnvironmentVariableDeclarations; var lexicalEnvironmentFunctionDeclarations; var lexicalEnvironmentVariableDeclarationsStack = []; var lexicalEnvironmentFunctionDeclarationsStack = []; var lexicalEnvironmentStackOffset = 0; var lexicalEnvironmentSuspended = false; var emitHelpers; var onSubstituteNode = function (_, node) { return node; }; var onEmitNode = function (hint, node, callback) { return callback(hint, node); }; var state = 0 /* Uninitialized */; // The transformation context is provided to each transformer as part of transformer // initialization. var context = { getCompilerOptions: function () { return options; }, getEmitResolver: function () { return resolver; }, getEmitHost: function () { return host; }, startLexicalEnvironment: startLexicalEnvironment, suspendLexicalEnvironment: suspendLexicalEnvironment, resumeLexicalEnvironment: resumeLexicalEnvironment, endLexicalEnvironment: endLexicalEnvironment, hoistVariableDeclaration: hoistVariableDeclaration, hoistFunctionDeclaration: hoistFunctionDeclaration, requestEmitHelper: requestEmitHelper, readEmitHelpers: readEmitHelpers, enableSubstitution: enableSubstitution, enableEmitNotification: enableEmitNotification, isSubstitutionEnabled: isSubstitutionEnabled, isEmitNotificationEnabled: isEmitNotificationEnabled, get onSubstituteNode() { return onSubstituteNode; }, set onSubstituteNode(value) { ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed."); ts.Debug.assert(value !== undefined, "Value must not be 'undefined'"); onSubstituteNode = value; }, get onEmitNode() { return onEmitNode; }, set onEmitNode(value) { ts.Debug.assert(state < 1 /* Initialized */, "Cannot modify transformation hooks after initialization has completed."); ts.Debug.assert(value !== undefined, "Value must not be 'undefined'"); onEmitNode = value; } }; // Ensure the parse tree is clean before applying transformations for (var _i = 0, nodes_4 = nodes; _i < nodes_4.length; _i++) { var node = nodes_4[_i]; ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node))); } ts.performance.mark("beforeTransform"); // Chain together and initialize each transformer. var transformation = ts.chain.apply(void 0, transformers)(context); // prevent modification of transformation hooks. state = 1 /* Initialized */; // Transform each node. var transformed = ts.map(nodes, allowDtsFiles ? transformation : transformRoot); // prevent modification of the lexical environment. state = 2 /* Completed */; ts.performance.mark("afterTransform"); ts.performance.measure("transformTime", "beforeTransform", "afterTransform"); return { transformed: transformed, substituteNode: substituteNode, emitNodeWithNotification: emitNodeWithNotification, dispose: dispose }; function transformRoot(node) { return node && (!ts.isSourceFile(node) || !node.isDeclarationFile) ? transformation(node) : node; } /** * Enables expression substitutions in the pretty printer for the provided SyntaxKind. */ function enableSubstitution(kind) { ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed."); enabledSyntaxKindFeatures[kind] |= 1 /* Substitution */; } /** * Determines whether expression substitutions are enabled for the provided node. */ function isSubstitutionEnabled(node) { return (enabledSyntaxKindFeatures[node.kind] & 1 /* Substitution */) !== 0 && (ts.getEmitFlags(node) & 4 /* NoSubstitution */) === 0; } /** * Emits a node with possible substitution. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node or its substitute. */ function substituteNode(hint, node) { ts.Debug.assert(state < 3 /* Disposed */, "Cannot substitute a node after the result is disposed."); return node && isSubstitutionEnabled(node) && onSubstituteNode(hint, node) || node; } /** * Enables before/after emit notifications in the pretty printer for the provided SyntaxKind. */ function enableEmitNotification(kind) { ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed."); enabledSyntaxKindFeatures[kind] |= 2 /* EmitNotifications */; } /** * Determines whether before/after emit notifications should be raised in the pretty * printer when it emits a node. */ function isEmitNotificationEnabled(node) { return (enabledSyntaxKindFeatures[node.kind] & 2 /* EmitNotifications */) !== 0 || (ts.getEmitFlags(node) & 2 /* AdviseOnEmitNode */) !== 0; } /** * Emits a node with possible emit notification. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ function emitNodeWithNotification(hint, node, emitCallback) { ts.Debug.assert(state < 3 /* Disposed */, "Cannot invoke TransformationResult callbacks after the result is disposed."); if (node) { if (isEmitNotificationEnabled(node)) { onEmitNode(hint, node, emitCallback); } else { emitCallback(hint, node); } } } /** * Records a hoisted variable declaration for the provided name within a lexical environment. */ function hoistVariableDeclaration(name) { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); var decl = ts.setEmitFlags(ts.createVariableDeclaration(name), 64 /* NoNestedSourceMaps */); if (!lexicalEnvironmentVariableDeclarations) { lexicalEnvironmentVariableDeclarations = [decl]; } else { lexicalEnvironmentVariableDeclarations.push(decl); } } /** * Records a hoisted function declaration within a lexical environment. */ function hoistFunctionDeclaration(func) { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); if (!lexicalEnvironmentFunctionDeclarations) { lexicalEnvironmentFunctionDeclarations = [func]; } else { lexicalEnvironmentFunctionDeclarations.push(func); } } /** * Starts a new lexical environment. Any existing hoisted variable or function declarations * are pushed onto a stack, and the related storage variables are reset. */ function startLexicalEnvironment() { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); // Save the current lexical environment. Rather than resizing the array we adjust the // stack size variable. This allows us to reuse existing array slots we've // already allocated between transformations to avoid allocation and GC overhead during // transformation. lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentVariableDeclarations; lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset] = lexicalEnvironmentFunctionDeclarations; lexicalEnvironmentStackOffset++; lexicalEnvironmentVariableDeclarations = undefined; lexicalEnvironmentFunctionDeclarations = undefined; } /** Suspends the current lexical environment, usually after visiting a parameter list. */ function suspendLexicalEnvironment() { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is already suspended."); lexicalEnvironmentSuspended = true; } /** Resumes a suspended lexical environment, usually before visiting a function body. */ function resumeLexicalEnvironment() { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); ts.Debug.assert(lexicalEnvironmentSuspended, "Lexical environment is not suspended."); lexicalEnvironmentSuspended = false; } /** * Ends a lexical environment. The previous set of hoisted declarations are restored and * any hoisted declarations added in this environment are returned. */ function endLexicalEnvironment() { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the lexical environment during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the lexical environment after transformation has completed."); ts.Debug.assert(!lexicalEnvironmentSuspended, "Lexical environment is suspended."); var statements; if (lexicalEnvironmentVariableDeclarations || lexicalEnvironmentFunctionDeclarations) { if (lexicalEnvironmentFunctionDeclarations) { statements = lexicalEnvironmentFunctionDeclarations.slice(); } if (lexicalEnvironmentVariableDeclarations) { var statement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList(lexicalEnvironmentVariableDeclarations)); if (!statements) { statements = [statement]; } else { statements.push(statement); } } } // Restore the previous lexical environment. lexicalEnvironmentStackOffset--; lexicalEnvironmentVariableDeclarations = lexicalEnvironmentVariableDeclarationsStack[lexicalEnvironmentStackOffset]; lexicalEnvironmentFunctionDeclarations = lexicalEnvironmentFunctionDeclarationsStack[lexicalEnvironmentStackOffset]; if (lexicalEnvironmentStackOffset === 0) { lexicalEnvironmentVariableDeclarationsStack = []; lexicalEnvironmentFunctionDeclarationsStack = []; } return statements; } function requestEmitHelper(helper) { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed."); ts.Debug.assert(!helper.scoped, "Cannot request a scoped emit helper."); emitHelpers = ts.append(emitHelpers, helper); } function readEmitHelpers() { ts.Debug.assert(state > 0 /* Uninitialized */, "Cannot modify the transformation context during initialization."); ts.Debug.assert(state < 2 /* Completed */, "Cannot modify the transformation context after transformation has completed."); var helpers = emitHelpers; emitHelpers = undefined; return helpers; } function dispose() { if (state < 3 /* Disposed */) { // Clean up emit nodes on parse tree for (var _i = 0, nodes_5 = nodes; _i < nodes_5.length; _i++) { var node = nodes_5[_i]; ts.disposeEmitNodes(ts.getSourceFileOfNode(ts.getParseTreeNode(node))); } // Release references to external entries for GC purposes. lexicalEnvironmentVariableDeclarations = undefined; lexicalEnvironmentVariableDeclarationsStack = undefined; lexicalEnvironmentFunctionDeclarations = undefined; lexicalEnvironmentFunctionDeclarationsStack = undefined; onSubstituteNode = undefined; onEmitNode = undefined; emitHelpers = undefined; // Prevent further use of the transformation result. state = 3 /* Disposed */; } } } ts.transformNodes = transformNodes; })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { function getDeclarationDiagnostics(host, resolver, targetSourceFile) { var declarationDiagnostics = ts.createDiagnosticCollection(); ts.forEachEmittedFile(host, getDeclarationDiagnosticsFromFile, targetSourceFile); return declarationDiagnostics.getDiagnostics(targetSourceFile ? targetSourceFile.fileName : undefined); function getDeclarationDiagnosticsFromFile(_a, sourceFileOrBundle) { var declarationFilePath = _a.declarationFilePath; emitDeclarations(host, resolver, declarationDiagnostics, declarationFilePath, sourceFileOrBundle, /*emitOnlyDtsFiles*/ false); } } ts.getDeclarationDiagnostics = getDeclarationDiagnostics; function emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles) { var sourceFiles = sourceFileOrBundle.kind === 270 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle]; var isBundledEmit = sourceFileOrBundle.kind === 270 /* Bundle */; var newLine = host.getNewLine(); var compilerOptions = host.getCompilerOptions(); var write; var writeLine; var increaseIndent; var decreaseIndent; var writeTextOfNode; var writer; createAndSetNewTextWriterWithSymbolWriter(); var enclosingDeclaration; var resultHasExternalModuleIndicator; var currentText; var currentLineMap; var currentIdentifiers; var isCurrentFileExternalModule; var reportedDeclarationError = false; var errorNameNode; var emitJsDocComments = compilerOptions.removeComments ? ts.noop : writeJsDocComments; var emit = compilerOptions.stripInternal ? stripInternal : emitNode; var needsDeclare = true; var moduleElementDeclarationEmitInfo = []; var asynchronousSubModuleDeclarationEmitInfo; // Contains the reference paths that needs to go in the declaration file. // Collecting this separately because reference paths need to be first thing in the declaration file // and we could be collecting these paths from multiple files into single one with --out option var referencesOutput = ""; var usedTypeDirectiveReferences; // Emit references corresponding to each file var emittedReferencedFiles = []; var addedGlobalFileReference = false; var allSourcesModuleElementDeclarationEmitInfo = []; ts.forEach(sourceFiles, function (sourceFile) { // Dont emit for javascript file if (ts.isSourceFileJavaScript(sourceFile)) { return; } // Check what references need to be added if (!compilerOptions.noResolve) { ts.forEach(sourceFile.referencedFiles, function (fileReference) { var referencedFile = ts.tryResolveScriptReference(host, sourceFile, fileReference); // Emit reference in dts, if the file reference was not already emitted if (referencedFile && !ts.contains(emittedReferencedFiles, referencedFile)) { // Add a reference to generated dts file, // global file reference is added only // - if it is not bundled emit (because otherwise it would be self reference) // - and it is not already added if (writeReferencePath(referencedFile, !isBundledEmit && !addedGlobalFileReference, emitOnlyDtsFiles)) { addedGlobalFileReference = true; } emittedReferencedFiles.push(referencedFile); } }); } resultHasExternalModuleIndicator = false; if (!isBundledEmit || !ts.isExternalModule(sourceFile)) { needsDeclare = true; emitSourceFile(sourceFile); } else if (ts.isExternalModule(sourceFile)) { needsDeclare = false; write("declare module \"" + ts.getResolvedExternalModuleName(host, sourceFile) + "\" {"); writeLine(); increaseIndent(); emitSourceFile(sourceFile); decreaseIndent(); write("}"); writeLine(); } // create asynchronous output for the importDeclarations if (moduleElementDeclarationEmitInfo.length) { var oldWriter = writer; ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) { if (aliasEmitInfo.isVisible && !aliasEmitInfo.asynchronousOutput) { ts.Debug.assert(aliasEmitInfo.node.kind === 239 /* ImportDeclaration */); createAndSetNewTextWriterWithSymbolWriter(); ts.Debug.assert(aliasEmitInfo.indent === 0 || (aliasEmitInfo.indent === 1 && isBundledEmit)); for (var i = 0; i < aliasEmitInfo.indent; i++) { increaseIndent(); } writeImportDeclaration(aliasEmitInfo.node); aliasEmitInfo.asynchronousOutput = writer.getText(); for (var i = 0; i < aliasEmitInfo.indent; i++) { decreaseIndent(); } } }); setWriter(oldWriter); allSourcesModuleElementDeclarationEmitInfo = allSourcesModuleElementDeclarationEmitInfo.concat(moduleElementDeclarationEmitInfo); moduleElementDeclarationEmitInfo = []; } if (!isBundledEmit && ts.isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) { // if file was external module with augmentations - this fact should be preserved in .d.ts as well. // in case if we didn't write any external module specifiers in .d.ts we need to emit something // that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here. write("export {};"); writeLine(); } }); if (usedTypeDirectiveReferences) { ts.forEachKey(usedTypeDirectiveReferences, function (directive) { referencesOutput += "/// " + newLine; }); } return { reportedDeclarationError: reportedDeclarationError, moduleElementDeclarationEmitInfo: allSourcesModuleElementDeclarationEmitInfo, synchronousDeclarationOutput: writer.getText(), referencesOutput: referencesOutput, }; function hasInternalAnnotation(range) { var comment = currentText.substring(range.pos, range.end); return ts.stringContains(comment, "@internal"); } function stripInternal(node) { if (node) { var leadingCommentRanges = ts.getLeadingCommentRanges(currentText, node.pos); if (ts.forEach(leadingCommentRanges, hasInternalAnnotation)) { return; } emitNode(node); } } function createAndSetNewTextWriterWithSymbolWriter() { var writer = ts.createTextWriter(newLine); writer.trackSymbol = trackSymbol; writer.reportInaccessibleThisError = reportInaccessibleThisError; writer.reportInaccessibleUniqueSymbolError = reportInaccessibleUniqueSymbolError; writer.reportPrivateInBaseOfClassExpression = reportPrivateInBaseOfClassExpression; writer.writeKeyword = writer.write; writer.writeOperator = writer.write; writer.writePunctuation = writer.write; writer.writeSpace = writer.write; writer.writeStringLiteral = writer.writeLiteral; writer.writeParameter = writer.write; writer.writeProperty = writer.write; writer.writeSymbol = writer.write; setWriter(writer); } function setWriter(newWriter) { writer = newWriter; write = newWriter.write; writeTextOfNode = newWriter.writeTextOfNode; writeLine = newWriter.writeLine; increaseIndent = newWriter.increaseIndent; decreaseIndent = newWriter.decreaseIndent; } function writeAsynchronousModuleElements(nodes) { var oldWriter = writer; ts.forEach(nodes, function (declaration) { var nodeToCheck; if (declaration.kind === 227 /* VariableDeclaration */) { nodeToCheck = declaration.parent.parent; } else if (declaration.kind === 242 /* NamedImports */ || declaration.kind === 243 /* ImportSpecifier */ || declaration.kind === 240 /* 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 === 239 /* 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 === 234 /* ModuleDeclaration */) { ts.Debug.assert(asynchronousSubModuleDeclarationEmitInfo === undefined); asynchronousSubModuleDeclarationEmitInfo = []; } writeModuleElement(nodeToCheck); if (nodeToCheck.kind === 234 /* ModuleDeclaration */) { moduleElementEmitInfo.subModuleElementDeclarationEmitInfo = asynchronousSubModuleDeclarationEmitInfo; asynchronousSubModuleDeclarationEmitInfo = undefined; } moduleElementEmitInfo.asynchronousOutput = writer.getText(); } } }); setWriter(oldWriter); } function recordTypeReferenceDirectivesIfNecessary(typeReferenceDirectives) { if (!typeReferenceDirectives) { return; } if (!usedTypeDirectiveReferences) { usedTypeDirectiveReferences = ts.createMap(); } for (var _i = 0, typeReferenceDirectives_1 = typeReferenceDirectives; _i < typeReferenceDirectives_1.length; _i++) { var directive = typeReferenceDirectives_1[_i]; if (!usedTypeDirectiveReferences.has(directive)) { usedTypeDirectiveReferences.set(directive, directive); } } } function handleSymbolAccessibilityError(symbolAccessibilityResult) { if (symbolAccessibilityResult.accessibility === 0 /* Accessible */) { // write the aliases if (symbolAccessibilityResult && symbolAccessibilityResult.aliasesToMakeVisible) { writeAsynchronousModuleElements(symbolAccessibilityResult.aliasesToMakeVisible); } } else { // Report error reportedDeclarationError = true; var errorInfo = writer.getSymbolAccessibilityDiagnostic(symbolAccessibilityResult); if (errorInfo) { if (errorInfo.typeName) { emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, ts.getTextOfNodeFromSourceText(currentText, errorInfo.typeName), symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName)); } else { emitterDiagnostics.add(ts.createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, symbolAccessibilityResult.errorSymbolName, symbolAccessibilityResult.errorModuleName)); } } } } function trackSymbol(symbol, enclosingDeclaration, meaning) { handleSymbolAccessibilityError(resolver.isSymbolAccessible(symbol, enclosingDeclaration, meaning, /*shouldComputeAliasesToMakeVisible*/ true)); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForSymbol(symbol, meaning)); } function reportPrivateInBaseOfClassExpression(propertyName) { if (errorNameNode) { reportedDeclarationError = true; emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.Property_0_of_exported_class_expression_may_not_be_private_or_protected, propertyName)); } } function reportInaccessibleUniqueSymbolError() { if (errorNameNode) { reportedDeclarationError = true; emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "unique symbol")); } } function reportInaccessibleThisError() { if (errorNameNode) { reportedDeclarationError = true; emitterDiagnostics.add(ts.createDiagnosticForNode(errorNameNode, ts.Diagnostics.The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary, ts.declarationNameToString(errorNameNode), "this")); } } function writeTypeOfDeclaration(declaration, type, getSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; write(": "); // use the checker's type, not the declared type, // for optional parameter properties // and also for non-optional initialized parameters that aren't a parameter property // these types may need to add `undefined`. var shouldUseResolverType = declaration.kind === 147 /* Parameter */ && (resolver.isRequiredInitializedParameter(declaration) || resolver.isOptionalUninitializedParameterProperty(declaration)); if (type && !shouldUseResolverType) { // Write the type emitType(type); } else { errorNameNode = declaration.name; var format = 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */ | (shouldUseResolverType ? 8192 /* AddUndefined */ : 0); resolver.writeTypeOfDeclaration(declaration, enclosingDeclaration, format, writer); errorNameNode = undefined; } } function writeReturnTypeAtSignature(signature, getSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; write(": "); if (signature.type) { // Write the type emitType(signature.type); } else { errorNameNode = signature.name; resolver.writeReturnTypeOfSignatureDeclaration(signature, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer); errorNameNode = undefined; } } function emitLines(nodes) { for (var _i = 0, nodes_6 = nodes; _i < nodes_6.length; _i++) { var node = nodes_6[_i]; emit(node); } } function emitSeparatedList(nodes, separator, eachNodeEmitFn, canEmitFn) { var currentWriterPos = writer.getTextPos(); for (var _i = 0, nodes_7 = nodes; _i < nodes_7.length; _i++) { var node = nodes_7[_i]; if (!canEmitFn || canEmitFn(node)) { if (currentWriterPos !== writer.getTextPos()) { write(separator); } currentWriterPos = writer.getTextPos(); eachNodeEmitFn(node); } } } function emitCommaList(nodes, eachNodeEmitFn, canEmitFn) { emitSeparatedList(nodes, ", ", eachNodeEmitFn, canEmitFn); } function writeJsDocComments(declaration) { if (declaration) { var jsDocComments = ts.getJSDocCommentRanges(declaration, currentText); ts.emitNewLineBeforeLeadingComments(currentLineMap, writer, declaration, jsDocComments); // jsDoc comments are emitted at /*leading comment1 */space/*leading comment*/space ts.emitComments(currentText, currentLineMap, writer, jsDocComments, /*leadingSeparator*/ false, /*trailingSeparator*/ true, newLine, ts.writeCommentRange); } } function emitTypeWithNewGetSymbolAccessibilityDiagnostic(type, getSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; emitType(type); } function emitType(type) { switch (type.kind) { case 119 /* AnyKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 122 /* BooleanKeyword */: case 134 /* ObjectKeyword */: case 137 /* SymbolKeyword */: case 105 /* VoidKeyword */: case 139 /* UndefinedKeyword */: case 95 /* NullKeyword */: case 130 /* NeverKeyword */: case 170 /* ThisType */: case 174 /* LiteralType */: return writeTextOfNode(currentText, type); case 202 /* ExpressionWithTypeArguments */: return emitExpressionWithTypeArguments(type); case 160 /* TypeReference */: return emitTypeReference(type); case 163 /* TypeQuery */: return emitTypeQuery(type); case 165 /* ArrayType */: return emitArrayType(type); case 166 /* TupleType */: return emitTupleType(type); case 167 /* UnionType */: return emitUnionType(type); case 168 /* IntersectionType */: return emitIntersectionType(type); case 169 /* ParenthesizedType */: return emitParenType(type); case 171 /* TypeOperator */: return emitTypeOperator(type); case 172 /* IndexedAccessType */: return emitIndexedAccessType(type); case 173 /* MappedType */: return emitMappedType(type); case 161 /* FunctionType */: case 162 /* ConstructorType */: return emitSignatureDeclarationWithJsDocComments(type); case 164 /* TypeLiteral */: return emitTypeLiteral(type); case 71 /* Identifier */: return emitEntityName(type); case 144 /* QualifiedName */: return emitEntityName(type); case 159 /* TypePredicate */: return emitTypePredicate(type); } function writeEntityName(entityName) { if (entityName.kind === 71 /* Identifier */) { writeTextOfNode(currentText, entityName); } else { var left = entityName.kind === 144 /* QualifiedName */ ? entityName.left : entityName.expression; var right = entityName.kind === 144 /* 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 === 238 /* ImportEqualsDeclaration */ ? entityName.parent : enclosingDeclaration); handleSymbolAccessibilityError(visibilityResult); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName)); writeEntityName(entityName); } function emitExpressionWithTypeArguments(node) { if (ts.isEntityNameExpression(node.expression)) { ts.Debug.assert(node.expression.kind === 71 /* Identifier */ || node.expression.kind === 180 /* PropertyAccessExpression */); emitEntityName(node.expression); if (node.typeArguments) { write("<"); emitCommaList(node.typeArguments, emitType); write(">"); } } } function emitTypeReference(type) { emitEntityName(type.typeName); if (type.typeArguments) { write("<"); emitCommaList(type.typeArguments, emitType); write(">"); } } function emitTypePredicate(type) { writeTextOfNode(currentText, type.parameterName); write(" is "); emitType(type.type); } function emitTypeQuery(type) { write("typeof "); emitEntityName(type.exprName); } function emitArrayType(type) { emitType(type.elementType); write("[]"); } function emitTupleType(type) { write("["); emitCommaList(type.elementTypes, emitType); write("]"); } function emitUnionType(type) { emitSeparatedList(type.types, " | ", emitType); } function emitIntersectionType(type) { emitSeparatedList(type.types, " & ", emitType); } function emitParenType(type) { write("("); emitType(type.type); write(")"); } function emitTypeOperator(type) { write(ts.tokenToString(type.operator)); write(" "); emitType(type.type); } function emitIndexedAccessType(node) { emitType(node.objectType); write("["); emitType(node.indexType); write("]"); } function emitMappedType(node) { var prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; write("{"); writeLine(); increaseIndent(); if (node.readonlyToken) { write("readonly "); } write("["); writeEntityName(node.typeParameter.name); write(" in "); emitType(node.typeParameter.constraint); write("]"); if (node.questionToken) { write("?"); } write(": "); emitType(node.type); write(";"); writeLine(); decreaseIndent(); write("}"); enclosingDeclaration = prevEnclosingDeclaration; } function emitTypeLiteral(type) { write("{"); if (type.members.length) { writeLine(); increaseIndent(); // write members emitLines(type.members); decreaseIndent(); } write("}"); } } function emitSourceFile(node) { currentText = node.text; currentLineMap = ts.getLineStarts(node); currentIdentifiers = node.identifiers; isCurrentFileExternalModule = ts.isExternalModule(node); enclosingDeclaration = node; ts.emitDetachedComments(currentText, currentLineMap, writer, ts.writeCommentRange, node, newLine, /*removeComments*/ true); emitLines(node.statements); } // Return a temp variable name to be used in `export default`/`export class ... extends` statements. // The temp name will be of the form _default_counter. // Note that export default is only allowed at most once in a module, so we // do not need to keep track of created temp names. function getExportTempVariableName(baseName) { if (!currentIdentifiers.has(baseName)) { return baseName; } var count = 0; while (true) { count++; var name = baseName + "_" + count; if (!currentIdentifiers.has(name)) { return name; } } } function emitTempVariableDeclaration(expr, baseName, diagnostic, needsDeclare) { var tempVarName = getExportTempVariableName(baseName); if (needsDeclare) { write("declare "); } write("const "); write(tempVarName); write(": "); writer.getSymbolAccessibilityDiagnostic = function () { return diagnostic; }; resolver.writeTypeOfExpression(expr, enclosingDeclaration, 4 /* UseTypeOfFunction */ | 16384 /* WriteClassExpressionAsTypeLiteral */, writer); write(";"); writeLine(); return tempVarName; } function emitExportAssignment(node) { if (node.expression.kind === 71 /* Identifier */) { write(node.isExportEquals ? "export = " : "export default "); writeTextOfNode(currentText, node.expression); } else { var tempVarName = emitTempVariableDeclaration(node.expression, "_default", { diagnosticMessage: ts.Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0, errorNode: node }, needsDeclare); write(node.isExportEquals ? "export = " : "export default "); write(tempVarName); } write(";"); writeLine(); // Make all the declarations visible for the export name if (node.expression.kind === 71 /* Identifier */) { var nodes = resolver.collectLinkedAliases(node.expression); // write each of these declarations asynchronously writeAsynchronousModuleElements(nodes); } } function isModuleElementVisible(node) { return resolver.isDeclarationVisible(node); } function emitModuleElement(node, isModuleElementVisible) { if (isModuleElementVisible) { writeModuleElement(node); } else if (node.kind === 238 /* ImportEqualsDeclaration */ || (node.parent.kind === 269 /* SourceFile */ && isCurrentFileExternalModule)) { var isVisible = void 0; if (asynchronousSubModuleDeclarationEmitInfo && node.parent.kind !== 269 /* 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 === 239 /* 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 229 /* FunctionDeclaration */: return writeFunctionDeclaration(node); case 209 /* VariableStatement */: return writeVariableStatement(node); case 231 /* InterfaceDeclaration */: return writeInterfaceDeclaration(node); case 230 /* ClassDeclaration */: return writeClassDeclaration(node); case 232 /* TypeAliasDeclaration */: return writeTypeAliasDeclaration(node); case 233 /* EnumDeclaration */: return writeEnumDeclaration(node); case 234 /* ModuleDeclaration */: return writeModuleDeclaration(node); case 238 /* ImportEqualsDeclaration */: return writeImportEqualsDeclaration(node); case 239 /* 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 === 269 /* SourceFile */) { var modifiers = ts.getModifierFlags(node); // If the node is exported if (modifiers & 1 /* Export */) { write("export "); } if (modifiers & 512 /* Default */) { write("default "); } else if (node.kind !== 231 /* InterfaceDeclaration */ && needsDeclare) { write("declare "); } } } function emitClassMemberDeclarationFlags(flags) { if (flags & 8 /* Private */) { write("private "); } else if (flags & 16 /* Protected */) { write("protected "); } if (flags & 32 /* Static */) { write("static "); } if (flags & 64 /* Readonly */) { write("readonly "); } if (flags & 128 /* Abstract */) { write("abstract "); } } function writeImportEqualsDeclaration(node) { // note usage of writer. methods instead of aliases created, just to make sure we are using // correct writer especially to handle asynchronous alias writing emitJsDocComments(node); if (ts.hasModifier(node, 1 /* Export */)) { write("export "); } write("import "); writeTextOfNode(currentText, node.name); write(" = "); if (ts.isInternalModuleImportEqualsDeclaration(node)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.moduleReference, getImportEntityNameVisibilityError); write(";"); } else { write("require("); emitExternalModuleSpecifier(node); write(");"); } writer.writeLine(); function getImportEntityNameVisibilityError() { return { diagnosticMessage: ts.Diagnostics.Import_declaration_0_is_using_private_name_1, errorNode: node, typeName: node.name }; } } function isVisibleNamedBinding(namedBindings) { if (namedBindings) { if (namedBindings.kind === 241 /* NamespaceImport */) { return resolver.isDeclarationVisible(namedBindings); } else { return ts.forEach(namedBindings.elements, function (namedImport) { return resolver.isDeclarationVisible(namedImport); }); } } } function writeImportDeclaration(node) { emitJsDocComments(node); if (ts.hasModifier(node, 1 /* Export */)) { write("export "); } write("import "); if (node.importClause) { var currentWriterPos = writer.getTextPos(); if (node.importClause.name && resolver.isDeclarationVisible(node.importClause)) { writeTextOfNode(currentText, node.importClause.name); } if (node.importClause.namedBindings && isVisibleNamedBinding(node.importClause.namedBindings)) { if (currentWriterPos !== writer.getTextPos()) { // If the default binding was emitted, write the separated write(", "); } if (node.importClause.namedBindings.kind === 241 /* 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 !== 234 /* ModuleDeclaration */; var moduleSpecifier; if (parent.kind === 238 /* ImportEqualsDeclaration */) { var node = parent; moduleSpecifier = ts.getExternalModuleImportEqualsDeclarationExpression(node); } else if (parent.kind === 234 /* ModuleDeclaration */) { moduleSpecifier = parent.name; } else { var node = parent; moduleSpecifier = node.moduleSpecifier; } if (moduleSpecifier.kind === 9 /* StringLiteral */ && isBundledEmit && (compilerOptions.out || compilerOptions.outFile)) { var moduleName = ts.getExternalModuleNameFromDeclaration(host, resolver, parent); if (moduleName) { write('"'); write(moduleName); write('"'); return; } } writeTextOfNode(currentText, moduleSpecifier); } function emitImportOrExportSpecifier(node) { if (node.propertyName) { writeTextOfNode(currentText, node.propertyName); write(" as "); } writeTextOfNode(currentText, node.name); } function emitExportSpecifier(node) { emitImportOrExportSpecifier(node); // Make all the declarations visible for the export name var nodes = resolver.collectLinkedAliases(node.propertyName || node.name); // write each of these declarations asynchronously writeAsynchronousModuleElements(nodes); } function emitExportDeclaration(node) { emitJsDocComments(node); write("export "); if (node.exportClause) { write("{ "); emitCommaList(node.exportClause.elements, emitExportSpecifier); write(" }"); } else { write("*"); } if (node.moduleSpecifier) { write(" from "); emitExternalModuleSpecifier(node); } write(";"); writer.writeLine(); } function writeModuleDeclaration(node) { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isGlobalScopeAugmentation(node)) { write("global "); } else { if (node.flags & 16 /* Namespace */) { write("namespace "); } else { write("module "); } if (ts.isExternalModuleAugmentation(node)) { emitExternalModuleSpecifier(node); } else { writeTextOfNode(currentText, node.name); } } while (node.body && node.body.kind !== 235 /* ModuleBlock */) { node = node.body; write("."); writeTextOfNode(currentText, node.name); } var prevEnclosingDeclaration = enclosingDeclaration; if (node.body) { enclosingDeclaration = node; write(" {"); writeLine(); increaseIndent(); emitLines(node.body.statements); decreaseIndent(); write("}"); writeLine(); enclosingDeclaration = prevEnclosingDeclaration; } else { write(";"); } } function writeTypeAliasDeclaration(node) { var prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("type "); writeTextOfNode(currentText, node.name); emitTypeParameters(node.typeParameters); write(" = "); emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError); write(";"); writeLine(); enclosingDeclaration = prevEnclosingDeclaration; function getTypeAliasDeclarationVisibilityError() { return { diagnosticMessage: ts.Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1, errorNode: node.type, typeName: node.name }; } } function writeEnumDeclaration(node) { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isConst(node)) { write("const "); } write("enum "); writeTextOfNode(currentText, node.name); write(" {"); writeLine(); increaseIndent(); emitLines(node.members); decreaseIndent(); write("}"); writeLine(); } function emitEnumMemberDeclaration(node) { emitJsDocComments(node); writeTextOfNode(currentText, node.name); var enumMemberValue = resolver.getConstantValue(node); if (enumMemberValue !== undefined) { write(" = "); write(ts.getTextOfConstantValue(enumMemberValue)); } write(","); writeLine(); } function isPrivateMethodTypeParameter(node) { return node.parent.kind === 152 /* MethodDeclaration */ && ts.hasModifier(node.parent, 8 /* Private */); } function emitTypeParameters(typeParameters) { function emitTypeParameter(node) { increaseIndent(); emitJsDocComments(node); decreaseIndent(); writeTextOfNode(currentText, node.name); // If there is constraint present and this is not a type parameter of the private method emit the constraint if (node.constraint && !isPrivateMethodTypeParameter(node)) { write(" extends "); if (node.parent.kind === 161 /* FunctionType */ || node.parent.kind === 162 /* ConstructorType */ || (node.parent.parent && node.parent.parent.kind === 164 /* TypeLiteral */)) { ts.Debug.assert(node.parent.kind === 152 /* MethodDeclaration */ || node.parent.kind === 151 /* MethodSignature */ || node.parent.kind === 161 /* FunctionType */ || node.parent.kind === 162 /* ConstructorType */ || node.parent.kind === 156 /* CallSignature */ || node.parent.kind === 157 /* ConstructSignature */); emitType(node.constraint); } else { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError); } } if (node.default && !isPrivateMethodTypeParameter(node)) { write(" = "); if (node.parent.kind === 161 /* FunctionType */ || node.parent.kind === 162 /* ConstructorType */ || (node.parent.parent && node.parent.parent.kind === 164 /* TypeLiteral */)) { ts.Debug.assert(node.parent.kind === 152 /* MethodDeclaration */ || node.parent.kind === 151 /* MethodSignature */ || node.parent.kind === 161 /* FunctionType */ || node.parent.kind === 162 /* ConstructorType */ || node.parent.kind === 156 /* CallSignature */ || node.parent.kind === 157 /* ConstructSignature */); emitType(node.default); } else { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError); } } function getTypeParameterConstraintVisibilityError() { // Type parameter constraints are named by user so we should always be able to name it var diagnosticMessage; switch (node.parent.kind) { case 230 /* ClassDeclaration */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_class_has_or_is_using_private_name_1; break; case 231 /* InterfaceDeclaration */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1; break; case 157 /* ConstructSignature */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_constructor_signature_from_exported_interface_has_or_is_using_private_name_1; break; case 156 /* CallSignature */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_call_signature_from_exported_interface_has_or_is_using_private_name_1; break; case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.hasModifier(node.parent, 32 /* Static */)) { diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } else if (node.parent.parent.kind === 230 /* 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 229 /* FunctionDeclaration */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_function_has_or_is_using_private_name_1; break; case 232 /* TypeAliasDeclaration */: diagnosticMessage = ts.Diagnostics.Type_parameter_0_of_exported_type_alias_has_or_is_using_private_name_1; break; default: ts.Debug.fail("This is unknown parent for type parameter: " + node.parent.kind); } return { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: node.name }; } } if (typeParameters) { write("<"); emitCommaList(typeParameters, emitTypeParameter); write(">"); } } function emitHeritageClause(typeReferences, isImplementsList) { if (typeReferences) { write(isImplementsList ? " implements " : " extends "); emitCommaList(typeReferences, emitTypeOfTypeReference); } function emitTypeOfTypeReference(node) { if (ts.isEntityNameExpression(node.expression)) { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node, getHeritageClauseVisibilityError); } else if (!isImplementsList && node.expression.kind === 95 /* NullKeyword */) { write("null"); } function getHeritageClauseVisibilityError() { var diagnosticMessage; // Heritage clause is written by user so it can always be named if (node.parent.parent.kind === 230 /* ClassDeclaration */) { // Class or Interface implemented/extended is inaccessible diagnosticMessage = isImplementsList ? ts.Diagnostics.Implements_clause_of_exported_class_0_has_or_is_using_private_name_1 : ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1; } else { // interface is inaccessible diagnosticMessage = ts.Diagnostics.extends_clause_of_exported_interface_0_has_or_is_using_private_name_1; } return { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: ts.getNameOfDeclaration(node.parent.parent) }; } } } function writeClassDeclaration(node) { function emitParameterProperties(constructorDeclaration) { if (constructorDeclaration) { ts.forEach(constructorDeclaration.parameters, function (param) { if (ts.hasModifier(param, 92 /* ParameterPropertyModifier */)) { emitPropertyDeclaration(param); } }); } } var prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; var baseTypeNode = ts.getClassExtendsHeritageClauseElement(node); var tempVarName; if (baseTypeNode && !ts.isEntityNameExpression(baseTypeNode.expression)) { tempVarName = baseTypeNode.expression.kind === 95 /* NullKeyword */ ? "null" : emitTempVariableDeclaration(baseTypeNode.expression, node.name.escapedText + "_base", { diagnosticMessage: ts.Diagnostics.extends_clause_of_exported_class_0_has_or_is_using_private_name_1, errorNode: baseTypeNode, typeName: node.name }, !ts.findAncestor(node, function (n) { return n.kind === 234 /* ModuleDeclaration */; })); } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.hasModifier(node, 128 /* Abstract */)) { write("abstract "); } write("class "); writeTextOfNode(currentText, node.name); emitTypeParameters(node.typeParameters); if (baseTypeNode) { if (!ts.isEntityNameExpression(baseTypeNode.expression)) { write(" extends "); write(tempVarName); if (baseTypeNode.typeArguments) { write("<"); emitCommaList(baseTypeNode.typeArguments, emitType); write(">"); } } else { emitHeritageClause([baseTypeNode], /*isImplementsList*/ false); } } emitHeritageClause(ts.getClassImplementsHeritageClauseElements(node), /*isImplementsList*/ true); write(" {"); writeLine(); increaseIndent(); emitParameterProperties(ts.getFirstConstructorWithBody(node)); emitLines(node.members); decreaseIndent(); write("}"); writeLine(); enclosingDeclaration = prevEnclosingDeclaration; } function writeInterfaceDeclaration(node) { emitJsDocComments(node); emitModuleElementDeclarationFlags(node); write("interface "); writeTextOfNode(currentText, node.name); var prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; emitTypeParameters(node.typeParameters); var interfaceExtendsTypes = ts.filter(ts.getInterfaceBaseTypeNodes(node), function (base) { return ts.isEntityNameExpression(base.expression); }); if (interfaceExtendsTypes && interfaceExtendsTypes.length) { emitHeritageClause(interfaceExtendsTypes, /*isImplementsList*/ false); } write(" {"); writeLine(); increaseIndent(); emitLines(node.members); decreaseIndent(); write("}"); writeLine(); enclosingDeclaration = prevEnclosingDeclaration; } function emitPropertyDeclaration(node) { if (ts.hasDynamicName(node) && !resolver.isLateBound(node)) { return; } emitJsDocComments(node); emitClassMemberDeclarationFlags(ts.getModifierFlags(node)); emitVariableDeclaration(node); write(";"); writeLine(); } function bindingNameContainsVisibleBindingElement(node) { return !!node && ts.isBindingPattern(node) && ts.some(node.elements, function (elem) { return !ts.isOmittedExpression(elem) && isVariableDeclarationVisible(elem); }); } function isVariableDeclarationVisible(node) { return resolver.isDeclarationVisible(node) || bindingNameContainsVisibleBindingElement(node.name); } 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 !== 227 /* VariableDeclaration */ || isVariableDeclarationVisible(node)) { if (ts.isBindingPattern(node.name)) { emitBindingPattern(node.name); } else { writeNameOfDeclaration(node, getVariableDeclarationTypeVisibilityError); // If optional property emit ? but in the case of parameterProperty declaration with "?" indicating optional parameter for the constructor // we don't want to emit property declaration with "?" if ((node.kind === 150 /* PropertyDeclaration */ || node.kind === 149 /* PropertySignature */ || (node.kind === 147 /* Parameter */ && !ts.isParameterPropertyDeclaration(node))) && ts.hasQuestionToken(node)) { write("?"); } if ((node.kind === 150 /* PropertyDeclaration */ || node.kind === 149 /* PropertySignature */) && node.parent.kind === 164 /* TypeLiteral */) { emitTypeOfVariableDeclarationFromTypeLiteral(node); } else if (resolver.isLiteralConstDeclaration(node)) { write(" = "); resolver.writeLiteralConstValue(node, writer); } else if (!ts.hasModifier(node, 8 /* Private */)) { writeTypeOfDeclaration(node, node.type, getVariableDeclarationTypeVisibilityError); } } } function getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) { if (node.kind === 227 /* 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 === 150 /* PropertyDeclaration */ || node.kind === 149 /* PropertySignature */ || (node.kind === 147 /* Parameter */ && ts.hasModifier(node.parent, 8 /* Private */))) { // TODO(jfreeman): Deal with computed properties in error reporting. if (ts.hasModifier(node, 32 /* Static */)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } else if (node.parent.kind === 230 /* ClassDeclaration */ || node.kind === 147 /* Parameter */) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_property_0_of_exported_class_has_or_is_using_private_name_1; } else { // Interfaces cannot have types that cannot be named return symbolAccessibilityResult.errorModuleName ? ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Property_0_of_exported_interface_has_or_is_using_private_name_1; } } } function getVariableDeclarationTypeVisibilityError(symbolAccessibilityResult) { var diagnosticMessage = getVariableDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: node.name } : undefined; } function emitBindingPattern(bindingPattern) { // Only select visible, 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 !== 201 /* OmittedExpression */ && isVariableDeclarationVisible(element)) { 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 isVariableDeclarationVisible(varDeclaration); }); } function writeVariableStatement(node) { // If binding pattern doesn't have name, then there is nothing to be emitted for declaration file i.e. const [,] = [1,2]. if (ts.every(node.declarationList && node.declarationList.declarations, function (decl) { return decl.name && ts.isEmptyBindingPattern(decl.name); })) { return; } emitJsDocComments(node); emitModuleElementDeclarationFlags(node); if (ts.isLet(node.declarationList)) { write("let "); } else if (ts.isConst(node.declarationList)) { write("const "); } else { write("var "); } emitCommaList(node.declarationList.declarations, emitVariableDeclaration, isVariableDeclarationVisible); write(";"); writeLine(); } function emitAccessorDeclaration(node) { if (ts.hasDynamicName(node) && !resolver.isLateBound(node)) { return; } var accessors = ts.getAllAccessorDeclarations(node.parent.members, node); var accessorWithTypeAnnotation; if (node === accessors.firstAccessor) { emitJsDocComments(accessors.getAccessor); emitJsDocComments(accessors.setAccessor); emitClassMemberDeclarationFlags(ts.getModifierFlags(node) | (accessors.setAccessor ? 0 : 64 /* Readonly */)); writeNameOfDeclaration(node, getAccessorNameVisibilityError); if (!ts.hasModifier(node, 8 /* Private */)) { accessorWithTypeAnnotation = node; var type = getTypeAnnotationFromAccessor(node); if (!type) { // couldn't get type for the first accessor, try the another one var anotherAccessor = node.kind === 154 /* 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 === 154 /* GetAccessor */ ? accessor.type // Getter - return type : accessor.parameters.length > 0 ? accessor.parameters[0].type // Setter parameter type : undefined; } } function getAccessorNameVisibilityError(symbolAccessibilityResult) { var diagnosticMessage = getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: node.name } : undefined; } function getAccessorNameVisibilityDiagnosticMessage(symbolAccessibilityResult) { if (ts.hasModifier(node, 32 /* Static */)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } else if (node.parent.kind === 230 /* 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 { 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 getAccessorDeclarationTypeVisibilityError(symbolAccessibilityResult) { var diagnosticMessage; if (accessorWithTypeAnnotation.kind === 155 /* SetAccessor */) { // Getters can infer the return type from the returned expression, but setters cannot, so the // "_from_external_module_1_but_cannot_be_named" case cannot occur. if (ts.hasModifier(accessorWithTypeAnnotation, 32 /* Static */)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_type_of_public_static_setter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_type_of_public_setter_0_from_exported_class_has_or_is_using_private_name_1; } } else { if (ts.hasModifier(accessorWithTypeAnnotation, 32 /* Static */)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Return_type_of_public_static_getter_0_from_exported_class_has_or_is_using_private_name_1; } else { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Return_type_of_public_getter_0_from_exported_class_has_or_is_using_private_name_1; } } return { diagnosticMessage: diagnosticMessage, errorNode: accessorWithTypeAnnotation.name, typeName: accessorWithTypeAnnotation.name }; } } function writeFunctionDeclaration(node) { if (ts.hasDynamicName(node) && !resolver.isLateBound(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 === 229 /* FunctionDeclaration */) { emitModuleElementDeclarationFlags(node); } else if (node.kind === 152 /* MethodDeclaration */ || node.kind === 153 /* Constructor */) { emitClassMemberDeclarationFlags(ts.getModifierFlags(node)); } if (node.kind === 229 /* FunctionDeclaration */) { write("function "); writeTextOfNode(currentText, node.name); } else if (node.kind === 153 /* Constructor */) { write("constructor"); } else { writeNameOfDeclaration(node, getMethodNameVisibilityError); if (ts.hasQuestionToken(node)) { write("?"); } } emitSignatureDeclaration(node); } function getMethodNameVisibilityError(symbolAccessibilityResult) { var diagnosticMessage = getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: node.name } : undefined; } function getMethodNameVisibilityDiagnosticMessage(symbolAccessibilityResult) { if (ts.hasModifier(node, 32 /* Static */)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_static_method_0_of_exported_class_has_or_is_using_private_name_1; } else if (node.parent.kind === 230 /* ClassDeclaration */) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Public_method_0_of_exported_class_has_or_is_using_private_name_1; } else { return symbolAccessibilityResult.errorModuleName ? ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Method_0_of_exported_interface_has_or_is_using_private_name_1; } } } function writeNameOfDeclaration(node, getSymbolAccessibilityDiagnostic) { if (ts.hasDynamicName(node)) { // If this node has a dynamic name, it can only be an identifier or property access because // we've already skipped it otherwise. ts.Debug.assert(resolver.isLateBound(node)); writeLateBoundNameOfDeclaration(node, getSymbolAccessibilityDiagnostic); } 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); } } function writeLateBoundNameOfDeclaration(node, getSymbolAccessibilityDiagnostic) { writer.getSymbolAccessibilityDiagnostic = getSymbolAccessibilityDiagnostic; var entityName = node.name.expression; var visibilityResult = resolver.isEntityNameVisible(entityName, enclosingDeclaration); handleSymbolAccessibilityError(visibilityResult); recordTypeReferenceDirectivesIfNecessary(resolver.getTypeReferenceDirectivesForEntityName(entityName)); writeTextOfNode(currentText, node.name); } function emitSignatureDeclarationWithJsDocComments(node) { emitJsDocComments(node); emitSignatureDeclaration(node); } function emitSignatureDeclaration(node) { var prevEnclosingDeclaration = enclosingDeclaration; enclosingDeclaration = node; var closeParenthesizedFunctionType = false; if (node.kind === 158 /* IndexSignature */) { // Index signature can have readonly modifier emitClassMemberDeclarationFlags(ts.getModifierFlags(node)); write("["); } else { if (node.kind === 153 /* Constructor */ && ts.hasModifier(node, 8 /* Private */)) { write("();"); writeLine(); return; } // Construct signature or constructor type write new Signature if (node.kind === 157 /* ConstructSignature */ || node.kind === 162 /* ConstructorType */) { write("new "); } else if (node.kind === 161 /* 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< (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 === 158 /* IndexSignature */) { write("]"); } else { write(")"); } // If this is not a constructor and is not private, emit the return type var isFunctionTypeOrConstructorType = node.kind === 161 /* FunctionType */ || node.kind === 162 /* ConstructorType */; if (isFunctionTypeOrConstructorType || node.parent.kind === 164 /* TypeLiteral */) { // Emit type literal signature return type only if specified if (node.type) { write(isFunctionTypeOrConstructorType ? " => " : ": "); emitType(node.type); } } else if (node.kind !== 153 /* Constructor */ && !ts.hasModifier(node, 8 /* Private */)) { writeReturnTypeAtSignature(node, getReturnTypeVisibilityError); } enclosingDeclaration = prevEnclosingDeclaration; if (!isFunctionTypeOrConstructorType) { write(";"); writeLine(); } else if (closeParenthesizedFunctionType) { write(")"); } function getReturnTypeVisibilityError(symbolAccessibilityResult) { var diagnosticMessage; switch (node.kind) { case 157 /* 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 156 /* 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 158 /* 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 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.hasModifier(node, 32 /* Static */)) { diagnosticMessage = symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_external_module_1_but_cannot_be_named : ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_name_0_from_private_module_1 : ts.Diagnostics.Return_type_of_public_static_method_from_exported_class_has_or_is_using_private_name_0; } else if (node.parent.kind === 230 /* 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 229 /* 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 === 161 /* FunctionType */ || node.parent.kind === 162 /* ConstructorType */ || node.parent.parent.kind === 164 /* TypeLiteral */) { emitTypeOfVariableDeclarationFromTypeLiteral(node); } else if (!ts.hasModifier(node.parent, 8 /* Private */)) { writeTypeOfDeclaration(node, node.type, getParameterDeclarationTypeVisibilityError); } function getParameterDeclarationTypeVisibilityError(symbolAccessibilityResult) { var diagnosticMessage = getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult); return diagnosticMessage !== undefined ? { diagnosticMessage: diagnosticMessage, errorNode: node, typeName: node.name } : undefined; } function getParameterDeclarationTypeVisibilityDiagnosticMessage(symbolAccessibilityResult) { switch (node.parent.kind) { case 153 /* 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 157 /* 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 156 /* 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 158 /* IndexSignature */: // Interfaces cannot have parameter types that cannot be named return symbolAccessibilityResult.errorModuleName ? ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_index_signature_from_exported_interface_has_or_is_using_private_name_1; case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.hasModifier(node.parent, 32 /* Static */)) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === 2 /* CannotBeNamed */ ? ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_name_1_from_private_module_2 : ts.Diagnostics.Parameter_0_of_public_static_method_from_exported_class_has_or_is_using_private_name_1; } else if (node.parent.parent.kind === 230 /* 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 229 /* 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 === 175 /* ObjectBindingPattern */) { write("{"); emitCommaList(bindingPattern.elements, emitBindingElement); write("}"); } else if (bindingPattern.kind === 176 /* ArrayBindingPattern */) { write("["); var elements = bindingPattern.elements; emitCommaList(elements, emitBindingElement); if (elements && elements.hasTrailingComma) { write(", "); } write("]"); } } function emitBindingElement(bindingElement) { if (bindingElement.kind === 201 /* 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 === 177 /* BindingElement */) { if (bindingElement.propertyName) { // bindingElement has propertyName property in the following case: // { y: [a,b,c] ...} -> bindingPattern will have a property called propertyName for "y" // We have to explicitly emit the propertyName before descending into its binding elements. // Example: // original: function foo({y: [a,b,c]}) {} // emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void; writeTextOfNode(currentText, bindingElement.propertyName); write(": "); } if (bindingElement.name) { if (ts.isBindingPattern(bindingElement.name)) { // If it is a nested binding pattern, we will recursively descend into each element and emit each one separately. // In the case of rest element, we will omit rest element. // Example: // original: function foo([a, [[b]], c] = [1,[["string"]], 3]) {} // emit : declare function foo([a, [[b]], c]: [number, [[string]], number]): void; // original with rest: function foo([a, ...c]) {} // emit : declare function foo([a, ...c]): void; emitBindingPattern(bindingElement.name); } else { ts.Debug.assert(bindingElement.name.kind === 71 /* Identifier */); // If the node is just an identifier, we will simply emit the text associated with the node's name // Example: // original: function foo({y = 10, x}) {} // emit : declare function foo({y, x}: {number, any}): void; if (bindingElement.dotDotDotToken) { write("..."); } writeTextOfNode(currentText, bindingElement.name); } } } } } function emitNode(node) { switch (node.kind) { case 229 /* FunctionDeclaration */: case 234 /* ModuleDeclaration */: case 238 /* ImportEqualsDeclaration */: case 231 /* InterfaceDeclaration */: case 230 /* ClassDeclaration */: case 232 /* TypeAliasDeclaration */: case 233 /* EnumDeclaration */: return emitModuleElement(node, isModuleElementVisible(node)); case 209 /* VariableStatement */: return emitModuleElement(node, isVariableStatementVisible(node)); case 239 /* ImportDeclaration */: // Import declaration without import clause is visible, otherwise it is not visible return emitModuleElement(node, /*isModuleElementVisible*/ !node.importClause); case 245 /* ExportDeclaration */: return emitExportDeclaration(node); case 153 /* Constructor */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: return writeFunctionDeclaration(node); case 157 /* ConstructSignature */: case 156 /* CallSignature */: case 158 /* IndexSignature */: return emitSignatureDeclarationWithJsDocComments(node); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return emitAccessorDeclaration(node); case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return emitPropertyDeclaration(node); case 268 /* EnumMember */: return emitEnumMemberDeclaration(node); case 244 /* ExportAssignment */: return emitExportAssignment(node); case 269 /* SourceFile */: return emitSourceFile(node); } } /** * Adds the reference to referenced file, returns true if global file reference was emitted * @param referencedFile * @param addBundledFileReference Determines if global file reference corresponding to bundled file should be emitted or not */ function writeReferencePath(referencedFile, addBundledFileReference, emitOnlyDtsFiles) { var declFileName; var addedBundledEmitReference = false; if (referencedFile.isDeclarationFile) { // Declaration file, use declaration file name declFileName = referencedFile.fileName; } else { // Get the declaration file path ts.forEachEmittedFile(host, getDeclFileName, referencedFile, emitOnlyDtsFiles); } if (declFileName) { declFileName = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizeSlashes(declarationFilePath)), declFileName, host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); referencesOutput += "/// " + newLine; } return addedBundledEmitReference; function getDeclFileName(emitFileNames, sourceFileOrBundle) { // Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path var isBundledEmit = sourceFileOrBundle.kind === 270 /* Bundle */; if (isBundledEmit && !addBundledFileReference) { return; } ts.Debug.assert(!!emitFileNames.declarationFilePath || ts.isSourceFileJavaScript(referencedFile), "Declaration file is not present only for javascript files"); declFileName = emitFileNames.declarationFilePath || emitFileNames.jsFilePath; addedBundledEmitReference = isBundledEmit; } } } /* @internal */ function writeDeclarationFile(declarationFilePath, sourceFileOrBundle, host, resolver, emitterDiagnostics, emitOnlyDtsFiles) { var emitDeclarationResult = emitDeclarations(host, resolver, emitterDiagnostics, declarationFilePath, sourceFileOrBundle, emitOnlyDtsFiles); var emitSkipped = emitDeclarationResult.reportedDeclarationError || host.isEmitBlocked(declarationFilePath) || host.getCompilerOptions().noEmit; if (!emitSkipped) { var sourceFiles = sourceFileOrBundle.kind === 270 /* Bundle */ ? sourceFileOrBundle.sourceFiles : [sourceFileOrBundle]; var declarationOutput = emitDeclarationResult.referencesOutput + getDeclarationOutput(emitDeclarationResult.synchronousDeclarationOutput, emitDeclarationResult.moduleElementDeclarationEmitInfo); ts.writeFile(host, emitterDiagnostics, declarationFilePath, declarationOutput, host.getCompilerOptions().emitBOM, sourceFiles); } return emitSkipped; function getDeclarationOutput(synchronousDeclarationOutput, moduleElementDeclarationEmitInfo) { var appliedSyncOutputPos = 0; var declarationOutput = ""; // apply asynchronous additions to the synchronous output ts.forEach(moduleElementDeclarationEmitInfo, function (aliasEmitInfo) { if (aliasEmitInfo.asynchronousOutput) { declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos, aliasEmitInfo.outputPos); declarationOutput += getDeclarationOutput(aliasEmitInfo.asynchronousOutput, aliasEmitInfo.subModuleElementDeclarationEmitInfo); appliedSyncOutputPos = aliasEmitInfo.outputPos; } }); declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos); return declarationOutput; } } ts.writeDeclarationFile = writeDeclarationFile; })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { // Used for initialize lastEncodedSourceMapSpan and reset lastEncodedSourceMapSpan when updateLastEncodedAndRecordedSpans var defaultLastEncodedSourceMapSpan = { emittedLine: 1, emittedColumn: 1, sourceLine: 1, sourceColumn: 1, sourceIndex: 0 }; function createSourceMapWriter(host, writer) { var compilerOptions = host.getCompilerOptions(); var extendedDiagnostics = compilerOptions.extendedDiagnostics; var currentSource; var currentSourceText; var sourceMapDir; // The directory in which sourcemap will be // Current source map file and its index in the sources list var sourceMapSourceIndex; // Last recorded and encoded spans var lastRecordedSourceMapSpan; var lastEncodedSourceMapSpan; var lastEncodedNameIndex; // Source map data var sourceMapData; var disabled = !(compilerOptions.sourceMap || compilerOptions.inlineSourceMap); return { initialize: initialize, reset: reset, getSourceMapData: function () { return sourceMapData; }, setSourceFile: setSourceFile, emitPos: emitPos, emitNodeWithSourceMap: emitNodeWithSourceMap, emitTokenWithSourceMap: emitTokenWithSourceMap, getText: getText, getSourceMappingURL: getSourceMappingURL, }; /** * Skips trivia such as comments and white-space that can optionally overriden by the source map source */ function skipSourceTrivia(pos) { return currentSource.skipTrivia ? currentSource.skipTrivia(pos) : ts.skipTrivia(currentSourceText, pos); } /** * Initialize the SourceMapWriter for a new output file. * * @param filePath The path to the generated output file. * @param sourceMapFilePath The path to the output source map file. * @param sourceFileOrBundle The input source file or bundle for the program. */ function initialize(filePath, sourceMapFilePath, sourceFileOrBundle) { if (disabled) { return; } if (sourceMapData) { reset(); } currentSource = undefined; currentSourceText = undefined; // Current source map file and its index in the sources list sourceMapSourceIndex = -1; // Last recorded and encoded spans lastRecordedSourceMapSpan = undefined; lastEncodedSourceMapSpan = defaultLastEncodedSourceMapSpan; lastEncodedNameIndex = 0; // Initialize source map data sourceMapData = { sourceMapFilePath: sourceMapFilePath, jsSourceMappingURL: !compilerOptions.inlineSourceMap ? ts.getBaseFileName(ts.normalizeSlashes(sourceMapFilePath)) : undefined, sourceMapFile: ts.getBaseFileName(ts.normalizeSlashes(filePath)), sourceMapSourceRoot: compilerOptions.sourceRoot || "", sourceMapSources: [], inputSourceFileNames: [], sourceMapNames: [], sourceMapMappings: "", sourceMapSourcesContent: compilerOptions.inlineSources ? [] : undefined, sourceMapDecodedMappings: [] }; // Normalize source root and make sure it has trailing "/" so that it can be used to combine paths with the // relative paths of the sources list in the sourcemap sourceMapData.sourceMapSourceRoot = ts.normalizeSlashes(sourceMapData.sourceMapSourceRoot); if (sourceMapData.sourceMapSourceRoot.length && sourceMapData.sourceMapSourceRoot.charCodeAt(sourceMapData.sourceMapSourceRoot.length - 1) !== 47 /* slash */) { sourceMapData.sourceMapSourceRoot += ts.directorySeparator; } if (compilerOptions.mapRoot) { sourceMapDir = ts.normalizeSlashes(compilerOptions.mapRoot); if (sourceFileOrBundle.kind === 269 /* SourceFile */) { // For modules or multiple emit files the mapRoot will have directory structure like the sources // So if src\a.ts and src\lib\b.ts are compiled together user would be moving the maps into mapRoot\a.js.map and mapRoot\lib\b.js.map sourceMapDir = ts.getDirectoryPath(ts.getSourceFilePathInNewDir(sourceFileOrBundle, host, sourceMapDir)); } if (!ts.isRootedDiskPath(sourceMapDir) && !ts.isUrl(sourceMapDir)) { // The relative paths are relative to the common directory sourceMapDir = ts.combinePaths(host.getCommonSourceDirectory(), sourceMapDir); sourceMapData.jsSourceMappingURL = ts.getRelativePathToDirectoryOrUrl(ts.getDirectoryPath(ts.normalizePath(filePath)), // get the relative sourceMapDir path based on jsFilePath ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL), // this is where user expects to see sourceMap host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); } else { sourceMapData.jsSourceMappingURL = ts.combinePaths(sourceMapDir, sourceMapData.jsSourceMappingURL); } } else { sourceMapDir = ts.getDirectoryPath(ts.normalizePath(filePath)); } } /** * Reset the SourceMapWriter to an empty state. */ function reset() { if (disabled) { return; } currentSource = undefined; sourceMapDir = undefined; sourceMapSourceIndex = undefined; lastRecordedSourceMapSpan = undefined; lastEncodedSourceMapSpan = undefined; lastEncodedNameIndex = undefined; sourceMapData = undefined; } // Encoding for sourcemap span function encodeLastRecordedSourceMapSpan() { if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan === lastEncodedSourceMapSpan) { return; } var prevEncodedEmittedColumn = lastEncodedSourceMapSpan.emittedColumn; // Line/Comma delimiters if (lastEncodedSourceMapSpan.emittedLine === lastRecordedSourceMapSpan.emittedLine) { // Emit comma to separate the entry if (sourceMapData.sourceMapMappings) { sourceMapData.sourceMapMappings += ","; } } else { // Emit line delimiters for (var encodedLine = lastEncodedSourceMapSpan.emittedLine; encodedLine < lastRecordedSourceMapSpan.emittedLine; encodedLine++) { sourceMapData.sourceMapMappings += ";"; } prevEncodedEmittedColumn = 1; } // 1. Relative Column 0 based sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.emittedColumn - prevEncodedEmittedColumn); // 2. Relative sourceIndex sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceIndex - lastEncodedSourceMapSpan.sourceIndex); // 3. Relative sourceLine 0 based sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceLine - lastEncodedSourceMapSpan.sourceLine); // 4. Relative sourceColumn 0 based sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.sourceColumn - lastEncodedSourceMapSpan.sourceColumn); // 5. Relative namePosition 0 based if (lastRecordedSourceMapSpan.nameIndex >= 0) { ts.Debug.assert(false, "We do not support name index right now, Make sure to update updateLastEncodedAndRecordedSpans when we start using this"); sourceMapData.sourceMapMappings += base64VLQFormatEncode(lastRecordedSourceMapSpan.nameIndex - lastEncodedNameIndex); lastEncodedNameIndex = lastRecordedSourceMapSpan.nameIndex; } lastEncodedSourceMapSpan = lastRecordedSourceMapSpan; sourceMapData.sourceMapDecodedMappings.push(lastEncodedSourceMapSpan); } /** * Emits a mapping. * * If the position is synthetic (undefined or a negative value), no mapping will be * created. * * @param pos The position. */ function emitPos(pos) { if (disabled || ts.positionIsSynthesized(pos)) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeSourcemap"); } var sourceLinePos = ts.getLineAndCharacterOfPosition(currentSource, pos); // Convert the location to be one-based. sourceLinePos.line++; sourceLinePos.character++; var emittedLine = writer.getLine(); var emittedColumn = writer.getColumn(); // If this location wasn't recorded or the location in source is going backwards, record the span if (!lastRecordedSourceMapSpan || lastRecordedSourceMapSpan.emittedLine !== emittedLine || lastRecordedSourceMapSpan.emittedColumn !== emittedColumn || (lastRecordedSourceMapSpan.sourceIndex === sourceMapSourceIndex && (lastRecordedSourceMapSpan.sourceLine > sourceLinePos.line || (lastRecordedSourceMapSpan.sourceLine === sourceLinePos.line && lastRecordedSourceMapSpan.sourceColumn > sourceLinePos.character)))) { // Encode the last recordedSpan before assigning new encodeLastRecordedSourceMapSpan(); // New span lastRecordedSourceMapSpan = { emittedLine: emittedLine, emittedColumn: emittedColumn, sourceLine: sourceLinePos.line, sourceColumn: sourceLinePos.character, sourceIndex: sourceMapSourceIndex }; } else { // Take the new pos instead since there is no change in emittedLine and column since last location lastRecordedSourceMapSpan.sourceLine = sourceLinePos.line; lastRecordedSourceMapSpan.sourceColumn = sourceLinePos.character; lastRecordedSourceMapSpan.sourceIndex = sourceMapSourceIndex; } if (extendedDiagnostics) { ts.performance.mark("afterSourcemap"); ts.performance.measure("Source Map", "beforeSourcemap", "afterSourcemap"); } } /** * Emits a node with possible leading and trailing source maps. * * @param hint A hint as to the intended usage of the node. * @param node The node to emit. * @param emitCallback The callback used to emit the node. */ function emitNodeWithSourceMap(hint, node, emitCallback) { if (disabled) { return emitCallback(hint, node); } if (node) { var emitNode = node.emitNode; var emitFlags = emitNode && emitNode.flags; var range = emitNode && emitNode.sourceMapRange; var _a = range || node, pos = _a.pos, end = _a.end; var source = range && range.source; var oldSource = currentSource; if (source === oldSource) source = undefined; if (source) setSourceFile(source); if (node.kind !== 291 /* NotEmittedStatement */ && (emitFlags & 16 /* NoLeadingSourceMap */) === 0 && pos >= 0) { emitPos(skipSourceTrivia(pos)); } if (source) setSourceFile(oldSource); if (emitFlags & 64 /* NoNestedSourceMaps */) { disabled = true; emitCallback(hint, node); disabled = false; } else { emitCallback(hint, node); } if (source) setSourceFile(source); if (node.kind !== 291 /* NotEmittedStatement */ && (emitFlags & 32 /* NoTrailingSourceMap */) === 0 && end >= 0) { emitPos(end); } if (source) setSourceFile(oldSource); } } /** * Emits a token of a node with possible leading and trailing source maps. * * @param node The node containing the token. * @param token The token to emit. * @param tokenStartPos The start pos of the token. * @param emitCallback The callback used to emit the token. */ function emitTokenWithSourceMap(node, token, tokenPos, emitCallback) { if (disabled) { return emitCallback(token, tokenPos); } var emitNode = node && node.emitNode; var emitFlags = emitNode && emitNode.flags; var range = emitNode && emitNode.tokenSourceMapRanges && emitNode.tokenSourceMapRanges[token]; tokenPos = skipSourceTrivia(range ? range.pos : tokenPos); if ((emitFlags & 128 /* NoTokenLeadingSourceMaps */) === 0 && tokenPos >= 0) { emitPos(tokenPos); } tokenPos = emitCallback(token, tokenPos); if (range) tokenPos = range.end; if ((emitFlags & 256 /* NoTokenTrailingSourceMaps */) === 0 && tokenPos >= 0) { emitPos(tokenPos); } return tokenPos; } /** * Set the current source file. * * @param sourceFile The source file. */ function setSourceFile(sourceFile) { if (disabled) { return; } currentSource = sourceFile; currentSourceText = currentSource.text; // Add the file to tsFilePaths // If sourceroot option: Use the relative path corresponding to the common directory path // otherwise source locations relative to map file location var sourcesDirectoryPath = compilerOptions.sourceRoot ? host.getCommonSourceDirectory() : sourceMapDir; var source = ts.getRelativePathToDirectoryOrUrl(sourcesDirectoryPath, currentSource.fileName, host.getCurrentDirectory(), host.getCanonicalFileName, /*isAbsolutePathAnUrl*/ true); sourceMapSourceIndex = ts.indexOf(sourceMapData.sourceMapSources, source); if (sourceMapSourceIndex === -1) { sourceMapSourceIndex = sourceMapData.sourceMapSources.length; sourceMapData.sourceMapSources.push(source); // The one that can be used from program to get the actual source file sourceMapData.inputSourceFileNames.push(currentSource.fileName); if (compilerOptions.inlineSources) { sourceMapData.sourceMapSourcesContent.push(currentSource.text); } } } /** * Gets the text for the source map. */ function getText() { if (disabled) { return; } encodeLastRecordedSourceMapSpan(); return JSON.stringify({ version: 3, file: sourceMapData.sourceMapFile, sourceRoot: sourceMapData.sourceMapSourceRoot, sources: sourceMapData.sourceMapSources, names: sourceMapData.sourceMapNames, mappings: sourceMapData.sourceMapMappings, sourcesContent: sourceMapData.sourceMapSourcesContent, }); } /** * Gets the SourceMappingURL for the source map. */ function getSourceMappingURL() { if (disabled) { return; } if (compilerOptions.inlineSourceMap) { // Encode the sourceMap into the sourceMap url var base64SourceMapText = ts.convertToBase64(getText()); return sourceMapData.jsSourceMappingURL = "data:application/json;base64," + base64SourceMapText; } else { return sourceMapData.jsSourceMappingURL; } } } ts.createSourceMapWriter = createSourceMapWriter; var base64Chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; function base64FormatEncode(inValue) { if (inValue < 64) { return base64Chars.charAt(inValue); } throw TypeError(inValue + ": not a 64 based value"); } function base64VLQFormatEncode(inValue) { // Add a new least significant bit that has the sign of the value. // if negative number the least significant bit that gets added to the number has value 1 // else least significant bit value that gets added is 0 // eg. -1 changes to binary : 01 [1] => 3 // +1 changes to binary : 01 [0] => 2 if (inValue < 0) { inValue = ((-inValue) << 1) + 1; } else { inValue = inValue << 1; } // Encode 5 bits at a time starting from least significant bits var encodedStr = ""; do { var currentDigit = inValue & 31; // 11111 inValue = inValue >> 5; if (inValue > 0) { // There are still more digits to decode, set the msb (6th bit) currentDigit = currentDigit | 32; } encodedStr = encodedStr + base64FormatEncode(currentDigit); } while (inValue > 0); return encodedStr; } })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { function createCommentWriter(printerOptions, emitPos) { var extendedDiagnostics = printerOptions.extendedDiagnostics; var newLine = ts.getNewLineCharacter(printerOptions); var writer; var containerPos = -1; var containerEnd = -1; var declarationListContainerEnd = -1; var currentSourceFile; var currentText; var currentLineMap; var detachedCommentsInfo; var hasWrittenComment = false; var disabled = printerOptions.removeComments; return { reset: reset, setWriter: setWriter, setSourceFile: setSourceFile, emitNodeWithComments: emitNodeWithComments, emitBodyWithDetachedComments: emitBodyWithDetachedComments, emitTrailingCommentsOfPosition: emitTrailingCommentsOfPosition, emitLeadingCommentsOfPosition: emitLeadingCommentsOfPosition, }; function emitNodeWithComments(hint, node, emitCallback) { if (disabled) { emitCallback(hint, node); return; } if (node) { hasWrittenComment = false; var emitNode = node.emitNode; var emitFlags = emitNode && emitNode.flags; var _a = emitNode && emitNode.commentRange || node, pos = _a.pos, end = _a.end; if ((pos < 0 && end < 0) || (pos === end)) { // Both pos and end are synthesized, so just emit the node without comments. emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback); } else { if (extendedDiagnostics) { ts.performance.mark("preEmitNodeWithComment"); } var isEmittedNode = node.kind !== 291 /* NotEmittedStatement */; // We have to explicitly check that the node is JsxText because if the compilerOptions.jsx is "preserve" we will not do any transformation. // It is expensive to walk entire tree just to set one kind of node to have no comments. var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0 || node.kind === 10 /* JsxText */; var skipTrailingComments = end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0 || node.kind === 10 /* JsxText */; // Emit leading comments if the position is not synthesized and the node // has not opted out from emitting leading comments. if (!skipLeadingComments) { emitLeadingComments(pos, isEmittedNode); } // Save current container state on the stack. var savedContainerPos = containerPos; var savedContainerEnd = containerEnd; var savedDeclarationListContainerEnd = declarationListContainerEnd; if (!skipLeadingComments) { containerPos = pos; } if (!skipTrailingComments) { containerEnd = end; // To avoid invalid comment emit in a down-level binding pattern, we // keep track of the last declaration list container's end if (node.kind === 228 /* VariableDeclarationList */) { declarationListContainerEnd = end; } } if (extendedDiagnostics) { ts.performance.measure("commentTime", "preEmitNodeWithComment"); } emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback); if (extendedDiagnostics) { ts.performance.mark("postEmitNodeWithComment"); } // Restore previous container state. containerPos = savedContainerPos; containerEnd = savedContainerEnd; declarationListContainerEnd = savedDeclarationListContainerEnd; // Emit trailing comments if the position is not synthesized and the node // has not opted out from emitting leading comments and is an emitted node. if (!skipTrailingComments && isEmittedNode) { emitTrailingComments(end); } if (extendedDiagnostics) { ts.performance.measure("commentTime", "postEmitNodeWithComment"); } } } } function emitNodeWithSynthesizedComments(hint, node, emitNode, emitFlags, emitCallback) { var leadingComments = emitNode && emitNode.leadingComments; if (ts.some(leadingComments)) { if (extendedDiagnostics) { ts.performance.mark("preEmitNodeWithSynthesizedComments"); } ts.forEach(leadingComments, emitLeadingSynthesizedComment); if (extendedDiagnostics) { ts.performance.measure("commentTime", "preEmitNodeWithSynthesizedComments"); } } emitNodeWithNestedComments(hint, node, emitFlags, emitCallback); var trailingComments = emitNode && emitNode.trailingComments; if (ts.some(trailingComments)) { if (extendedDiagnostics) { ts.performance.mark("postEmitNodeWithSynthesizedComments"); } ts.forEach(trailingComments, emitTrailingSynthesizedComment); if (extendedDiagnostics) { ts.performance.measure("commentTime", "postEmitNodeWithSynthesizedComments"); } } } function emitLeadingSynthesizedComment(comment) { if (comment.kind === 2 /* SingleLineCommentTrivia */) { writer.writeLine(); } writeSynthesizedComment(comment); if (comment.hasTrailingNewLine || comment.kind === 2 /* SingleLineCommentTrivia */) { writer.writeLine(); } else { writer.write(" "); } } function emitTrailingSynthesizedComment(comment) { if (!writer.isAtStartOfLine()) { writer.write(" "); } writeSynthesizedComment(comment); if (comment.hasTrailingNewLine) { writer.writeLine(); } } function writeSynthesizedComment(comment) { var text = formatSynthesizedComment(comment); var lineMap = comment.kind === 3 /* MultiLineCommentTrivia */ ? ts.computeLineStarts(text) : undefined; ts.writeCommentRange(text, lineMap, writer, 0, text.length, newLine); } function formatSynthesizedComment(comment) { return comment.kind === 3 /* MultiLineCommentTrivia */ ? "/*" + comment.text + "*/" : "//" + comment.text; } function emitNodeWithNestedComments(hint, node, emitFlags, emitCallback) { if (emitFlags & 2048 /* NoNestedComments */) { disabled = true; emitCallback(hint, node); disabled = false; } else { emitCallback(hint, node); } } function emitBodyWithDetachedComments(node, detachedRange, emitCallback) { if (extendedDiagnostics) { ts.performance.mark("preEmitBodyWithDetachedComments"); } var pos = detachedRange.pos, end = detachedRange.end; var emitFlags = ts.getEmitFlags(node); var skipLeadingComments = pos < 0 || (emitFlags & 512 /* NoLeadingComments */) !== 0; var skipTrailingComments = disabled || end < 0 || (emitFlags & 1024 /* NoTrailingComments */) !== 0; if (!skipLeadingComments) { emitDetachedCommentsAndUpdateCommentsInfo(detachedRange); } if (extendedDiagnostics) { ts.performance.measure("commentTime", "preEmitBodyWithDetachedComments"); } if (emitFlags & 2048 /* NoNestedComments */ && !disabled) { disabled = true; emitCallback(node); disabled = false; } else { emitCallback(node); } if (extendedDiagnostics) { ts.performance.mark("beginEmitBodyWithDetachedCommetns"); } if (!skipTrailingComments) { emitLeadingComments(detachedRange.end, /*isEmittedNode*/ true); if (hasWrittenComment && !writer.isAtStartOfLine()) { writer.writeLine(); } } if (extendedDiagnostics) { ts.performance.measure("commentTime", "beginEmitBodyWithDetachedCommetns"); } } function emitLeadingComments(pos, isEmittedNode) { hasWrittenComment = false; if (isEmittedNode) { forEachLeadingCommentToEmit(pos, emitLeadingComment); } else if (pos === 0) { // If the node will not be emitted in JS, remove all the comments(normal, pinned and ///) associated with the node, // unless it is a triple slash comment at the top of the file. // For Example: // /// // declare var x; // /// // interface F {} // The first /// will NOT be removed while the second one will be removed even though both node will not be emitted forEachLeadingCommentToEmit(pos, emitTripleSlashLeadingComment); } } function emitTripleSlashLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) { if (isTripleSlashComment(commentPos, commentEnd)) { emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos); } } function emitLeadingComment(commentPos, commentEnd, kind, hasTrailingNewLine, rangePos) { if (!hasWrittenComment) { ts.emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos); hasWrittenComment = true; } // Leading comments are emitted at /*leading comment1 */space/*leading comment*/space if (emitPos) emitPos(commentPos); ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); } else if (kind === 3 /* MultiLineCommentTrivia */) { writer.write(" "); } } function emitLeadingCommentsOfPosition(pos) { if (disabled || pos === -1) { return; } emitLeadingComments(pos, /*isEmittedNode*/ true); } function emitTrailingComments(pos) { forEachTrailingCommentToEmit(pos, emitTrailingComment); } function emitTrailingComment(commentPos, commentEnd, _kind, hasTrailingNewLine) { // trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/ if (!writer.isAtStartOfLine()) { writer.write(" "); } if (emitPos) emitPos(commentPos); ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); } } function emitTrailingCommentsOfPosition(pos, prefixSpace) { if (disabled) { return; } if (extendedDiagnostics) { ts.performance.mark("beforeEmitTrailingCommentsOfPosition"); } forEachTrailingCommentToEmit(pos, prefixSpace ? emitTrailingComment : emitTrailingCommentOfPosition); if (extendedDiagnostics) { ts.performance.measure("commentTime", "beforeEmitTrailingCommentsOfPosition"); } } function emitTrailingCommentOfPosition(commentPos, commentEnd, _kind, hasTrailingNewLine) { // trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space if (emitPos) emitPos(commentPos); ts.writeCommentRange(currentText, currentLineMap, writer, commentPos, commentEnd, newLine); if (emitPos) emitPos(commentEnd); if (hasTrailingNewLine) { writer.writeLine(); } else { writer.write(" "); } } function forEachLeadingCommentToEmit(pos, cb) { // Emit the leading comments only if the container's pos doesn't match because the container should take care of emitting these comments if (containerPos === -1 || pos !== containerPos) { if (hasDetachedComments(pos)) { forEachLeadingCommentWithoutDetachedComments(cb); } else { ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos); } } } function forEachTrailingCommentToEmit(end, cb) { // Emit the trailing comments only if the container's end doesn't match because the container should take care of emitting these comments if (containerEnd === -1 || (end !== containerEnd && end !== declarationListContainerEnd)) { ts.forEachTrailingCommentRange(currentText, end, cb); } } function reset() { currentSourceFile = undefined; currentText = undefined; currentLineMap = undefined; detachedCommentsInfo = undefined; } function setWriter(output) { writer = output; } function setSourceFile(sourceFile) { currentSourceFile = sourceFile; currentText = currentSourceFile.text; currentLineMap = ts.getLineStarts(currentSourceFile); detachedCommentsInfo = undefined; } function hasDetachedComments(pos) { return detachedCommentsInfo !== undefined && ts.lastOrUndefined(detachedCommentsInfo).nodePos === pos; } function forEachLeadingCommentWithoutDetachedComments(cb) { // get the leading comments from detachedPos var pos = ts.lastOrUndefined(detachedCommentsInfo).detachedCommentEndPos; if (detachedCommentsInfo.length - 1) { detachedCommentsInfo.pop(); } else { detachedCommentsInfo = undefined; } ts.forEachLeadingCommentRange(currentText, pos, cb, /*state*/ pos); } function emitDetachedCommentsAndUpdateCommentsInfo(range) { var currentDetachedCommentInfo = ts.emitDetachedComments(currentText, currentLineMap, writer, writeComment, range, newLine, disabled); if (currentDetachedCommentInfo) { if (detachedCommentsInfo) { detachedCommentsInfo.push(currentDetachedCommentInfo); } else { detachedCommentsInfo = [currentDetachedCommentInfo]; } } } function writeComment(text, lineMap, writer, commentPos, commentEnd, newLine) { if (emitPos) emitPos(commentPos); ts.writeCommentRange(text, lineMap, writer, commentPos, commentEnd, newLine); if (emitPos) emitPos(commentEnd); } /** * Determine if the given comment is a triple-slash * * @return true if the comment is a triple-slash comment else false */ function isTripleSlashComment(commentPos, commentEnd) { return ts.isRecognizedTripleSlashComment(currentText, commentPos, commentEnd); } } ts.createCommentWriter = createCommentWriter; })(ts || (ts = {})); /// /// /// /// /// var ts; (function (ts) { var delimiters = createDelimiterMap(); var brackets = createBracketsMap(); /*@internal*/ /** * Iterates over the source files that are expected to have an emit output. * * @param host An EmitHost. * @param action The action to execute. * @param sourceFilesOrTargetSourceFile * If an array, the full list of source files to emit. * Else, calls `getSourceFilesToEmit` with the (optional) target source file to determine the list of source files to emit. */ function forEachEmittedFile(host, action, sourceFilesOrTargetSourceFile, emitOnlyDtsFiles) { var sourceFiles = ts.isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : ts.getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile); var options = host.getCompilerOptions(); if (options.outFile || options.out) { if (sourceFiles.length) { var jsFilePath = options.outFile || options.out; var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); var declarationFilePath = options.declaration ? ts.removeFileExtension(jsFilePath) + ".d.ts" /* Dts */ : ""; action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, ts.createBundle(sourceFiles), emitOnlyDtsFiles); } } else { for (var _a = 0, sourceFiles_1 = sourceFiles; _a < sourceFiles_1.length; _a++) { var sourceFile = sourceFiles_1[_a]; var jsFilePath = ts.getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options)); var sourceMapFilePath = getSourceMapFilePath(jsFilePath, options); var declarationFilePath = !ts.isSourceFileJavaScript(sourceFile) && (emitOnlyDtsFiles || options.declaration) ? ts.getDeclarationEmitOutputFilePath(sourceFile, host) : undefined; action({ jsFilePath: jsFilePath, sourceMapFilePath: sourceMapFilePath, declarationFilePath: declarationFilePath }, sourceFile, emitOnlyDtsFiles); } } } ts.forEachEmittedFile = forEachEmittedFile; function getSourceMapFilePath(jsFilePath, options) { return options.sourceMap ? jsFilePath + ".map" : undefined; } // JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also. // So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve. // For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve function getOutputExtension(sourceFile, options) { if (options.jsx === 1 /* Preserve */) { if (ts.isSourceFileJavaScript(sourceFile)) { if (ts.fileExtensionIs(sourceFile.fileName, ".jsx" /* Jsx */)) { return ".jsx" /* Jsx */; } } else if (sourceFile.languageVariant === 1 /* JSX */) { // TypeScript source file preserving JSX syntax return ".jsx" /* Jsx */; } } return ".js" /* Js */; } function getOriginalSourceFileOrBundle(sourceFileOrBundle) { if (sourceFileOrBundle.kind === 270 /* Bundle */) { return ts.updateBundle(sourceFileOrBundle, ts.sameMap(sourceFileOrBundle.sourceFiles, ts.getOriginalSourceFile)); } return ts.getOriginalSourceFile(sourceFileOrBundle); } /*@internal*/ // targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature function emitFiles(resolver, host, targetSourceFile, emitOnlyDtsFiles, transformers) { var compilerOptions = host.getCompilerOptions(); var moduleKind = ts.getEmitModuleKind(compilerOptions); var sourceMapDataList = compilerOptions.sourceMap || compilerOptions.inlineSourceMap ? [] : undefined; var emittedFilesList = compilerOptions.listEmittedFiles ? [] : undefined; var emitterDiagnostics = ts.createDiagnosticCollection(); var newLine = host.getNewLine(); var writer = ts.createTextWriter(newLine); var sourceMap = ts.createSourceMapWriter(host, writer); var currentSourceFile; var bundledHelpers; var isOwnFileEmit; var emitSkipped = false; var sourceFiles = ts.getSourceFilesToEmit(host, targetSourceFile); // Transform the source files var transform = ts.transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false); // Create a printer to print the nodes var printer = createPrinter(compilerOptions, { // resolver hooks hasGlobalName: resolver.hasGlobalName, // transform hooks onEmitNode: transform.emitNodeWithNotification, substituteNode: transform.substituteNode, // sourcemap hooks onEmitSourceMapOfNode: sourceMap.emitNodeWithSourceMap, onEmitSourceMapOfToken: sourceMap.emitTokenWithSourceMap, onEmitSourceMapOfPosition: sourceMap.emitPos, // emitter hooks onEmitHelpers: emitHelpers, onSetSourceFile: setSourceFile, }); // Emit each output file ts.performance.mark("beforePrint"); forEachEmittedFile(host, emitSourceFileOrBundle, transform.transformed, emitOnlyDtsFiles); ts.performance.measure("printTime", "beforePrint"); // Clean up emit nodes on parse tree transform.dispose(); return { emitSkipped: emitSkipped, diagnostics: emitterDiagnostics.getDiagnostics(), emittedFiles: emittedFilesList, sourceMaps: sourceMapDataList }; function emitSourceFileOrBundle(_a, sourceFileOrBundle) { var jsFilePath = _a.jsFilePath, sourceMapFilePath = _a.sourceMapFilePath, declarationFilePath = _a.declarationFilePath; // Make sure not to write js file and source map file if any of them cannot be written if (!host.isEmitBlocked(jsFilePath) && !compilerOptions.noEmit) { if (!emitOnlyDtsFiles) { printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle); } } else { emitSkipped = true; } if (declarationFilePath) { emitSkipped = ts.writeDeclarationFile(declarationFilePath, getOriginalSourceFileOrBundle(sourceFileOrBundle), host, resolver, emitterDiagnostics, emitOnlyDtsFiles) || emitSkipped; } if (!emitSkipped && emittedFilesList) { if (!emitOnlyDtsFiles) { emittedFilesList.push(jsFilePath); } if (sourceMapFilePath) { emittedFilesList.push(sourceMapFilePath); } if (declarationFilePath) { emittedFilesList.push(declarationFilePath); } } } function printSourceFileOrBundle(jsFilePath, sourceMapFilePath, sourceFileOrBundle) { var bundle = sourceFileOrBundle.kind === 270 /* Bundle */ ? sourceFileOrBundle : undefined; var sourceFile = sourceFileOrBundle.kind === 269 /* SourceFile */ ? sourceFileOrBundle : undefined; var sourceFiles = bundle ? bundle.sourceFiles : [sourceFile]; sourceMap.initialize(jsFilePath, sourceMapFilePath, sourceFileOrBundle); if (bundle) { bundledHelpers = ts.createMap(); isOwnFileEmit = false; printer.writeBundle(bundle, writer); } else { isOwnFileEmit = true; printer.writeFile(sourceFile, writer); } writer.writeLine(); var sourceMappingURL = sourceMap.getSourceMappingURL(); if (sourceMappingURL) { writer.write("//# " + "sourceMappingURL" + "=" + sourceMappingURL); // Sometimes tools can sometimes see this line as a source mapping url comment } // Write the source map if (compilerOptions.sourceMap && !compilerOptions.inlineSourceMap) { ts.writeFile(host, emitterDiagnostics, sourceMapFilePath, sourceMap.getText(), /*writeByteOrderMark*/ false, sourceFiles); } // Record source map data for the test harness. if (sourceMapDataList) { sourceMapDataList.push(sourceMap.getSourceMapData()); } // Write the output file ts.writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles); // Reset state sourceMap.reset(); writer.reset(); currentSourceFile = undefined; bundledHelpers = undefined; isOwnFileEmit = false; } function setSourceFile(node) { currentSourceFile = node; sourceMap.setSourceFile(node); } function emitHelpers(node, writeLines) { var helpersEmitted = false; var bundle = node.kind === 270 /* Bundle */ ? node : undefined; if (bundle && moduleKind === ts.ModuleKind.None) { return; } var numNodes = bundle ? bundle.sourceFiles.length : 1; for (var i = 0; i < numNodes; i++) { var currentNode = bundle ? bundle.sourceFiles[i] : node; var sourceFile = ts.isSourceFile(currentNode) ? currentNode : currentSourceFile; var shouldSkip = compilerOptions.noEmitHelpers || ts.getExternalHelpersModuleName(sourceFile) !== undefined; var shouldBundle = ts.isSourceFile(currentNode) && !isOwnFileEmit; var helpers = ts.getEmitHelpers(currentNode); if (helpers) { for (var _a = 0, _b = ts.stableSort(helpers, ts.compareEmitHelpers); _a < _b.length; _a++) { var helper = _b[_a]; if (!helper.scoped) { // Skip the helper if it can be skipped and the noEmitHelpers compiler // option is set, or if it can be imported and the importHelpers compiler // option is set. if (shouldSkip) continue; // Skip the helper if it can be bundled but hasn't already been emitted and we // are emitting a bundled module. if (shouldBundle) { if (bundledHelpers.get(helper.name)) { continue; } bundledHelpers.set(helper.name, true); } } else if (bundle) { // Skip the helper if it is scoped and we are emitting bundled helpers continue; } writeLines(helper.text); helpersEmitted = true; } } } return helpersEmitted; } } ts.emitFiles = emitFiles; function createPrinter(printerOptions, handlers) { if (printerOptions === void 0) { printerOptions = {}; } if (handlers === void 0) { handlers = {}; } var hasGlobalName = handlers.hasGlobalName, onEmitSourceMapOfNode = handlers.onEmitSourceMapOfNode, onEmitSourceMapOfToken = handlers.onEmitSourceMapOfToken, onEmitSourceMapOfPosition = handlers.onEmitSourceMapOfPosition, onEmitNode = handlers.onEmitNode, onEmitHelpers = handlers.onEmitHelpers, onSetSourceFile = handlers.onSetSourceFile, substituteNode = handlers.substituteNode, onBeforeEmitNodeArray = handlers.onBeforeEmitNodeArray, onAfterEmitNodeArray = handlers.onAfterEmitNodeArray, onBeforeEmitToken = handlers.onBeforeEmitToken, onAfterEmitToken = handlers.onAfterEmitToken; var newLine = ts.getNewLineCharacter(printerOptions); var comments = ts.createCommentWriter(printerOptions, onEmitSourceMapOfPosition); var emitNodeWithComments = comments.emitNodeWithComments, emitBodyWithDetachedComments = comments.emitBodyWithDetachedComments, emitTrailingCommentsOfPosition = comments.emitTrailingCommentsOfPosition, emitLeadingCommentsOfPosition = comments.emitLeadingCommentsOfPosition; var currentSourceFile; var nodeIdToGeneratedName; // Map of generated names for specific nodes. var autoGeneratedIdToGeneratedName; // Map of generated names for temp and loop variables. var generatedNames; // Set of names generated by the NameGenerator. var tempFlagsStack; // Stack of enclosing name generation scopes. var tempFlags; // TempFlags for the current name generation scope. var writer; var ownWriter; reset(); return { // public API printNode: printNode, printFile: printFile, printBundle: printBundle, // internal API writeNode: writeNode, writeFile: writeFile, writeBundle: writeBundle }; function printNode(hint, node, sourceFile) { switch (hint) { case 0 /* SourceFile */: ts.Debug.assert(ts.isSourceFile(node), "Expected a SourceFile node."); break; case 2 /* IdentifierName */: ts.Debug.assert(ts.isIdentifier(node), "Expected an Identifier node."); break; case 1 /* Expression */: ts.Debug.assert(ts.isExpression(node), "Expected an Expression node."); break; } switch (node.kind) { case 269 /* SourceFile */: return printFile(node); case 270 /* Bundle */: return printBundle(node); } writeNode(hint, node, sourceFile, beginPrint()); return endPrint(); } function printBundle(bundle) { writeBundle(bundle, beginPrint()); return endPrint(); } function printFile(sourceFile) { writeFile(sourceFile, beginPrint()); return endPrint(); } function writeNode(hint, node, sourceFile, output) { var previousWriter = writer; setWriter(output); print(hint, node, sourceFile); reset(); writer = previousWriter; } function writeBundle(bundle, output) { var previousWriter = writer; setWriter(output); emitShebangIfNeeded(bundle); emitPrologueDirectivesIfNeeded(bundle); emitHelpersIndirect(bundle); for (var _a = 0, _b = bundle.sourceFiles; _a < _b.length; _a++) { var sourceFile = _b[_a]; print(0 /* SourceFile */, sourceFile, sourceFile); } reset(); writer = previousWriter; } function writeFile(sourceFile, output) { var previousWriter = writer; setWriter(output); emitShebangIfNeeded(sourceFile); emitPrologueDirectivesIfNeeded(sourceFile); print(0 /* SourceFile */, sourceFile, sourceFile); reset(); writer = previousWriter; } function beginPrint() { return ownWriter || (ownWriter = ts.createTextWriter(newLine)); } function endPrint() { var text = ownWriter.getText(); ownWriter.reset(); return text; } function print(hint, node, sourceFile) { if (sourceFile) { setSourceFile(sourceFile); } pipelineEmitWithNotification(hint, node); } function setSourceFile(sourceFile) { currentSourceFile = sourceFile; comments.setSourceFile(sourceFile); if (onSetSourceFile) { onSetSourceFile(sourceFile); } } function setWriter(output) { writer = output; comments.setWriter(output); } function reset() { nodeIdToGeneratedName = []; autoGeneratedIdToGeneratedName = []; generatedNames = ts.createMap(); tempFlagsStack = []; tempFlags = 0 /* Auto */; comments.reset(); setWriter(/*output*/ undefined); } // TODO: Should this just be `emit`? // See https://github.com/Microsoft/TypeScript/pull/18284#discussion_r137611034 function emitIfPresent(node) { if (node) { emit(node); } } function emit(node) { pipelineEmitWithNotification(4 /* Unspecified */, node); } function emitIdentifierName(node) { pipelineEmitWithNotification(2 /* IdentifierName */, node); } function emitExpression(node) { pipelineEmitWithNotification(1 /* Expression */, node); } function pipelineEmitWithNotification(hint, node) { if (onEmitNode) { onEmitNode(hint, node, pipelineEmitWithComments); } else { pipelineEmitWithComments(hint, node); } } function pipelineEmitWithComments(hint, node) { node = trySubstituteNode(hint, node); if (emitNodeWithComments && hint !== 0 /* SourceFile */) { emitNodeWithComments(hint, node, pipelineEmitWithSourceMap); } else { pipelineEmitWithSourceMap(hint, node); } } function pipelineEmitWithSourceMap(hint, node) { if (onEmitSourceMapOfNode && hint !== 0 /* SourceFile */ && hint !== 2 /* IdentifierName */) { onEmitSourceMapOfNode(hint, node, pipelineEmitWithHint); } else { pipelineEmitWithHint(hint, node); } } function pipelineEmitWithHint(hint, node) { switch (hint) { case 0 /* SourceFile */: return pipelineEmitSourceFile(node); case 2 /* IdentifierName */: return pipelineEmitIdentifierName(node); case 1 /* Expression */: return pipelineEmitExpression(node); case 3 /* MappedTypeParameter */: return emitMappedTypeParameter(ts.cast(node, ts.isTypeParameterDeclaration)); case 4 /* Unspecified */: return pipelineEmitUnspecified(node); } } function pipelineEmitSourceFile(node) { ts.Debug.assertNode(node, ts.isSourceFile); emitSourceFile(node); } function pipelineEmitIdentifierName(node) { ts.Debug.assertNode(node, ts.isIdentifier); emitIdentifier(node); } function emitMappedTypeParameter(node) { emit(node.name); write(" in "); emit(node.constraint); } function pipelineEmitUnspecified(node) { var kind = node.kind; // Reserved words // Strict mode reserved words // Contextual keywords if (ts.isKeyword(kind)) { writeTokenNode(node); return; } switch (kind) { // Pseudo-literals case 14 /* TemplateHead */: case 15 /* TemplateMiddle */: case 16 /* TemplateTail */: return emitLiteral(node); // Identifiers case 71 /* Identifier */: return emitIdentifier(node); // Parse tree nodes // Names case 144 /* QualifiedName */: return emitQualifiedName(node); case 145 /* ComputedPropertyName */: return emitComputedPropertyName(node); // Signature elements case 146 /* TypeParameter */: return emitTypeParameter(node); case 147 /* Parameter */: return emitParameter(node); case 148 /* Decorator */: return emitDecorator(node); // Type members case 149 /* PropertySignature */: return emitPropertySignature(node); case 150 /* PropertyDeclaration */: return emitPropertyDeclaration(node); case 151 /* MethodSignature */: return emitMethodSignature(node); case 152 /* MethodDeclaration */: return emitMethodDeclaration(node); case 153 /* Constructor */: return emitConstructor(node); case 154 /* GetAccessor */: case 155 /* SetAccessor */: return emitAccessorDeclaration(node); case 156 /* CallSignature */: return emitCallSignature(node); case 157 /* ConstructSignature */: return emitConstructSignature(node); case 158 /* IndexSignature */: return emitIndexSignature(node); // Types case 159 /* TypePredicate */: return emitTypePredicate(node); case 160 /* TypeReference */: return emitTypeReference(node); case 161 /* FunctionType */: return emitFunctionType(node); case 277 /* JSDocFunctionType */: return emitJSDocFunctionType(node); case 162 /* ConstructorType */: return emitConstructorType(node); case 163 /* TypeQuery */: return emitTypeQuery(node); case 164 /* TypeLiteral */: return emitTypeLiteral(node); case 165 /* ArrayType */: return emitArrayType(node); case 166 /* TupleType */: return emitTupleType(node); case 167 /* UnionType */: return emitUnionType(node); case 168 /* IntersectionType */: return emitIntersectionType(node); case 169 /* ParenthesizedType */: return emitParenthesizedType(node); case 202 /* ExpressionWithTypeArguments */: return emitExpressionWithTypeArguments(node); case 170 /* ThisType */: return emitThisType(); case 171 /* TypeOperator */: return emitTypeOperator(node); case 172 /* IndexedAccessType */: return emitIndexedAccessType(node); case 173 /* MappedType */: return emitMappedType(node); case 174 /* LiteralType */: return emitLiteralType(node); case 272 /* JSDocAllType */: write("*"); return; case 273 /* JSDocUnknownType */: write("?"); return; case 274 /* JSDocNullableType */: return emitJSDocNullableType(node); case 275 /* JSDocNonNullableType */: return emitJSDocNonNullableType(node); case 276 /* JSDocOptionalType */: return emitJSDocOptionalType(node); case 278 /* JSDocVariadicType */: return emitJSDocVariadicType(node); // Binding patterns case 175 /* ObjectBindingPattern */: return emitObjectBindingPattern(node); case 176 /* ArrayBindingPattern */: return emitArrayBindingPattern(node); case 177 /* BindingElement */: return emitBindingElement(node); // Misc case 206 /* TemplateSpan */: return emitTemplateSpan(node); case 207 /* SemicolonClassElement */: return emitSemicolonClassElement(); // Statements case 208 /* Block */: return emitBlock(node); case 209 /* VariableStatement */: return emitVariableStatement(node); case 210 /* EmptyStatement */: return emitEmptyStatement(); case 211 /* ExpressionStatement */: return emitExpressionStatement(node); case 212 /* IfStatement */: return emitIfStatement(node); case 213 /* DoStatement */: return emitDoStatement(node); case 214 /* WhileStatement */: return emitWhileStatement(node); case 215 /* ForStatement */: return emitForStatement(node); case 216 /* ForInStatement */: return emitForInStatement(node); case 217 /* ForOfStatement */: return emitForOfStatement(node); case 218 /* ContinueStatement */: return emitContinueStatement(node); case 219 /* BreakStatement */: return emitBreakStatement(node); case 220 /* ReturnStatement */: return emitReturnStatement(node); case 221 /* WithStatement */: return emitWithStatement(node); case 222 /* SwitchStatement */: return emitSwitchStatement(node); case 223 /* LabeledStatement */: return emitLabeledStatement(node); case 224 /* ThrowStatement */: return emitThrowStatement(node); case 225 /* TryStatement */: return emitTryStatement(node); case 226 /* DebuggerStatement */: return emitDebuggerStatement(node); // Declarations case 227 /* VariableDeclaration */: return emitVariableDeclaration(node); case 228 /* VariableDeclarationList */: return emitVariableDeclarationList(node); case 229 /* FunctionDeclaration */: return emitFunctionDeclaration(node); case 230 /* ClassDeclaration */: return emitClassDeclaration(node); case 231 /* InterfaceDeclaration */: return emitInterfaceDeclaration(node); case 232 /* TypeAliasDeclaration */: return emitTypeAliasDeclaration(node); case 233 /* EnumDeclaration */: return emitEnumDeclaration(node); case 234 /* ModuleDeclaration */: return emitModuleDeclaration(node); case 235 /* ModuleBlock */: return emitModuleBlock(node); case 236 /* CaseBlock */: return emitCaseBlock(node); case 237 /* NamespaceExportDeclaration */: return emitNamespaceExportDeclaration(node); case 238 /* ImportEqualsDeclaration */: return emitImportEqualsDeclaration(node); case 239 /* ImportDeclaration */: return emitImportDeclaration(node); case 240 /* ImportClause */: return emitImportClause(node); case 241 /* NamespaceImport */: return emitNamespaceImport(node); case 242 /* NamedImports */: return emitNamedImports(node); case 243 /* ImportSpecifier */: return emitImportSpecifier(node); case 244 /* ExportAssignment */: return emitExportAssignment(node); case 245 /* ExportDeclaration */: return emitExportDeclaration(node); case 246 /* NamedExports */: return emitNamedExports(node); case 247 /* ExportSpecifier */: return emitExportSpecifier(node); case 248 /* MissingDeclaration */: return; // Module references case 249 /* ExternalModuleReference */: return emitExternalModuleReference(node); // JSX (non-expression) case 10 /* JsxText */: return emitJsxText(node); case 252 /* JsxOpeningElement */: case 255 /* JsxOpeningFragment */: return emitJsxOpeningElementOrFragment(node); case 253 /* JsxClosingElement */: case 256 /* JsxClosingFragment */: return emitJsxClosingElementOrFragment(node); case 257 /* JsxAttribute */: return emitJsxAttribute(node); case 258 /* JsxAttributes */: return emitJsxAttributes(node); case 259 /* JsxSpreadAttribute */: return emitJsxSpreadAttribute(node); case 260 /* JsxExpression */: return emitJsxExpression(node); // Clauses case 261 /* CaseClause */: return emitCaseClause(node); case 262 /* DefaultClause */: return emitDefaultClause(node); case 263 /* HeritageClause */: return emitHeritageClause(node); case 264 /* CatchClause */: return emitCatchClause(node); // Property assignments case 265 /* PropertyAssignment */: return emitPropertyAssignment(node); case 266 /* ShorthandPropertyAssignment */: return emitShorthandPropertyAssignment(node); case 267 /* SpreadAssignment */: return emitSpreadAssignment(node); // Enum case 268 /* EnumMember */: return emitEnumMember(node); } // If the node is an expression, try to emit it as an expression with // substitution. if (ts.isExpression(node)) { return pipelineEmitExpression(trySubstituteNode(1 /* Expression */, node)); } if (ts.isToken(node)) { writeTokenNode(node); return; } } function pipelineEmitExpression(node) { var kind = node.kind; switch (kind) { // Literals case 8 /* NumericLiteral */: return emitNumericLiteral(node); case 9 /* StringLiteral */: case 12 /* RegularExpressionLiteral */: case 13 /* NoSubstitutionTemplateLiteral */: return emitLiteral(node); // Identifiers case 71 /* Identifier */: return emitIdentifier(node); // Reserved words case 86 /* FalseKeyword */: case 95 /* NullKeyword */: case 97 /* SuperKeyword */: case 101 /* TrueKeyword */: case 99 /* ThisKeyword */: case 91 /* ImportKeyword */: writeTokenNode(node); return; // Expressions case 178 /* ArrayLiteralExpression */: return emitArrayLiteralExpression(node); case 179 /* ObjectLiteralExpression */: return emitObjectLiteralExpression(node); case 180 /* PropertyAccessExpression */: return emitPropertyAccessExpression(node); case 181 /* ElementAccessExpression */: return emitElementAccessExpression(node); case 182 /* CallExpression */: return emitCallExpression(node); case 183 /* NewExpression */: return emitNewExpression(node); case 184 /* TaggedTemplateExpression */: return emitTaggedTemplateExpression(node); case 185 /* TypeAssertionExpression */: return emitTypeAssertionExpression(node); case 186 /* ParenthesizedExpression */: return emitParenthesizedExpression(node); case 187 /* FunctionExpression */: return emitFunctionExpression(node); case 188 /* ArrowFunction */: return emitArrowFunction(node); case 189 /* DeleteExpression */: return emitDeleteExpression(node); case 190 /* TypeOfExpression */: return emitTypeOfExpression(node); case 191 /* VoidExpression */: return emitVoidExpression(node); case 192 /* AwaitExpression */: return emitAwaitExpression(node); case 193 /* PrefixUnaryExpression */: return emitPrefixUnaryExpression(node); case 194 /* PostfixUnaryExpression */: return emitPostfixUnaryExpression(node); case 195 /* BinaryExpression */: return emitBinaryExpression(node); case 196 /* ConditionalExpression */: return emitConditionalExpression(node); case 197 /* TemplateExpression */: return emitTemplateExpression(node); case 198 /* YieldExpression */: return emitYieldExpression(node); case 199 /* SpreadElement */: return emitSpreadExpression(node); case 200 /* ClassExpression */: return emitClassExpression(node); case 201 /* OmittedExpression */: return; case 203 /* AsExpression */: return emitAsExpression(node); case 204 /* NonNullExpression */: return emitNonNullExpression(node); case 205 /* MetaProperty */: return emitMetaProperty(node); // JSX case 250 /* JsxElement */: return emitJsxElement(node); case 251 /* JsxSelfClosingElement */: return emitJsxSelfClosingElement(node); case 254 /* JsxFragment */: return emitJsxFragment(node); // Transformation nodes case 292 /* PartiallyEmittedExpression */: return emitPartiallyEmittedExpression(node); case 293 /* CommaListExpression */: return emitCommaList(node); } } function trySubstituteNode(hint, node) { return node && substituteNode && substituteNode(hint, node) || node; } function emitHelpersIndirect(node) { if (onEmitHelpers) { onEmitHelpers(node, writeLines); } } // // Literals/Pseudo-literals // // SyntaxKind.NumericLiteral function emitNumericLiteral(node) { emitLiteral(node); } // SyntaxKind.StringLiteral // SyntaxKind.RegularExpressionLiteral // SyntaxKind.NoSubstitutionTemplateLiteral // SyntaxKind.TemplateHead // SyntaxKind.TemplateMiddle // SyntaxKind.TemplateTail function emitLiteral(node) { var text = getLiteralTextOfNode(node); if ((printerOptions.sourceMap || printerOptions.inlineSourceMap) && (node.kind === 9 /* StringLiteral */ || ts.isTemplateLiteralKind(node.kind))) { writer.writeLiteral(text); } else { write(text); } } // // Identifiers // function emitIdentifier(node) { write(getTextOfNode(node, /*includeTrivia*/ false)); emitTypeArguments(node, node.typeArguments); } // // Names // function emitQualifiedName(node) { emitEntityName(node.left); write("."); emit(node.right); } function emitEntityName(node) { if (node.kind === 71 /* Identifier */) { emitExpression(node); } else { emit(node); } } function emitComputedPropertyName(node) { write("["); emitExpression(node.expression); write("]"); } // // Signature elements // function emitTypeParameter(node) { emit(node.name); emitWithPrefix(" extends ", node.constraint); emitWithPrefix(" = ", node.default); } function emitParameter(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitIfPresent(node.dotDotDotToken); if (node.name) { emit(node.name); } emitIfPresent(node.questionToken); if (node.parent && node.parent.kind === 277 /* JSDocFunctionType */ && !node.name) { emit(node.type); } else { emitWithPrefix(": ", node.type); } emitExpressionWithPrefix(" = ", node.initializer); } function emitDecorator(decorator) { write("@"); emitExpression(decorator.expression); } // // Type members // function emitPropertySignature(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); write(";"); } function emitPropertyDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); emitIfPresent(node.questionToken); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); write(";"); } function emitMethodSignature(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emit(node.name); emitIfPresent(node.questionToken); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); write(";"); } function emitMethodDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitIfPresent(node.asteriskToken); emit(node.name); emitIfPresent(node.questionToken); emitSignatureAndBody(node, emitSignatureHead); } function emitConstructor(node) { emitModifiers(node, node.modifiers); write("constructor"); emitSignatureAndBody(node, emitSignatureHead); } function emitAccessorDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write(node.kind === 154 /* GetAccessor */ ? "get " : "set "); emit(node.name); emitSignatureAndBody(node, emitSignatureHead); } function emitCallSignature(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); write(";"); } function emitConstructSignature(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("new "); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); write(";"); } function emitIndexSignature(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitParametersForIndexSignature(node, node.parameters); emitWithPrefix(": ", node.type); write(";"); } function emitSemicolonClassElement() { write(";"); } // // Types // function emitTypePredicate(node) { emit(node.parameterName); write(" is "); emit(node.type); } function emitTypeReference(node) { emit(node.typeName); emitTypeArguments(node, node.typeArguments); } function emitFunctionType(node) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); write(" => "); emit(node.type); } function emitJSDocFunctionType(node) { write("function"); emitParameters(node, node.parameters); write(":"); emit(node.type); } function emitJSDocNullableType(node) { write("?"); emit(node.type); } function emitJSDocNonNullableType(node) { write("!"); emit(node.type); } function emitJSDocOptionalType(node) { emit(node.type); write("="); } function emitConstructorType(node) { write("new "); emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); write(" => "); emit(node.type); } function emitTypeQuery(node) { write("typeof "); emit(node.exprName); } function emitTypeLiteral(node) { write("{"); var flags = ts.getEmitFlags(node) & 1 /* SingleLine */ ? 448 /* SingleLineTypeLiteralMembers */ : 65 /* MultiLineTypeLiteralMembers */; emitList(node, node.members, flags | 262144 /* NoSpaceIfEmpty */); write("}"); } function emitArrayType(node) { emit(node.elementType); write("[]"); } function emitJSDocVariadicType(node) { write("..."); emit(node.type); } function emitTupleType(node) { write("["); emitList(node, node.elementTypes, 336 /* TupleTypeElements */); write("]"); } function emitUnionType(node) { emitList(node, node.types, 260 /* UnionTypeConstituents */); } function emitIntersectionType(node) { emitList(node, node.types, 264 /* IntersectionTypeConstituents */); } function emitParenthesizedType(node) { write("("); emit(node.type); write(")"); } function emitThisType() { write("this"); } function emitTypeOperator(node) { writeTokenText(node.operator); write(" "); emit(node.type); } function emitIndexedAccessType(node) { emit(node.objectType); write("["); emit(node.indexType); write("]"); } function emitMappedType(node) { var emitFlags = ts.getEmitFlags(node); write("{"); if (emitFlags & 1 /* SingleLine */) { write(" "); } else { writeLine(); increaseIndent(); } if (node.readonlyToken) { emit(node.readonlyToken); write(" "); } write("["); pipelineEmitWithNotification(3 /* MappedTypeParameter */, node.typeParameter); write("]"); emitIfPresent(node.questionToken); write(": "); emit(node.type); write(";"); if (emitFlags & 1 /* SingleLine */) { write(" "); } else { writeLine(); decreaseIndent(); } write("}"); } function emitLiteralType(node) { emitExpression(node.literal); } // // Binding patterns // function emitObjectBindingPattern(node) { var elements = node.elements; if (elements.length === 0) { write("{}"); } else { write("{"); emitList(node, elements, 432 /* ObjectBindingPatternElements */); write("}"); } } function emitArrayBindingPattern(node) { var elements = node.elements; if (elements.length === 0) { write("[]"); } else { write("["); emitList(node, node.elements, 304 /* ArrayBindingPatternElements */); write("]"); } } function emitBindingElement(node) { emitWithSuffix(node.propertyName, ": "); emitIfPresent(node.dotDotDotToken); emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } // // Expressions // function emitArrayLiteralExpression(node) { var elements = node.elements; var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; emitExpressionList(node, elements, 4466 /* ArrayLiteralExpressionElements */ | preferNewLine); } function emitObjectLiteralExpression(node) { var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; if (indentedFlag) { increaseIndent(); } var preferNewLine = node.multiLine ? 32768 /* PreferNewLine */ : 0 /* None */; var allowTrailingComma = currentSourceFile.languageVersion >= 1 /* ES5 */ ? 32 /* AllowTrailingComma */ : 0 /* None */; emitList(node, node.properties, 263122 /* ObjectLiteralExpressionProperties */ | allowTrailingComma | preferNewLine); if (indentedFlag) { decreaseIndent(); } } function emitPropertyAccessExpression(node) { var indentBeforeDot = false; var indentAfterDot = false; if (!(ts.getEmitFlags(node) & 131072 /* NoIndentation */)) { var dotRangeStart = node.expression.end; var dotRangeEnd = ts.skipTrivia(currentSourceFile.text, node.expression.end) + 1; var dotToken = ts.createToken(23 /* DotToken */); dotToken.pos = dotRangeStart; dotToken.end = dotRangeEnd; indentBeforeDot = needsIndentation(node, node.expression, dotToken); indentAfterDot = needsIndentation(node, dotToken, node.name); } emitExpression(node.expression); increaseIndentIf(indentBeforeDot); var shouldEmitDotDot = !indentBeforeDot && needsDotDotForPropertyAccess(node.expression); write(shouldEmitDotDot ? ".." : "."); increaseIndentIf(indentAfterDot); emit(node.name); decreaseIndentIf(indentBeforeDot, indentAfterDot); } // 1..toString is a valid property access, emit a dot after the literal // Also emit a dot if expression is a integer const enum value - it will appear in generated code as numeric literal function needsDotDotForPropertyAccess(expression) { expression = ts.skipPartiallyEmittedExpressions(expression); if (ts.isNumericLiteral(expression)) { // check if numeric literal is a decimal literal that was originally written with a dot var text = getLiteralTextOfNode(expression); return !expression.numericLiteralFlags && !ts.stringContains(text, ts.tokenToString(23 /* DotToken */)); } else if (ts.isPropertyAccessExpression(expression) || ts.isElementAccessExpression(expression)) { // check if constant enum value is integer var constantValue = ts.getConstantValue(expression); // isFinite handles cases when constantValue is undefined return typeof constantValue === "number" && isFinite(constantValue) && Math.floor(constantValue) === constantValue && printerOptions.removeComments; } } function emitElementAccessExpression(node) { emitExpression(node.expression); write("["); emitExpression(node.argumentExpression); write("]"); } function emitCallExpression(node) { emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, 1296 /* CallExpressionArguments */); } function emitNewExpression(node) { write("new "); emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); emitExpressionList(node, node.arguments, 9488 /* NewExpressionArguments */); } function emitTaggedTemplateExpression(node) { emitExpression(node.tag); write(" "); emitExpression(node.template); } function emitTypeAssertionExpression(node) { write("<"); emit(node.type); write(">"); emitExpression(node.expression); } function emitParenthesizedExpression(node) { write("("); emitExpression(node.expression); write(")"); } function emitFunctionExpression(node) { emitFunctionDeclarationOrExpression(node); } function emitArrowFunction(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); emitSignatureAndBody(node, emitArrowFunctionHead); } function emitArrowFunctionHead(node) { emitTypeParameters(node, node.typeParameters); emitParametersForArrow(node, node.parameters); emitWithPrefix(": ", node.type); write(" "); emit(node.equalsGreaterThanToken); } function emitDeleteExpression(node) { write("delete "); emitExpression(node.expression); } function emitTypeOfExpression(node) { write("typeof "); emitExpression(node.expression); } function emitVoidExpression(node) { write("void "); emitExpression(node.expression); } function emitAwaitExpression(node) { write("await "); emitExpression(node.expression); } function emitPrefixUnaryExpression(node) { writeTokenText(node.operator); if (shouldEmitWhitespaceBeforeOperand(node)) { write(" "); } emitExpression(node.operand); } function shouldEmitWhitespaceBeforeOperand(node) { // In some cases, we need to emit a space between the operator and the operand. One obvious case // is when the operator is an identifier, like delete or typeof. We also need to do this for plus // and minus expressions in certain cases. Specifically, consider the following two cases (parens // are just for clarity of exposition, and not part of the source code): // // (+(+1)) // (+(++1)) // // We need to emit a space in both cases. In the first case, the absence of a space will make // the resulting expression a prefix increment operation. And in the second, it will make the resulting // expression a prefix increment whose operand is a plus expression - (++(+x)) // The same is true of minus of course. var operand = node.operand; return operand.kind === 193 /* PrefixUnaryExpression */ && ((node.operator === 37 /* PlusToken */ && (operand.operator === 37 /* PlusToken */ || operand.operator === 43 /* PlusPlusToken */)) || (node.operator === 38 /* MinusToken */ && (operand.operator === 38 /* MinusToken */ || operand.operator === 44 /* MinusMinusToken */))); } function emitPostfixUnaryExpression(node) { emitExpression(node.operand); writeTokenText(node.operator); } function emitBinaryExpression(node) { var isCommaOperator = node.operatorToken.kind !== 26 /* CommaToken */; var indentBeforeOperator = needsIndentation(node, node.left, node.operatorToken); var indentAfterOperator = needsIndentation(node, node.operatorToken, node.right); emitExpression(node.left); increaseIndentIf(indentBeforeOperator, isCommaOperator ? " " : undefined); emitLeadingCommentsOfPosition(node.operatorToken.pos); writeTokenNode(node.operatorToken); emitTrailingCommentsOfPosition(node.operatorToken.end, /*prefixSpace*/ true); // Binary operators should have a space before the comment starts increaseIndentIf(indentAfterOperator, " "); emitExpression(node.right); decreaseIndentIf(indentBeforeOperator, indentAfterOperator); } function emitConditionalExpression(node) { var indentBeforeQuestion = needsIndentation(node, node.condition, node.questionToken); var indentAfterQuestion = needsIndentation(node, node.questionToken, node.whenTrue); var indentBeforeColon = needsIndentation(node, node.whenTrue, node.colonToken); var indentAfterColon = needsIndentation(node, node.colonToken, node.whenFalse); emitExpression(node.condition); increaseIndentIf(indentBeforeQuestion, " "); emit(node.questionToken); increaseIndentIf(indentAfterQuestion, " "); emitExpression(node.whenTrue); decreaseIndentIf(indentBeforeQuestion, indentAfterQuestion); increaseIndentIf(indentBeforeColon, " "); emit(node.colonToken); increaseIndentIf(indentAfterColon, " "); emitExpression(node.whenFalse); decreaseIndentIf(indentBeforeColon, indentAfterColon); } function emitTemplateExpression(node) { emit(node.head); emitList(node, node.templateSpans, 131072 /* TemplateExpressionSpans */); } function emitYieldExpression(node) { write("yield"); emit(node.asteriskToken); emitExpressionWithPrefix(" ", node.expression); } function emitSpreadExpression(node) { write("..."); emitExpression(node.expression); } function emitClassExpression(node) { emitClassDeclarationOrExpression(node); } function emitExpressionWithTypeArguments(node) { emitExpression(node.expression); emitTypeArguments(node, node.typeArguments); } function emitAsExpression(node) { emitExpression(node.expression); if (node.type) { write(" as "); emit(node.type); } } function emitNonNullExpression(node) { emitExpression(node.expression); write("!"); } function emitMetaProperty(node) { writeToken(node.keywordToken, node.pos); write("."); emit(node.name); } // // Misc // function emitTemplateSpan(node) { emitExpression(node.expression); emit(node.literal); } // // Statements // function emitBlock(node) { writeToken(17 /* OpenBraceToken */, node.pos, /*contextNode*/ node); emitBlockStatements(node, /*forceSingleLine*/ !node.multiLine && isEmptyBlock(node)); // We have to call emitLeadingComments explicitly here because otherwise leading comments of the close brace token will not be emitted increaseIndent(); emitLeadingCommentsOfPosition(node.statements.end); decreaseIndent(); writeToken(18 /* CloseBraceToken */, node.statements.end, /*contextNode*/ node); } function emitBlockStatements(node, forceSingleLine) { var format = forceSingleLine || ts.getEmitFlags(node) & 1 /* SingleLine */ ? 384 /* SingleLineBlockStatements */ : 65 /* MultiLineBlockStatements */; emitList(node, node.statements, format); } function emitVariableStatement(node) { emitModifiers(node, node.modifiers); emit(node.declarationList); write(";"); } function emitEmptyStatement() { write(";"); } function emitExpressionStatement(node) { emitExpression(node.expression); write(";"); } function emitIfStatement(node) { var openParenPos = writeToken(90 /* IfKeyword */, node.pos, node); write(" "); writeToken(19 /* OpenParenToken */, openParenPos, node); emitExpression(node.expression); writeToken(20 /* CloseParenToken */, node.expression.end, node); emitEmbeddedStatement(node, node.thenStatement); if (node.elseStatement) { writeLineOrSpace(node); writeToken(82 /* ElseKeyword */, node.thenStatement.end, node); if (node.elseStatement.kind === 212 /* IfStatement */) { write(" "); emit(node.elseStatement); } else { emitEmbeddedStatement(node, node.elseStatement); } } } function emitDoStatement(node) { write("do"); emitEmbeddedStatement(node, node.statement); if (ts.isBlock(node.statement)) { write(" "); } else { writeLineOrSpace(node); } write("while ("); emitExpression(node.expression); write(");"); } function emitWhileStatement(node) { write("while ("); emitExpression(node.expression); write(")"); emitEmbeddedStatement(node, node.statement); } function emitForStatement(node) { var openParenPos = writeToken(88 /* ForKeyword */, node.pos); write(" "); writeToken(19 /* OpenParenToken */, openParenPos, /*contextNode*/ node); emitForBinding(node.initializer); write(";"); emitExpressionWithPrefix(" ", node.condition); write(";"); emitExpressionWithPrefix(" ", node.incrementor); write(")"); emitEmbeddedStatement(node, node.statement); } function emitForInStatement(node) { var openParenPos = writeToken(88 /* ForKeyword */, node.pos); write(" "); writeToken(19 /* OpenParenToken */, openParenPos); emitForBinding(node.initializer); write(" in "); emitExpression(node.expression); writeToken(20 /* CloseParenToken */, node.expression.end); emitEmbeddedStatement(node, node.statement); } function emitForOfStatement(node) { var openParenPos = writeToken(88 /* ForKeyword */, node.pos); write(" "); emitWithSuffix(node.awaitModifier, " "); writeToken(19 /* OpenParenToken */, openParenPos); emitForBinding(node.initializer); write(" of "); emitExpression(node.expression); writeToken(20 /* CloseParenToken */, node.expression.end); emitEmbeddedStatement(node, node.statement); } function emitForBinding(node) { if (node !== undefined) { if (node.kind === 228 /* VariableDeclarationList */) { emit(node); } else { emitExpression(node); } } } function emitContinueStatement(node) { writeToken(77 /* ContinueKeyword */, node.pos); emitWithPrefix(" ", node.label); write(";"); } function emitBreakStatement(node) { writeToken(72 /* BreakKeyword */, node.pos); emitWithPrefix(" ", node.label); write(";"); } function emitTokenWithComment(token, pos, contextNode) { var node = contextNode && ts.getParseTreeNode(contextNode); if (node && node.kind === contextNode.kind) { pos = ts.skipTrivia(currentSourceFile.text, pos); } pos = writeToken(token, pos, /*contextNode*/ contextNode); if (node && node.kind === contextNode.kind) { emitTrailingCommentsOfPosition(pos, /*prefixSpace*/ true); } return pos; } function emitReturnStatement(node) { emitTokenWithComment(96 /* ReturnKeyword */, node.pos, /*contextNode*/ node); emitExpressionWithPrefix(" ", node.expression); write(";"); } function emitWithStatement(node) { write("with ("); emitExpression(node.expression); write(")"); emitEmbeddedStatement(node, node.statement); } function emitSwitchStatement(node) { var openParenPos = writeToken(98 /* SwitchKeyword */, node.pos); write(" "); writeToken(19 /* OpenParenToken */, openParenPos); emitExpression(node.expression); writeToken(20 /* CloseParenToken */, node.expression.end); write(" "); emit(node.caseBlock); } function emitLabeledStatement(node) { emit(node.label); write(": "); emit(node.statement); } function emitThrowStatement(node) { write("throw"); emitExpressionWithPrefix(" ", node.expression); write(";"); } function emitTryStatement(node) { write("try "); emit(node.tryBlock); if (node.catchClause) { writeLineOrSpace(node); emit(node.catchClause); } if (node.finallyBlock) { writeLineOrSpace(node); write("finally "); emit(node.finallyBlock); } } function emitDebuggerStatement(node) { writeToken(78 /* DebuggerKeyword */, node.pos); write(";"); } // // Declarations // function emitVariableDeclaration(node) { emit(node.name); emitWithPrefix(": ", node.type); emitExpressionWithPrefix(" = ", node.initializer); } function emitVariableDeclarationList(node) { write(ts.isLet(node) ? "let " : ts.isConst(node) ? "const " : "var "); emitList(node, node.declarations, 272 /* VariableDeclarationList */); } function emitFunctionDeclaration(node) { emitFunctionDeclarationOrExpression(node); } function emitFunctionDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("function"); emitIfPresent(node.asteriskToken); write(" "); emitIdentifierName(node.name); emitSignatureAndBody(node, emitSignatureHead); } function emitBlockCallback(_hint, body) { emitBlockFunctionBody(body); } function emitSignatureAndBody(node, emitSignatureHead) { var body = node.body; if (body) { if (ts.isBlock(body)) { var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; if (indentedFlag) { increaseIndent(); } pushNameGenerationScope(node); emitSignatureHead(node); if (onEmitNode) { onEmitNode(4 /* Unspecified */, body, emitBlockCallback); } else { emitBlockFunctionBody(body); } popNameGenerationScope(node); if (indentedFlag) { decreaseIndent(); } } else { emitSignatureHead(node); write(" "); emitExpression(body); } } else { emitSignatureHead(node); write(";"); } } function emitSignatureHead(node) { emitTypeParameters(node, node.typeParameters); emitParameters(node, node.parameters); emitWithPrefix(": ", node.type); } function shouldEmitBlockFunctionBodyOnSingleLine(body) { // We must emit a function body as a single-line body in the following case: // * The body has NodeEmitFlags.SingleLine specified. // We must emit a function body as a multi-line body in the following cases: // * The body is explicitly marked as multi-line. // * A non-synthesized body's start and end position are on different lines. // * Any statement in the body starts on a new line. if (ts.getEmitFlags(body) & 1 /* SingleLine */) { return true; } if (body.multiLine) { return false; } if (!ts.nodeIsSynthesized(body) && !ts.rangeIsOnSingleLine(body, currentSourceFile)) { return false; } if (shouldWriteLeadingLineTerminator(body, body.statements, 2 /* PreserveLines */) || shouldWriteClosingLineTerminator(body, body.statements, 2 /* PreserveLines */)) { return false; } var previousStatement; for (var _a = 0, _b = body.statements; _a < _b.length; _a++) { var statement = _b[_a]; if (shouldWriteSeparatingLineTerminator(previousStatement, statement, 2 /* PreserveLines */)) { return false; } previousStatement = statement; } return true; } function emitBlockFunctionBody(body) { write(" {"); increaseIndent(); var emitBlockFunctionBody = shouldEmitBlockFunctionBodyOnSingleLine(body) ? emitBlockFunctionBodyOnSingleLine : emitBlockFunctionBodyWorker; if (emitBodyWithDetachedComments) { emitBodyWithDetachedComments(body, body.statements, emitBlockFunctionBody); } else { emitBlockFunctionBody(body); } decreaseIndent(); writeToken(18 /* CloseBraceToken */, body.statements.end, body); } function emitBlockFunctionBodyOnSingleLine(body) { emitBlockFunctionBodyWorker(body, /*emitBlockFunctionBodyOnSingleLine*/ true); } function emitBlockFunctionBodyWorker(body, emitBlockFunctionBodyOnSingleLine) { // Emit all the prologue directives (like "use strict"). var statementOffset = emitPrologueDirectives(body.statements, /*startWithNewLine*/ true); var pos = writer.getTextPos(); emitHelpersIndirect(body); if (statementOffset === 0 && pos === writer.getTextPos() && emitBlockFunctionBodyOnSingleLine) { decreaseIndent(); emitList(body, body.statements, 384 /* SingleLineFunctionBodyStatements */); increaseIndent(); } else { emitList(body, body.statements, 1 /* MultiLineFunctionBodyStatements */, statementOffset); } } function emitClassDeclaration(node) { emitClassDeclarationOrExpression(node); } function emitClassDeclarationOrExpression(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("class"); emitNodeWithPrefix(" ", node.name, emitIdentifierName); var indentedFlag = ts.getEmitFlags(node) & 65536 /* Indented */; if (indentedFlag) { increaseIndent(); } emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, 256 /* ClassHeritageClauses */); write(" {"); emitList(node, node.members, 65 /* ClassMembers */); write("}"); if (indentedFlag) { decreaseIndent(); } } function emitInterfaceDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("interface "); emit(node.name); emitTypeParameters(node, node.typeParameters); emitList(node, node.heritageClauses, 256 /* HeritageClauses */); write(" {"); emitList(node, node.members, 65 /* InterfaceMembers */); write("}"); } function emitTypeAliasDeclaration(node) { emitDecorators(node, node.decorators); emitModifiers(node, node.modifiers); write("type "); emit(node.name); emitTypeParameters(node, node.typeParameters); write(" = "); emit(node.type); write(";"); } function emitEnumDeclaration(node) { emitModifiers(node, node.modifiers); write("enum "); emit(node.name); write(" {"); emitList(node, node.members, 81 /* EnumMembers */); write("}"); } function emitModuleDeclaration(node) { emitModifiers(node, node.modifiers); if (~node.flags & 512 /* GlobalAugmentation */) { write(node.flags & 16 /* Namespace */ ? "namespace " : "module "); } emit(node.name); var body = node.body; while (body.kind === 234 /* ModuleDeclaration */) { write("."); emit(body.name); body = body.body; } write(" "); emit(body); } function emitModuleBlock(node) { pushNameGenerationScope(node); write("{"); emitBlockStatements(node, /*forceSingleLine*/ isEmptyBlock(node)); write("}"); popNameGenerationScope(node); } function emitCaseBlock(node) { writeToken(17 /* OpenBraceToken */, node.pos); emitList(node, node.clauses, 65 /* CaseBlockClauses */); writeToken(18 /* CloseBraceToken */, node.clauses.end); } function emitImportEqualsDeclaration(node) { emitModifiers(node, node.modifiers); write("import "); emit(node.name); write(" = "); emitModuleReference(node.moduleReference); write(";"); } function emitModuleReference(node) { if (node.kind === 71 /* Identifier */) { emitExpression(node); } else { emit(node); } } function emitImportDeclaration(node) { emitModifiers(node, node.modifiers); write("import "); if (node.importClause) { emit(node.importClause); write(" from "); } emitExpression(node.moduleSpecifier); write(";"); } function emitImportClause(node) { emit(node.name); if (node.name && node.namedBindings) { write(", "); } emit(node.namedBindings); } function emitNamespaceImport(node) { write("* as "); emit(node.name); } function emitNamedImports(node) { emitNamedImportsOrExports(node); } function emitImportSpecifier(node) { emitImportOrExportSpecifier(node); } function emitExportAssignment(node) { write(node.isExportEquals ? "export = " : "export default "); emitExpression(node.expression); write(";"); } function emitExportDeclaration(node) { write("export "); if (node.exportClause) { emit(node.exportClause); } else { write("*"); } if (node.moduleSpecifier) { write(" from "); emitExpression(node.moduleSpecifier); } write(";"); } function emitNamespaceExportDeclaration(node) { write("export as namespace "); emit(node.name); write(";"); } function emitNamedExports(node) { emitNamedImportsOrExports(node); } function emitExportSpecifier(node) { emitImportOrExportSpecifier(node); } function emitNamedImportsOrExports(node) { write("{"); emitList(node, node.elements, 432 /* NamedImportsOrExportsElements */); write("}"); } function emitImportOrExportSpecifier(node) { if (node.propertyName) { emit(node.propertyName); write(" as "); } emit(node.name); } // // Module references // function emitExternalModuleReference(node) { write("require("); emitExpression(node.expression); write(")"); } // // JSX // function emitJsxElement(node) { emit(node.openingElement); emitList(node, node.children, 131072 /* JsxElementOrFragmentChildren */); emit(node.closingElement); } function emitJsxSelfClosingElement(node) { write("<"); emitJsxTagName(node.tagName); write(" "); // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { emit(node.attributes); } write("/>"); } function emitJsxFragment(node) { emit(node.openingFragment); emitList(node, node.children, 131072 /* JsxElementOrFragmentChildren */); emit(node.closingFragment); } function emitJsxOpeningElementOrFragment(node) { write("<"); if (ts.isJsxOpeningElement(node)) { emitJsxTagName(node.tagName); // We are checking here so we won't re-enter the emitting pipeline and emit extra sourcemap if (node.attributes.properties && node.attributes.properties.length > 0) { write(" "); emit(node.attributes); } } write(">"); } function emitJsxText(node) { writer.writeLiteral(getTextOfNode(node, /*includeTrivia*/ true)); } function emitJsxClosingElementOrFragment(node) { write(""); } function emitJsxAttributes(node) { emitList(node, node.properties, 131328 /* JsxElementAttributes */); } function emitJsxAttribute(node) { emit(node.name); emitWithPrefix("=", node.initializer); } function emitJsxSpreadAttribute(node) { write("{..."); emitExpression(node.expression); write("}"); } function emitJsxExpression(node) { if (node.expression) { write("{"); emitIfPresent(node.dotDotDotToken); emitExpression(node.expression); write("}"); } } function emitJsxTagName(node) { if (node.kind === 71 /* Identifier */) { emitExpression(node); } else { emit(node); } } // // Clauses // function emitCaseClause(node) { write("case "); emitExpression(node.expression); write(":"); emitCaseOrDefaultClauseStatements(node, node.statements); } function emitDefaultClause(node) { write("default:"); emitCaseOrDefaultClauseStatements(node, node.statements); } function emitCaseOrDefaultClauseStatements(parentNode, statements) { var emitAsSingleStatement = statements.length === 1 && ( // treat synthesized nodes as located on the same line for emit purposes ts.nodeIsSynthesized(parentNode) || ts.nodeIsSynthesized(statements[0]) || ts.rangeStartPositionsAreOnSameLine(parentNode, statements[0], currentSourceFile)); // e.g: // case 0: // Zero // case 1: // One // case 2: // two // return "hi"; // If there is no statements, emitNodeWithComments of the parentNode which is caseClause will take care of trailing comment. // So in example above, comment "// Zero" and "// One" will be emit in emitTrailingComments in emitNodeWithComments. // However, for "case 2", because parentNode which is caseClause has an "end" property to be end of the statements (in this case return statement) // comment "// two" will not be emitted in emitNodeWithComments. // Therefore, we have to do the check here to emit such comment. if (statements.length > 0) { // We use emitTrailingCommentsOfPosition instead of emitLeadingCommentsOfPosition because leading comments is defined as comments before the node after newline character separating it from previous line // Note: we can't use parentNode.end as such position includes statements. emitTrailingCommentsOfPosition(statements.pos); } var format = 81985 /* CaseOrDefaultClauseStatements */; if (emitAsSingleStatement) { write(" "); format &= ~(1 /* MultiLine */ | 64 /* Indented */); } emitList(parentNode, statements, format); } function emitHeritageClause(node) { write(" "); writeTokenText(node.token); write(" "); emitList(node, node.types, 272 /* HeritageClauseTypes */); } function emitCatchClause(node) { var openParenPos = writeToken(74 /* CatchKeyword */, node.pos); write(" "); if (node.variableDeclaration) { writeToken(19 /* OpenParenToken */, openParenPos); emit(node.variableDeclaration); writeToken(20 /* CloseParenToken */, node.variableDeclaration.end); write(" "); } emit(node.block); } // // Property assignments // function emitPropertyAssignment(node) { emit(node.name); write(": "); // This is to ensure that we emit comment in the following case: // For example: // obj = { // id: /*comment1*/ ()=>void // } // "comment1" is not considered to be leading comment for node.initializer // but rather a trailing comment on the previous node. var initializer = node.initializer; if (emitTrailingCommentsOfPosition && (ts.getEmitFlags(initializer) & 512 /* NoLeadingComments */) === 0) { var commentRange = ts.getCommentRange(initializer); emitTrailingCommentsOfPosition(commentRange.pos); } emitExpression(initializer); } function emitShorthandPropertyAssignment(node) { emit(node.name); if (node.objectAssignmentInitializer) { write(" = "); emitExpression(node.objectAssignmentInitializer); } } function emitSpreadAssignment(node) { if (node.expression) { write("..."); emitExpression(node.expression); } } // // Enum // function emitEnumMember(node) { emit(node.name); emitExpressionWithPrefix(" = ", node.initializer); } // // Top-level nodes // function emitSourceFile(node) { writeLine(); var statements = node.statements; if (emitBodyWithDetachedComments) { // Emit detached comment if there are no prologue directives or if the first node is synthesized. // The synthesized node will have no leading comment so some comments may be missed. var shouldEmitDetachedComment = statements.length === 0 || !ts.isPrologueDirective(statements[0]) || ts.nodeIsSynthesized(statements[0]); if (shouldEmitDetachedComment) { emitBodyWithDetachedComments(node, statements, emitSourceFileWorker); return; } } emitSourceFileWorker(node); } function emitSourceFileWorker(node) { var statements = node.statements; pushNameGenerationScope(node); emitHelpersIndirect(node); var index = ts.findIndex(statements, function (statement) { return !ts.isPrologueDirective(statement); }); emitList(node, statements, 1 /* MultiLine */, index === -1 ? statements.length : index); popNameGenerationScope(node); } // Transformation nodes function emitPartiallyEmittedExpression(node) { emitExpression(node.expression); } function emitCommaList(node) { emitExpressionList(node, node.elements, 272 /* CommaListElements */); } /** * Emits any prologue directives at the start of a Statement list, returning the * number of prologue directives written to the output. */ function emitPrologueDirectives(statements, startWithNewLine, seenPrologueDirectives) { for (var i = 0; i < statements.length; i++) { var statement = statements[i]; if (ts.isPrologueDirective(statement)) { var shouldEmitPrologueDirective = seenPrologueDirectives ? !seenPrologueDirectives.has(statement.expression.text) : true; if (shouldEmitPrologueDirective) { if (startWithNewLine || i > 0) { writeLine(); } emit(statement); if (seenPrologueDirectives) { seenPrologueDirectives.set(statement.expression.text, true); } } } else { // return index of the first non prologue directive return i; } } return statements.length; } function emitPrologueDirectivesIfNeeded(sourceFileOrBundle) { if (ts.isSourceFile(sourceFileOrBundle)) { setSourceFile(sourceFileOrBundle); emitPrologueDirectives(sourceFileOrBundle.statements); } else { var seenPrologueDirectives = ts.createMap(); for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) { var sourceFile = _b[_a]; setSourceFile(sourceFile); emitPrologueDirectives(sourceFile.statements, /*startWithNewLine*/ true, seenPrologueDirectives); } } } function emitShebangIfNeeded(sourceFileOrBundle) { if (ts.isSourceFile(sourceFileOrBundle)) { var shebang = ts.getShebang(sourceFileOrBundle.text); if (shebang) { write(shebang); writeLine(); return true; } } else { for (var _a = 0, _b = sourceFileOrBundle.sourceFiles; _a < _b.length; _a++) { var sourceFile = _b[_a]; // Emit only the first encountered shebang if (emitShebangIfNeeded(sourceFile)) { break; } } } } // // Helpers // function emitModifiers(node, modifiers) { if (modifiers && modifiers.length) { emitList(node, modifiers, 131328 /* Modifiers */); write(" "); } } function emitWithPrefix(prefix, node) { emitNodeWithPrefix(prefix, node, emit); } function emitExpressionWithPrefix(prefix, node) { emitNodeWithPrefix(prefix, node, emitExpression); } function emitNodeWithPrefix(prefix, node, emit) { if (node) { write(prefix); emit(node); } } function emitWithSuffix(node, suffix) { if (node) { emit(node); write(suffix); } } function emitEmbeddedStatement(parent, node) { if (ts.isBlock(node) || ts.getEmitFlags(parent) & 1 /* SingleLine */) { write(" "); emit(node); } else { writeLine(); increaseIndent(); emit(node); decreaseIndent(); } } function emitDecorators(parentNode, decorators) { emitList(parentNode, decorators, 24577 /* Decorators */); } function emitTypeArguments(parentNode, typeArguments) { emitList(parentNode, typeArguments, 26960 /* TypeArguments */); } function emitTypeParameters(parentNode, typeParameters) { emitList(parentNode, typeParameters, 26960 /* TypeParameters */); } function emitParameters(parentNode, parameters) { emitList(parentNode, parameters, 1360 /* Parameters */); } function canEmitSimpleArrowHead(parentNode, parameters) { var parameter = ts.singleOrUndefined(parameters); return parameter && parameter.pos === parentNode.pos // may not have parsed tokens between parent and parameter && !(ts.isArrowFunction(parentNode) && parentNode.type) // arrow function may not have return type annotation && !ts.some(parentNode.decorators) // parent may not have decorators && !ts.some(parentNode.modifiers) // parent may not have modifiers && !ts.some(parentNode.typeParameters) // parent may not have type parameters && !ts.some(parameter.decorators) // parameter may not have decorators && !ts.some(parameter.modifiers) // parameter may not have modifiers && !parameter.dotDotDotToken // parameter may not be rest && !parameter.questionToken // parameter may not be optional && !parameter.type // parameter may not have a type annotation && !parameter.initializer // parameter may not have an initializer && ts.isIdentifier(parameter.name); // parameter name must be identifier } function emitParametersForArrow(parentNode, parameters) { if (canEmitSimpleArrowHead(parentNode, parameters)) { emitList(parentNode, parameters, 1360 /* Parameters */ & ~1024 /* Parenthesis */); } else { emitParameters(parentNode, parameters); } } function emitParametersForIndexSignature(parentNode, parameters) { emitList(parentNode, parameters, 4432 /* IndexSignatureParameters */); } function emitList(parentNode, children, format, start, count) { emitNodeList(emit, parentNode, children, format, start, count); } function emitExpressionList(parentNode, children, format, start, count) { emitNodeList(emitExpression, parentNode, children, format, start, count); } function emitNodeList(emit, parentNode, children, format, start, count) { if (start === void 0) { start = 0; } if (count === void 0) { count = children ? children.length - start : 0; } var isUndefined = children === undefined; if (isUndefined && format & 8192 /* OptionalIfUndefined */) { return; } var isEmpty = isUndefined || start >= children.length || count === 0; if (isEmpty && format & 16384 /* OptionalIfEmpty */) { if (onBeforeEmitNodeArray) { onBeforeEmitNodeArray(children); } if (onAfterEmitNodeArray) { onAfterEmitNodeArray(children); } return; } if (format & 7680 /* BracketsMask */) { write(getOpeningBracket(format)); } if (onBeforeEmitNodeArray) { onBeforeEmitNodeArray(children); } if (isEmpty) { // Write a line terminator if the parent node was multi-line if (format & 1 /* MultiLine */) { writeLine(); } else if (format & 128 /* SpaceBetweenBraces */ && !(format & 262144 /* NoSpaceIfEmpty */)) { write(" "); } } else { // Write the opening line terminator or leading whitespace. var mayEmitInterveningComments = (format & 131072 /* NoInterveningComments */) === 0; var shouldEmitInterveningComments = mayEmitInterveningComments; if (shouldWriteLeadingLineTerminator(parentNode, children, format)) { writeLine(); shouldEmitInterveningComments = false; } else if (format & 128 /* SpaceBetweenBraces */) { write(" "); } // Increase the indent, if requested. if (format & 64 /* Indented */) { increaseIndent(); } // Emit each child. var previousSibling = void 0; var shouldDecreaseIndentAfterEmit = void 0; var delimiter = getDelimiter(format); for (var i = 0; i < count; i++) { var child = children[start + i]; // Write the delimiter if this is not the first node. if (previousSibling) { // i.e // function commentedParameters( // /* Parameter a */ // a // /* End of parameter a */ -> this comment isn't considered to be trailing comment of parameter "a" due to newline // , if (delimiter && previousSibling.end !== parentNode.end) { emitLeadingCommentsOfPosition(previousSibling.end); } write(delimiter); // Write either a line terminator or whitespace to separate the elements. if (shouldWriteSeparatingLineTerminator(previousSibling, child, format)) { // If a synthesized node in a single-line list starts on a new // line, we should increase the indent. if ((format & (3 /* LinesMask */ | 64 /* Indented */)) === 0 /* SingleLine */) { increaseIndent(); shouldDecreaseIndentAfterEmit = true; } writeLine(); shouldEmitInterveningComments = false; } else if (previousSibling && format & 256 /* SpaceBetweenSiblings */) { write(" "); } } // Emit this child. if (shouldEmitInterveningComments) { if (emitTrailingCommentsOfPosition) { var commentRange = ts.getCommentRange(child); emitTrailingCommentsOfPosition(commentRange.pos); } } else { shouldEmitInterveningComments = mayEmitInterveningComments; } emit(child); if (shouldDecreaseIndentAfterEmit) { decreaseIndent(); shouldDecreaseIndentAfterEmit = false; } previousSibling = child; } // Write a trailing comma, if requested. var hasTrailingComma = (format & 32 /* AllowTrailingComma */) && children.hasTrailingComma; if (format & 16 /* CommaDelimited */ && hasTrailingComma) { write(","); } // Emit any trailing comment of the last element in the list // i.e // var array = [... // 2 // /* end of element 2 */ // ]; if (previousSibling && delimiter && previousSibling.end !== parentNode.end && !(ts.getEmitFlags(previousSibling) & 1024 /* NoTrailingComments */)) { emitLeadingCommentsOfPosition(previousSibling.end); } // Decrease the indent, if requested. if (format & 64 /* Indented */) { decreaseIndent(); } // Write the closing line terminator or closing whitespace. if (shouldWriteClosingLineTerminator(parentNode, children, format)) { writeLine(); } else if (format & 128 /* SpaceBetweenBraces */) { write(" "); } } if (onAfterEmitNodeArray) { onAfterEmitNodeArray(children); } if (format & 7680 /* BracketsMask */) { write(getClosingBracket(format)); } } function write(s) { writer.write(s); } function writeLine() { writer.writeLine(); } function increaseIndent() { writer.increaseIndent(); } function decreaseIndent() { writer.decreaseIndent(); } function writeToken(token, pos, contextNode) { return onEmitSourceMapOfToken ? onEmitSourceMapOfToken(contextNode, token, pos, writeTokenText) : writeTokenText(token, pos); } function writeTokenNode(node) { if (onBeforeEmitToken) { onBeforeEmitToken(node); } write(ts.tokenToString(node.kind)); if (onAfterEmitToken) { onAfterEmitToken(node); } } function writeTokenText(token, pos) { var tokenString = ts.tokenToString(token); write(tokenString); return pos < 0 ? pos : pos + tokenString.length; } function writeLineOrSpace(node) { if (ts.getEmitFlags(node) & 1 /* SingleLine */) { write(" "); } else { writeLine(); } } function writeLines(text) { var lines = text.split(/\r\n?|\n/g); var indentation = guessIndentation(lines); for (var _a = 0, lines_1 = lines; _a < lines_1.length; _a++) { var lineText = lines_1[_a]; var line = indentation ? lineText.slice(indentation) : lineText; if (line.length) { writeLine(); write(line); writeLine(); } } } function guessIndentation(lines) { var indentation; for (var _a = 0, lines_2 = lines; _a < lines_2.length; _a++) { var line = lines_2[_a]; for (var i = 0; i < line.length && (indentation === undefined || i < indentation); i++) { if (!ts.isWhiteSpaceLike(line.charCodeAt(i))) { if (indentation === undefined || i < indentation) { indentation = i; break; } } } } return indentation; } function increaseIndentIf(value, valueToWriteWhenNotIndenting) { if (value) { increaseIndent(); writeLine(); } else if (valueToWriteWhenNotIndenting) { write(valueToWriteWhenNotIndenting); } } // Helper function to decrease the indent if we previously indented. Allows multiple // previous indent values to be considered at a time. This also allows caller to just // call this once, passing in all their appropriate indent values, instead of needing // to call this helper function multiple times. function decreaseIndentIf(value1, value2) { if (value1) { decreaseIndent(); } if (value2) { decreaseIndent(); } } function shouldWriteLeadingLineTerminator(parentNode, children, format) { if (format & 1 /* MultiLine */) { return true; } if (format & 2 /* PreserveLines */) { if (format & 32768 /* PreferNewLine */) { return true; } var firstChild = children[0]; if (firstChild === undefined) { return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile); } else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(firstChild)) { return synthesizedNodeStartsOnNewLine(firstChild, format); } else { return !ts.rangeStartPositionsAreOnSameLine(parentNode, firstChild, currentSourceFile); } } else { return false; } } function shouldWriteSeparatingLineTerminator(previousNode, nextNode, format) { if (format & 1 /* MultiLine */) { return true; } else if (format & 2 /* PreserveLines */) { if (previousNode === undefined || nextNode === undefined) { return false; } else if (ts.nodeIsSynthesized(previousNode) || ts.nodeIsSynthesized(nextNode)) { return synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format); } else { return !ts.rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile); } } else { return ts.getStartsOnNewLine(nextNode); } } function shouldWriteClosingLineTerminator(parentNode, children, format) { if (format & 1 /* MultiLine */) { return (format & 65536 /* NoTrailingNewLine */) === 0; } else if (format & 2 /* PreserveLines */) { if (format & 32768 /* PreferNewLine */) { return true; } var lastChild = ts.lastOrUndefined(children); if (lastChild === undefined) { return !ts.rangeIsOnSingleLine(parentNode, currentSourceFile); } else if (ts.positionIsSynthesized(parentNode.pos) || ts.nodeIsSynthesized(lastChild)) { return synthesizedNodeStartsOnNewLine(lastChild, format); } else { return !ts.rangeEndPositionsAreOnSameLine(parentNode, lastChild, currentSourceFile); } } else { return false; } } function synthesizedNodeStartsOnNewLine(node, format) { if (ts.nodeIsSynthesized(node)) { var startsOnNewLine = ts.getStartsOnNewLine(node); if (startsOnNewLine === undefined) { return (format & 32768 /* PreferNewLine */) !== 0; } return startsOnNewLine; } return (format & 32768 /* PreferNewLine */) !== 0; } function needsIndentation(parent, node1, node2) { parent = skipSynthesizedParentheses(parent); node1 = skipSynthesizedParentheses(node1); node2 = skipSynthesizedParentheses(node2); // Always use a newline for synthesized code if the synthesizer desires it. if (ts.getStartsOnNewLine(node2)) { return true; } return !ts.nodeIsSynthesized(parent) && !ts.nodeIsSynthesized(node1) && !ts.nodeIsSynthesized(node2) && !ts.rangeEndIsOnSameLineAsRangeStart(node1, node2, currentSourceFile); } function isEmptyBlock(block) { return block.statements.length === 0 && ts.rangeEndIsOnSameLineAsRangeStart(block, block, currentSourceFile); } function skipSynthesizedParentheses(node) { while (node.kind === 186 /* ParenthesizedExpression */ && ts.nodeIsSynthesized(node)) { node = node.expression; } return node; } function getTextOfNode(node, includeTrivia) { if (ts.isGeneratedIdentifier(node)) { return generateName(node); } else if (ts.isIdentifier(node) && (ts.nodeIsSynthesized(node) || !node.parent)) { return ts.idText(node); } else if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) { return getTextOfNode(node.textSourceNode, includeTrivia); } else if (ts.isLiteralExpression(node) && (ts.nodeIsSynthesized(node) || !node.parent)) { return node.text; } return ts.getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia); } function getLiteralTextOfNode(node) { if (node.kind === 9 /* StringLiteral */ && node.textSourceNode) { var textSourceNode = node.textSourceNode; if (ts.isIdentifier(textSourceNode)) { return ts.getEmitFlags(node) & 16777216 /* NoAsciiEscaping */ ? "\"" + ts.escapeString(getTextOfNode(textSourceNode)) + "\"" : "\"" + ts.escapeNonAsciiString(getTextOfNode(textSourceNode)) + "\""; } else { return getLiteralTextOfNode(textSourceNode); } } return ts.getLiteralText(node, currentSourceFile); } /** * Push a new name generation scope. */ function pushNameGenerationScope(node) { if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) { return; } tempFlagsStack.push(tempFlags); tempFlags = 0; } /** * Pop the current name generation scope. */ function popNameGenerationScope(node) { if (node && ts.getEmitFlags(node) & 524288 /* ReuseTempVariableScope */) { return; } tempFlags = tempFlagsStack.pop(); } /** * Generate the text for a generated identifier. */ function generateName(name) { if (name.autoGenerateKind === 4 /* Node */) { // Node names generate unique names based on their original node // and are cached based on that node's id. if (name.skipNameGenerationScope) { var savedTempFlags = tempFlags; popNameGenerationScope(/*node*/ undefined); var result = generateNameCached(getNodeForGeneratedName(name)); pushNameGenerationScope(/*node*/ undefined); tempFlags = savedTempFlags; return result; } else { return generateNameCached(getNodeForGeneratedName(name)); } } else { // Auto, Loop, and Unique names are cached based on their unique // autoGenerateId. var autoGenerateId = name.autoGenerateId; return autoGeneratedIdToGeneratedName[autoGenerateId] || (autoGeneratedIdToGeneratedName[autoGenerateId] = makeName(name)); } } function generateNameCached(node) { var nodeId = ts.getNodeId(node); return nodeIdToGeneratedName[nodeId] || (nodeIdToGeneratedName[nodeId] = generateNameForNode(node)); } /** * Returns a value indicating whether a name is unique globally, within the current file, * or within the NameGenerator. */ function isUniqueName(name) { return !(hasGlobalName && hasGlobalName(name)) && !currentSourceFile.identifiers.has(name) && !generatedNames.has(name); } /** * Returns a value indicating whether a name is unique within a container. */ function isUniqueLocalName(name, container) { for (var node = container; ts.isNodeDescendantOf(node, container); node = node.nextContainer) { if (node.locals) { var local = node.locals.get(ts.escapeLeadingUnderscores(name)); // We conservatively include alias symbols to cover cases where they're emitted as locals if (local && local.flags & (107455 /* Value */ | 1048576 /* ExportValue */ | 2097152 /* Alias */)) { return false; } } } return true; } /** * Return the next available name in the pattern _a ... _z, _0, _1, ... * TempFlags._i or TempFlags._n may be used to express a preference for that dedicated name. * Note that names generated by makeTempVariableName and makeUniqueName will never conflict. */ function makeTempVariableName(flags) { if (flags && !(tempFlags & flags)) { var name = flags === 268435456 /* _i */ ? "_i" : "_n"; if (isUniqueName(name)) { tempFlags |= flags; return name; } } while (true) { var count = tempFlags & 268435455 /* CountMask */; tempFlags++; // Skip over 'i' and 'n' if (count !== 8 && count !== 13) { var name = count < 26 ? "_" + String.fromCharCode(97 /* a */ + count) : "_" + (count - 26); if (isUniqueName(name)) { return name; } } } } /** * Generate a name that is unique within the current file and doesn't conflict with any names * in global scope. The name is formed by adding an '_n' suffix to the specified base name, * where n is a positive integer. Note that names generated by makeTempVariableName and * makeUniqueName are guaranteed to never conflict. */ function makeUniqueName(baseName) { // Find the first unique 'name_n', where n is a positive number if (baseName.charCodeAt(baseName.length - 1) !== 95 /* _ */) { baseName += "_"; } var i = 1; while (true) { var generatedName = baseName + i; if (isUniqueName(generatedName)) { generatedNames.set(generatedName, true); return generatedName; } i++; } } /** * Generates a unique name for a ModuleDeclaration or EnumDeclaration. */ function generateNameForModuleOrEnum(node) { var name = getTextOfNode(node.name); // Use module/enum name itself if it is unique, otherwise make a unique variation return isUniqueLocalName(name, node) ? name : makeUniqueName(name); } /** * Generates a unique name for an ImportDeclaration or ExportDeclaration. */ function generateNameForImportOrExportDeclaration(node) { var expr = ts.getExternalModuleName(node); var baseName = ts.isStringLiteral(expr) ? ts.makeIdentifierFromModuleName(expr.text) : "module"; return makeUniqueName(baseName); } /** * Generates a unique name for a default export. */ function generateNameForExportDefault() { return makeUniqueName("default"); } /** * Generates a unique name for a class expression. */ function generateNameForClassExpression() { return makeUniqueName("class"); } function generateNameForMethodOrAccessor(node) { if (ts.isIdentifier(node.name)) { return generateNameCached(node.name); } return makeTempVariableName(0 /* Auto */); } /** * Generates a unique name from a node. */ function generateNameForNode(node) { switch (node.kind) { case 71 /* Identifier */: return makeUniqueName(getTextOfNode(node)); case 234 /* ModuleDeclaration */: case 233 /* EnumDeclaration */: return generateNameForModuleOrEnum(node); case 239 /* ImportDeclaration */: case 245 /* ExportDeclaration */: return generateNameForImportOrExportDeclaration(node); case 229 /* FunctionDeclaration */: case 230 /* ClassDeclaration */: case 244 /* ExportAssignment */: return generateNameForExportDefault(); case 200 /* ClassExpression */: return generateNameForClassExpression(); case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return generateNameForMethodOrAccessor(node); default: return makeTempVariableName(0 /* Auto */); } } /** * Generates a unique identifier for a node. */ function makeName(name) { switch (name.autoGenerateKind) { case 1 /* Auto */: return makeTempVariableName(0 /* Auto */); case 2 /* Loop */: return makeTempVariableName(268435456 /* _i */); case 3 /* Unique */: return makeUniqueName(ts.idText(name)); } ts.Debug.fail("Unsupported GeneratedIdentifierKind."); } /** * Gets the node from which a name should be generated. */ function getNodeForGeneratedName(name) { var autoGenerateId = name.autoGenerateId; var node = name; var original = node.original; while (original) { node = original; // if "node" is a different generated name (having a different // "autoGenerateId"), use it and stop traversing. if (ts.isIdentifier(node) && node.autoGenerateKind === 4 /* Node */ && node.autoGenerateId !== autoGenerateId) { break; } original = node.original; } // otherwise, return the original node for the source; return node; } } ts.createPrinter = createPrinter; function createDelimiterMap() { var delimiters = []; delimiters[0 /* None */] = ""; delimiters[16 /* CommaDelimited */] = ","; delimiters[4 /* BarDelimited */] = " |"; delimiters[8 /* AmpersandDelimited */] = " &"; return delimiters; } function getDelimiter(format) { return delimiters[format & 28 /* DelimitersMask */]; } function createBracketsMap() { var brackets = []; brackets[512 /* Braces */] = ["{", "}"]; brackets[1024 /* Parenthesis */] = ["(", ")"]; brackets[2048 /* AngleBrackets */] = ["<", ">"]; brackets[4096 /* SquareBrackets */] = ["[", "]"]; return brackets; } function getOpeningBracket(format) { return brackets[format & 7680 /* BracketsMask */][0]; } function getClosingBracket(format) { return brackets[format & 7680 /* BracketsMask */][1]; } // Flags enum to track count of temp variables and a few dedicated names var TempFlags; (function (TempFlags) { TempFlags[TempFlags["Auto"] = 0] = "Auto"; TempFlags[TempFlags["CountMask"] = 268435455] = "CountMask"; TempFlags[TempFlags["_i"] = 268435456] = "_i"; })(TempFlags || (TempFlags = {})); var ListFormat; (function (ListFormat) { ListFormat[ListFormat["None"] = 0] = "None"; // Line separators ListFormat[ListFormat["SingleLine"] = 0] = "SingleLine"; ListFormat[ListFormat["MultiLine"] = 1] = "MultiLine"; ListFormat[ListFormat["PreserveLines"] = 2] = "PreserveLines"; ListFormat[ListFormat["LinesMask"] = 3] = "LinesMask"; // Delimiters ListFormat[ListFormat["NotDelimited"] = 0] = "NotDelimited"; ListFormat[ListFormat["BarDelimited"] = 4] = "BarDelimited"; ListFormat[ListFormat["AmpersandDelimited"] = 8] = "AmpersandDelimited"; ListFormat[ListFormat["CommaDelimited"] = 16] = "CommaDelimited"; ListFormat[ListFormat["DelimitersMask"] = 28] = "DelimitersMask"; ListFormat[ListFormat["AllowTrailingComma"] = 32] = "AllowTrailingComma"; // Whitespace ListFormat[ListFormat["Indented"] = 64] = "Indented"; ListFormat[ListFormat["SpaceBetweenBraces"] = 128] = "SpaceBetweenBraces"; ListFormat[ListFormat["SpaceBetweenSiblings"] = 256] = "SpaceBetweenSiblings"; // Brackets/Braces ListFormat[ListFormat["Braces"] = 512] = "Braces"; ListFormat[ListFormat["Parenthesis"] = 1024] = "Parenthesis"; ListFormat[ListFormat["AngleBrackets"] = 2048] = "AngleBrackets"; ListFormat[ListFormat["SquareBrackets"] = 4096] = "SquareBrackets"; ListFormat[ListFormat["BracketsMask"] = 7680] = "BracketsMask"; ListFormat[ListFormat["OptionalIfUndefined"] = 8192] = "OptionalIfUndefined"; ListFormat[ListFormat["OptionalIfEmpty"] = 16384] = "OptionalIfEmpty"; ListFormat[ListFormat["Optional"] = 24576] = "Optional"; // Other ListFormat[ListFormat["PreferNewLine"] = 32768] = "PreferNewLine"; ListFormat[ListFormat["NoTrailingNewLine"] = 65536] = "NoTrailingNewLine"; ListFormat[ListFormat["NoInterveningComments"] = 131072] = "NoInterveningComments"; ListFormat[ListFormat["NoSpaceIfEmpty"] = 262144] = "NoSpaceIfEmpty"; ListFormat[ListFormat["SingleElement"] = 524288] = "SingleElement"; // Precomputed Formats ListFormat[ListFormat["Modifiers"] = 131328] = "Modifiers"; ListFormat[ListFormat["HeritageClauses"] = 256] = "HeritageClauses"; ListFormat[ListFormat["SingleLineTypeLiteralMembers"] = 448] = "SingleLineTypeLiteralMembers"; ListFormat[ListFormat["MultiLineTypeLiteralMembers"] = 65] = "MultiLineTypeLiteralMembers"; ListFormat[ListFormat["TupleTypeElements"] = 336] = "TupleTypeElements"; ListFormat[ListFormat["UnionTypeConstituents"] = 260] = "UnionTypeConstituents"; ListFormat[ListFormat["IntersectionTypeConstituents"] = 264] = "IntersectionTypeConstituents"; ListFormat[ListFormat["ObjectBindingPatternElements"] = 432] = "ObjectBindingPatternElements"; ListFormat[ListFormat["ArrayBindingPatternElements"] = 304] = "ArrayBindingPatternElements"; ListFormat[ListFormat["ObjectLiteralExpressionProperties"] = 263122] = "ObjectLiteralExpressionProperties"; ListFormat[ListFormat["ArrayLiteralExpressionElements"] = 4466] = "ArrayLiteralExpressionElements"; ListFormat[ListFormat["CommaListElements"] = 272] = "CommaListElements"; ListFormat[ListFormat["CallExpressionArguments"] = 1296] = "CallExpressionArguments"; ListFormat[ListFormat["NewExpressionArguments"] = 9488] = "NewExpressionArguments"; ListFormat[ListFormat["TemplateExpressionSpans"] = 131072] = "TemplateExpressionSpans"; ListFormat[ListFormat["SingleLineBlockStatements"] = 384] = "SingleLineBlockStatements"; ListFormat[ListFormat["MultiLineBlockStatements"] = 65] = "MultiLineBlockStatements"; ListFormat[ListFormat["VariableDeclarationList"] = 272] = "VariableDeclarationList"; ListFormat[ListFormat["SingleLineFunctionBodyStatements"] = 384] = "SingleLineFunctionBodyStatements"; ListFormat[ListFormat["MultiLineFunctionBodyStatements"] = 1] = "MultiLineFunctionBodyStatements"; ListFormat[ListFormat["ClassHeritageClauses"] = 256] = "ClassHeritageClauses"; ListFormat[ListFormat["ClassMembers"] = 65] = "ClassMembers"; ListFormat[ListFormat["InterfaceMembers"] = 65] = "InterfaceMembers"; ListFormat[ListFormat["EnumMembers"] = 81] = "EnumMembers"; ListFormat[ListFormat["CaseBlockClauses"] = 65] = "CaseBlockClauses"; ListFormat[ListFormat["NamedImportsOrExportsElements"] = 432] = "NamedImportsOrExportsElements"; ListFormat[ListFormat["JsxElementOrFragmentChildren"] = 131072] = "JsxElementOrFragmentChildren"; ListFormat[ListFormat["JsxElementAttributes"] = 131328] = "JsxElementAttributes"; ListFormat[ListFormat["CaseOrDefaultClauseStatements"] = 81985] = "CaseOrDefaultClauseStatements"; ListFormat[ListFormat["HeritageClauseTypes"] = 272] = "HeritageClauseTypes"; ListFormat[ListFormat["SourceFileStatements"] = 65537] = "SourceFileStatements"; ListFormat[ListFormat["Decorators"] = 24577] = "Decorators"; ListFormat[ListFormat["TypeArguments"] = 26960] = "TypeArguments"; ListFormat[ListFormat["TypeParameters"] = 26960] = "TypeParameters"; ListFormat[ListFormat["Parameters"] = 1360] = "Parameters"; ListFormat[ListFormat["IndexSignatureParameters"] = 4432] = "IndexSignatureParameters"; })(ListFormat || (ListFormat = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { function getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers) { var outputFiles = []; var emitResult = program.emit(sourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers); return { outputFiles: outputFiles, emitSkipped: emitResult.emitSkipped }; function writeFile(fileName, text, writeByteOrderMark) { outputFiles.push({ name: fileName, writeByteOrderMark: writeByteOrderMark, text: text }); } } ts.getFileEmitOutput = getFileEmitOutput; function createBuilder(options) { var isModuleEmit; var fileInfos = ts.createMap(); var semanticDiagnosticsPerFile = ts.createMap(); /** The map has key by source file's path that has been changed */ var changedFilesSet = ts.createMap(); var hasShapeChanged = ts.createMap(); var allFilesExcludingDefaultLibraryFile; var emitHandler; return { updateProgram: updateProgram, getFilesAffectedBy: getFilesAffectedBy, emitChangedFiles: emitChangedFiles, getSemanticDiagnostics: getSemanticDiagnostics, clear: clear }; function createProgramGraph(program) { var currentIsModuleEmit = program.getCompilerOptions().module !== ts.ModuleKind.None; if (isModuleEmit !== currentIsModuleEmit) { isModuleEmit = currentIsModuleEmit; emitHandler = isModuleEmit ? getModuleEmitHandler() : getNonModuleEmitHandler(); fileInfos.clear(); semanticDiagnosticsPerFile.clear(); } hasShapeChanged.clear(); allFilesExcludingDefaultLibraryFile = undefined; ts.mutateMap(fileInfos, ts.arrayToMap(program.getSourceFiles(), function (sourceFile) { return sourceFile.path; }), { // Add new file info createNewValue: function (_path, sourceFile) { return addNewFileInfo(program, sourceFile); }, // Remove existing file info onDeleteValue: removeExistingFileInfo, // We will update in place instead of deleting existing value and adding new one onExistingValue: function (existingInfo, sourceFile) { return updateExistingFileInfo(program, existingInfo, sourceFile); } }); } function registerChangedFile(path) { changedFilesSet.set(path, true); // All changed files need to re-evaluate its semantic diagnostics semanticDiagnosticsPerFile.delete(path); } function addNewFileInfo(program, sourceFile) { registerChangedFile(sourceFile.path); emitHandler.onAddSourceFile(program, sourceFile); return { version: sourceFile.version, signature: undefined }; } function removeExistingFileInfo(_existingFileInfo, path) { // Since we dont need to track removed file as changed file // We can just remove its diagnostics changedFilesSet.delete(path); semanticDiagnosticsPerFile.delete(path); emitHandler.onRemoveSourceFile(path); } function updateExistingFileInfo(program, existingInfo, sourceFile) { if (existingInfo.version !== sourceFile.version) { registerChangedFile(sourceFile.path); existingInfo.version = sourceFile.version; emitHandler.onUpdateSourceFile(program, sourceFile); } else if (emitHandler.onUpdateSourceFileWithSameVersion(program, sourceFile)) { registerChangedFile(sourceFile.path); } } function ensureProgramGraph(program) { if (!emitHandler) { createProgramGraph(program); } } function updateProgram(newProgram) { if (emitHandler) { createProgramGraph(newProgram); } } function getFilesAffectedBy(program, path) { ensureProgramGraph(program); var sourceFile = program.getSourceFileByPath(path); if (!sourceFile) { return ts.emptyArray; } if (!updateShapeSignature(program, sourceFile)) { return [sourceFile]; } return emitHandler.getFilesAffectedByUpdatedShape(program, sourceFile); } function emitChangedFiles(program, writeFileCallback) { ensureProgramGraph(program); var compilerOptions = program.getCompilerOptions(); if (!changedFilesSet.size) { return ts.emptyArray; } // With --out or --outFile all outputs go into single file, do it only once if (compilerOptions.outFile || compilerOptions.out) { ts.Debug.assert(semanticDiagnosticsPerFile.size === 0); changedFilesSet.clear(); return [program.emit(/*targetSourceFile*/ undefined, writeFileCallback)]; } var seenFiles = ts.createMap(); var result; changedFilesSet.forEach(function (_true, path) { // Get the affected Files by this program var affectedFiles = getFilesAffectedBy(program, path); affectedFiles.forEach(function (affectedFile) { // Affected files shouldnt have cached diagnostics semanticDiagnosticsPerFile.delete(affectedFile.path); if (!seenFiles.has(affectedFile.path)) { seenFiles.set(affectedFile.path, true); // Emit the affected file (result || (result = [])).push(program.emit(affectedFile, writeFileCallback)); } }); }); changedFilesSet.clear(); return result || ts.emptyArray; } function getSemanticDiagnostics(program, cancellationToken) { ensureProgramGraph(program); ts.Debug.assert(changedFilesSet.size === 0); var compilerOptions = program.getCompilerOptions(); if (compilerOptions.outFile || compilerOptions.out) { ts.Debug.assert(semanticDiagnosticsPerFile.size === 0); // We dont need to cache the diagnostics just return them from program return program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken); } var diagnostics; for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; diagnostics = ts.addRange(diagnostics, getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken)); } return diagnostics || ts.emptyArray; } function getSemanticDiagnosticsOfFile(program, sourceFile, cancellationToken) { var path = sourceFile.path; var cachedDiagnostics = semanticDiagnosticsPerFile.get(path); // Report the semantic diagnostics from the cache if we already have those diagnostics present if (cachedDiagnostics) { return cachedDiagnostics; } // Diagnostics werent cached, get them from program, and cache the result var diagnostics = program.getSemanticDiagnostics(sourceFile, cancellationToken); semanticDiagnosticsPerFile.set(path, diagnostics); return diagnostics; } function clear() { isModuleEmit = undefined; emitHandler = undefined; fileInfos.clear(); semanticDiagnosticsPerFile.clear(); changedFilesSet.clear(); hasShapeChanged.clear(); } /** * For script files that contains only ambient external modules, although they are not actually external module files, * they can only be consumed via importing elements from them. Regular script files cannot consume them. Therefore, * there are no point to rebuild all script files if these special files have changed. However, if any statement * in the file is not ambient external module, we treat it as a regular script file. */ function containsOnlyAmbientModules(sourceFile) { for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) { var statement = _a[_i]; if (!ts.isModuleWithStringLiteralName(statement)) { return false; } } return true; } /** * @return {boolean} indicates if the shape signature has changed since last update. */ function updateShapeSignature(program, sourceFile) { ts.Debug.assert(!!sourceFile); // If we have cached the result for this file, that means hence forth we should assume file shape is uptodate if (hasShapeChanged.has(sourceFile.path)) { return false; } hasShapeChanged.set(sourceFile.path, true); var info = fileInfos.get(sourceFile.path); ts.Debug.assert(!!info); var prevSignature = info.signature; var latestSignature; if (sourceFile.isDeclarationFile) { latestSignature = sourceFile.version; info.signature = latestSignature; } else { var emitOutput = getFileEmitOutput(program, sourceFile, /*emitOnlyDtsFiles*/ true); if (emitOutput.outputFiles && emitOutput.outputFiles.length > 0) { latestSignature = options.computeHash(emitOutput.outputFiles[0].text); info.signature = latestSignature; } else { latestSignature = prevSignature; } } return !prevSignature || latestSignature !== prevSignature; } /** * Gets the referenced files for a file from the program with values for the keys as referenced file's path to be true */ function getReferencedFiles(program, sourceFile) { var referencedFiles; // We need to use a set here since the code can contain the same import twice, // but that will only be one dependency. // To avoid invernal conversion, the key of the referencedFiles map must be of type Path if (sourceFile.imports && sourceFile.imports.length > 0) { var checker = program.getTypeChecker(); for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) { var importName = _a[_i]; var symbol = checker.getSymbolAtLocation(importName); if (symbol && symbol.declarations && symbol.declarations[0]) { var declarationSourceFile = ts.getSourceFileOfNode(symbol.declarations[0]); if (declarationSourceFile) { addReferencedFile(declarationSourceFile.path); } } } } var sourceFileDirectory = ts.getDirectoryPath(sourceFile.path); // Handle triple slash references if (sourceFile.referencedFiles && sourceFile.referencedFiles.length > 0) { for (var _b = 0, _c = sourceFile.referencedFiles; _b < _c.length; _b++) { var referencedFile = _c[_b]; var referencedPath = ts.toPath(referencedFile.fileName, sourceFileDirectory, options.getCanonicalFileName); addReferencedFile(referencedPath); } } // Handle type reference directives if (sourceFile.resolvedTypeReferenceDirectiveNames) { sourceFile.resolvedTypeReferenceDirectiveNames.forEach(function (resolvedTypeReferenceDirective) { if (!resolvedTypeReferenceDirective) { return; } var fileName = resolvedTypeReferenceDirective.resolvedFileName; var typeFilePath = ts.toPath(fileName, sourceFileDirectory, options.getCanonicalFileName); addReferencedFile(typeFilePath); }); } return referencedFiles; function addReferencedFile(referencedPath) { if (!referencedFiles) { referencedFiles = ts.createMap(); } referencedFiles.set(referencedPath, true); } } /** * Gets all files of the program excluding the default library file */ function getAllFilesExcludingDefaultLibraryFile(program, firstSourceFile) { // Use cached result if (allFilesExcludingDefaultLibraryFile) { return allFilesExcludingDefaultLibraryFile; } var result; addSourceFile(firstSourceFile); for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; if (sourceFile !== firstSourceFile) { addSourceFile(sourceFile); } } allFilesExcludingDefaultLibraryFile = result || ts.emptyArray; return allFilesExcludingDefaultLibraryFile; function addSourceFile(sourceFile) { if (!program.isSourceFileDefaultLibrary(sourceFile)) { (result || (result = [])).push(sourceFile); } } } function getNonModuleEmitHandler() { return { onAddSourceFile: ts.noop, onRemoveSourceFile: ts.noop, onUpdateSourceFile: ts.noop, onUpdateSourceFileWithSameVersion: ts.returnFalse, getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape }; function getFilesAffectedByUpdatedShape(program, sourceFile) { var options = program.getCompilerOptions(); // If `--out` or `--outFile` is specified, any new emit will result in re-emitting the entire project, // so returning the file itself is good enough. if (options && (options.out || options.outFile)) { return [sourceFile]; } return getAllFilesExcludingDefaultLibraryFile(program, sourceFile); } } function getModuleEmitHandler() { var references = ts.createMap(); return { onAddSourceFile: setReferences, onRemoveSourceFile: onRemoveSourceFile, onUpdateSourceFile: updateReferences, onUpdateSourceFileWithSameVersion: updateReferencesTrackingChangedReferences, getFilesAffectedByUpdatedShape: getFilesAffectedByUpdatedShape }; function setReferences(program, sourceFile) { var newReferences = getReferencedFiles(program, sourceFile); if (newReferences) { references.set(sourceFile.path, newReferences); } } function updateReferences(program, sourceFile) { var newReferences = getReferencedFiles(program, sourceFile); if (newReferences) { references.set(sourceFile.path, newReferences); } else { references.delete(sourceFile.path); } } function updateReferencesTrackingChangedReferences(program, sourceFile) { var newReferences = getReferencedFiles(program, sourceFile); if (!newReferences) { // Changed if we had references return references.delete(sourceFile.path); } var oldReferences = references.get(sourceFile.path); references.set(sourceFile.path, newReferences); if (!oldReferences || oldReferences.size !== newReferences.size) { return true; } // If there are any new references that werent present previously there is change return ts.forEachEntry(newReferences, function (_true, referencedPath) { return !oldReferences.delete(referencedPath); }) || // Otherwise its changed if there are more references previously than now !!oldReferences.size; } function onRemoveSourceFile(removedFilePath) { // Remove existing references references.forEach(function (referencesInFile, filePath) { if (referencesInFile.has(removedFilePath)) { // add files referencing the removedFilePath, as changed files too var referencedByInfo = fileInfos.get(filePath); if (referencedByInfo) { registerChangedFile(filePath); } } }); // Delete the entry for the removed file path references.delete(removedFilePath); } function getReferencedByPaths(referencedFilePath) { return ts.mapDefinedIter(references.entries(), function (_a) { var filePath = _a[0], referencesInFile = _a[1]; return referencesInFile.has(referencedFilePath) ? filePath : undefined; }); } function getFilesAffectedByUpdatedShape(program, sourceFile) { if (!ts.isExternalModule(sourceFile) && !containsOnlyAmbientModules(sourceFile)) { return getAllFilesExcludingDefaultLibraryFile(program, sourceFile); } var compilerOptions = program.getCompilerOptions(); if (compilerOptions && (compilerOptions.isolatedModules || compilerOptions.out || compilerOptions.outFile)) { return [sourceFile]; } // Now we need to if each file in the referencedBy list has a shape change as well. // Because if so, its own referencedBy files need to be saved as well to make the // emitting result consistent with files on disk. var seenFileNamesMap = ts.createMap(); // Start with the paths this file was referenced by var path = sourceFile.path; seenFileNamesMap.set(path, sourceFile); var queue = getReferencedByPaths(path); while (queue.length > 0) { var currentPath = queue.pop(); if (!seenFileNamesMap.has(currentPath)) { var currentSourceFile = program.getSourceFileByPath(currentPath); seenFileNamesMap.set(currentPath, currentSourceFile); if (currentSourceFile && updateShapeSignature(program, currentSourceFile)) { queue.push.apply(queue, getReferencedByPaths(currentPath)); } } } // Return array of values that needs emit return ts.flatMapIter(seenFileNamesMap.values(), function (value) { return value; }); } } } ts.createBuilder = createBuilder; })(ts || (ts = {})); /// /// /// /// var ts; (function (ts) { var ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/; function findConfigFile(searchPath, fileExists, configName) { if (configName === void 0) { configName = "tsconfig.json"; } return ts.forEachAncestorDirectory(searchPath, function (ancestor) { var fileName = ts.combinePaths(ancestor, configName); return fileExists(fileName) ? fileName : undefined; }); } ts.findConfigFile = findConfigFile; function resolveTripleslashReference(moduleName, containingFile) { var basePath = ts.getDirectoryPath(containingFile); var referencedFileName = ts.isRootedDiskPath(moduleName) ? moduleName : ts.combinePaths(basePath, moduleName); return ts.normalizePath(referencedFileName); } ts.resolveTripleslashReference = resolveTripleslashReference; /* @internal */ function computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName) { var commonPathComponents; var failed = ts.forEach(fileNames, function (sourceFile) { // Each file contributes into common source file path var sourcePathComponents = ts.getNormalizedPathComponents(sourceFile, currentDirectory); sourcePathComponents.pop(); // The base file name is not part of the common directory path if (!commonPathComponents) { // first file commonPathComponents = sourcePathComponents; return; } var n = Math.min(commonPathComponents.length, sourcePathComponents.length); for (var i = 0; i < n; i++) { if (getCanonicalFileName(commonPathComponents[i]) !== getCanonicalFileName(sourcePathComponents[i])) { if (i === 0) { // Failed to find any common path component return true; } // New common path found that is 0 -> i-1 commonPathComponents.length = i; break; } } // If the sourcePathComponents was shorter than the commonPathComponents, truncate to the sourcePathComponents if (sourcePathComponents.length < commonPathComponents.length) { commonPathComponents.length = sourcePathComponents.length; } }); // A common path can not be found when paths span multiple drives on windows, for example if (failed) { return ""; } if (!commonPathComponents) { return currentDirectory; } return ts.getNormalizedPathFromPathComponents(commonPathComponents); } ts.computeCommonSourceDirectoryOfFilenames = computeCommonSourceDirectoryOfFilenames; function createCompilerHost(options, setParentNodes) { var existingDirectories = ts.createMap(); function getCanonicalFileName(fileName) { // if underlying system can distinguish between two files whose names differs only in cases then file name already in canonical form. // otherwise use toLowerCase as a canonical form. return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); } function getSourceFile(fileName, languageVersion, onError) { var text; try { ts.performance.mark("beforeIORead"); text = ts.sys.readFile(fileName, options.charset); ts.performance.mark("afterIORead"); ts.performance.measure("I/O Read", "beforeIORead", "afterIORead"); } catch (e) { if (onError) { onError(e.message); } text = ""; } return text !== undefined ? ts.createSourceFile(fileName, text, languageVersion, setParentNodes) : undefined; } function directoryExists(directoryPath) { if (existingDirectories.has(directoryPath)) { return true; } if (ts.sys.directoryExists(directoryPath)) { existingDirectories.set(directoryPath, true); return true; } return false; } function ensureDirectoriesExist(directoryPath) { if (directoryPath.length > ts.getRootLength(directoryPath) && !directoryExists(directoryPath)) { var parentDirectory = ts.getDirectoryPath(directoryPath); ensureDirectoriesExist(parentDirectory); ts.sys.createDirectory(directoryPath); } } var outputFingerprints; function writeFileIfUpdated(fileName, data, writeByteOrderMark) { if (!outputFingerprints) { outputFingerprints = ts.createMap(); } var hash = ts.sys.createHash(data); var mtimeBefore = ts.sys.getModifiedTime(fileName); if (mtimeBefore) { var fingerprint = outputFingerprints.get(fileName); // If output has not been changed, and the file has no external modification if (fingerprint && fingerprint.byteOrderMark === writeByteOrderMark && fingerprint.hash === hash && fingerprint.mtime.getTime() === mtimeBefore.getTime()) { return; } } ts.sys.writeFile(fileName, data, writeByteOrderMark); var mtimeAfter = ts.sys.getModifiedTime(fileName); outputFingerprints.set(fileName, { hash: hash, byteOrderMark: writeByteOrderMark, mtime: mtimeAfter }); } function writeFile(fileName, data, writeByteOrderMark, onError) { try { ts.performance.mark("beforeIOWrite"); ensureDirectoriesExist(ts.getDirectoryPath(ts.normalizePath(fileName))); if (ts.isWatchSet(options) && ts.sys.createHash && ts.sys.getModifiedTime) { writeFileIfUpdated(fileName, data, writeByteOrderMark); } else { ts.sys.writeFile(fileName, data, writeByteOrderMark); } ts.performance.mark("afterIOWrite"); ts.performance.measure("I/O Write", "beforeIOWrite", "afterIOWrite"); } catch (e) { if (onError) { onError(e.message); } } } function getDefaultLibLocation() { return ts.getDirectoryPath(ts.normalizePath(ts.sys.getExecutingFilePath())); } var newLine = ts.getNewLineCharacter(options); var realpath = ts.sys.realpath && (function (path) { return ts.sys.realpath(path); }); return { getSourceFile: getSourceFile, getDefaultLibLocation: getDefaultLibLocation, getDefaultLibFileName: function (options) { return ts.combinePaths(getDefaultLibLocation(), ts.getDefaultLibFileName(options)); }, writeFile: writeFile, getCurrentDirectory: ts.memoize(function () { return ts.sys.getCurrentDirectory(); }), useCaseSensitiveFileNames: function () { return ts.sys.useCaseSensitiveFileNames; }, getCanonicalFileName: getCanonicalFileName, getNewLine: function () { return newLine; }, fileExists: function (fileName) { return ts.sys.fileExists(fileName); }, readFile: function (fileName) { return ts.sys.readFile(fileName); }, trace: function (s) { return ts.sys.write(s + newLine); }, directoryExists: function (directoryName) { return ts.sys.directoryExists(directoryName); }, getEnvironmentVariable: function (name) { return ts.sys.getEnvironmentVariable ? ts.sys.getEnvironmentVariable(name) : ""; }, getDirectories: function (path) { return ts.sys.getDirectories(path); }, realpath: realpath }; } ts.createCompilerHost = createCompilerHost; function getPreEmitDiagnostics(program, sourceFile, cancellationToken) { var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken)); if (program.getCompilerOptions().declaration) { ts.addRange(diagnostics, program.getDeclarationDiagnostics(sourceFile, cancellationToken)); } return ts.sortAndDeduplicateDiagnostics(diagnostics); } ts.getPreEmitDiagnostics = getPreEmitDiagnostics; function formatDiagnostics(diagnostics, host) { var output = ""; for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { var diagnostic = diagnostics_1[_i]; output += formatDiagnostic(diagnostic, host); } return output; } ts.formatDiagnostics = formatDiagnostics; function formatDiagnostic(diagnostic, host) { var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); var errorMessage = category + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) + host.getNewLine(); if (diagnostic.file) { var _a = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start), line = _a.line, character = _a.character; var fileName = diagnostic.file.fileName; var relativeFileName = ts.convertToRelativePath(fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }); return relativeFileName + "(" + (line + 1) + "," + (character + 1) + "): " + errorMessage; } return errorMessage; } ts.formatDiagnostic = formatDiagnostic; var redForegroundEscapeSequence = "\u001b[91m"; var yellowForegroundEscapeSequence = "\u001b[93m"; var blueForegroundEscapeSequence = "\u001b[93m"; var gutterStyleSequence = "\u001b[30;47m"; var gutterSeparator = " "; var resetEscapeSequence = "\u001b[0m"; var ellipsis = "..."; function getCategoryFormat(category) { switch (category) { case ts.DiagnosticCategory.Warning: return yellowForegroundEscapeSequence; case ts.DiagnosticCategory.Error: return redForegroundEscapeSequence; case ts.DiagnosticCategory.Message: return blueForegroundEscapeSequence; } } function formatAndReset(text, formatStyle) { return formatStyle + text + resetEscapeSequence; } function padLeft(s, length) { while (s.length < length) { s = " " + s; } return s; } function formatDiagnosticsWithColorAndContext(diagnostics, host) { var output = ""; for (var _i = 0, diagnostics_2 = diagnostics; _i < diagnostics_2.length; _i++) { var diagnostic = diagnostics_2[_i]; var context = ""; if (diagnostic.file) { var start = diagnostic.start, length_5 = diagnostic.length, file = diagnostic.file; var _a = ts.getLineAndCharacterOfPosition(file, start), firstLine = _a.line, firstLineChar = _a.character; var _b = ts.getLineAndCharacterOfPosition(file, start + length_5), lastLine = _b.line, lastLineChar = _b.character; var lastLineInFile = ts.getLineAndCharacterOfPosition(file, file.text.length).line; var relativeFileName = host ? ts.convertToRelativePath(file.fileName, host.getCurrentDirectory(), function (fileName) { return host.getCanonicalFileName(fileName); }) : file.fileName; var hasMoreThanFiveLines = (lastLine - firstLine) >= 4; var gutterWidth = (lastLine + 1 + "").length; if (hasMoreThanFiveLines) { gutterWidth = Math.max(ellipsis.length, gutterWidth); } context += host.getNewLine(); for (var i = firstLine; i <= lastLine; i++) { // If the error spans over 5 lines, we'll only show the first 2 and last 2 lines, // so we'll skip ahead to the second-to-last line. if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) { context += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine(); i = lastLine - 1; } var lineStart = ts.getPositionOfLineAndCharacter(file, i, 0); var lineEnd = i < lastLineInFile ? ts.getPositionOfLineAndCharacter(file, i + 1, 0) : file.text.length; var lineContent = file.text.slice(lineStart, lineEnd); lineContent = lineContent.replace(/\s+$/g, ""); // trim from end lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces // Output the gutter and the actual contents of the line. context += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator; context += lineContent + host.getNewLine(); // Output the gutter and the error span for the line using tildes. context += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator; context += redForegroundEscapeSequence; if (i === firstLine) { // If we're on the last line, then limit it to the last character of the last line. // Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position. var lastCharForLine = i === lastLine ? lastLineChar : undefined; context += lineContent.slice(0, firstLineChar).replace(/\S/g, " "); context += lineContent.slice(firstLineChar, lastCharForLine).replace(/./g, "~"); } else if (i === lastLine) { context += lineContent.slice(0, lastLineChar).replace(/./g, "~"); } else { // Squiggle the entire line. context += lineContent.replace(/./g, "~"); } context += resetEscapeSequence; } output += host.getNewLine(); output += relativeFileName + "(" + (firstLine + 1) + "," + (firstLineChar + 1) + "): "; } var categoryColor = getCategoryFormat(diagnostic.category); var category = ts.DiagnosticCategory[diagnostic.category].toLowerCase(); output += formatAndReset(category, categoryColor) + " TS" + diagnostic.code + ": " + flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()); if (diagnostic.file) { output += host.getNewLine(); output += context; } output += host.getNewLine(); } return output; } ts.formatDiagnosticsWithColorAndContext = formatDiagnosticsWithColorAndContext; function flattenDiagnosticMessageText(messageText, newLine) { if (ts.isString(messageText)) { return messageText; } else { var diagnosticChain = messageText; var result = ""; var indent = 0; while (diagnosticChain) { if (indent) { result += newLine; for (var i = 0; i < indent; i++) { result += " "; } } result += diagnosticChain.messageText; indent++; diagnosticChain = diagnosticChain.next; } return result; } } ts.flattenDiagnosticMessageText = flattenDiagnosticMessageText; function loadWithLocalCache(names, containingFile, loader) { if (names.length === 0) { return []; } var resolutions = []; var cache = ts.createMap(); for (var _i = 0, names_1 = names; _i < names_1.length; _i++) { var name = names_1[_i]; var result = void 0; if (cache.has(name)) { result = cache.get(name); } else { cache.set(name, result = loader(name, containingFile)); } resolutions.push(result); } return resolutions; } /** * Determines if program structure is upto date or needs to be recreated */ /* @internal */ function isProgramUptoDate(program, rootFileNames, newOptions, getSourceVersion, fileExists, hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames) { // If we haven't create a program yet or has changed automatic type directives, then it is not up-to-date if (!program || hasChangedAutomaticTypeDirectiveNames) { return false; } // If number of files in the program do not match, it is not up-to-date if (program.getRootFileNames().length !== rootFileNames.length) { return false; } // If any file is not up-to-date, then the whole program is not up-to-date if (program.getSourceFiles().some(sourceFileNotUptoDate)) { return false; } // If any of the missing file paths are now created if (program.getMissingFilePaths().some(fileExists)) { return false; } var currentOptions = program.getCompilerOptions(); // If the compilation settings do no match, then the program is not up-to-date if (!ts.compareDataObjects(currentOptions, newOptions)) { return false; } // If everything matches but the text of config file is changed, // error locations can change for program options, so update the program if (currentOptions.configFile && newOptions.configFile) { return currentOptions.configFile.text === newOptions.configFile.text; } return true; function sourceFileNotUptoDate(sourceFile) { return sourceFile.version !== getSourceVersion(sourceFile.path) || hasInvalidatedResolution(sourceFile.path); } } ts.isProgramUptoDate = isProgramUptoDate; /** * Determined if source file needs to be re-created even if its text hasnt changed */ function shouldProgramCreateNewSourceFiles(program, newOptions) { // If any of these options change, we cant reuse old source file even if version match // The change in options like these could result in change in syntax tree change var oldOptions = program && program.getCompilerOptions(); return oldOptions && (oldOptions.target !== newOptions.target || oldOptions.module !== newOptions.module || oldOptions.moduleResolution !== newOptions.moduleResolution || oldOptions.noResolve !== newOptions.noResolve || oldOptions.jsx !== newOptions.jsx || oldOptions.allowJs !== newOptions.allowJs || oldOptions.disableSizeLimit !== newOptions.disableSizeLimit || oldOptions.baseUrl !== newOptions.baseUrl || !ts.equalOwnProperties(oldOptions.paths, newOptions.paths)); } /** * Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions' * that represent a compilation unit. * * Creating a program proceeds from a set of root files, expanding the set of inputs by following imports and * triple-slash-reference-path directives transitively. '@types' and triple-slash-reference-types are also pulled in. * * @param rootNames - A set of root files. * @param options - The compiler options which should be used. * @param host - The host interacts with the underlying file system. * @param oldProgram - Reuses an old program structure. * @returns A 'Program' object. */ function createProgram(rootNames, options, host, oldProgram) { var program; var files = []; var commonSourceDirectory; var diagnosticsProducingTypeChecker; var noDiagnosticsTypeChecker; var classifiableNames; var modifiedFilePaths; var cachedSemanticDiagnosticsForFile = {}; var cachedDeclarationDiagnosticsForFile = {}; var resolvedTypeReferenceDirectives = ts.createMap(); var fileProcessingDiagnostics = ts.createDiagnosticCollection(); // The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules. // This works as imported modules are discovered recursively in a depth first manner, specifically: // - For each root file, findSourceFile is called. // - This calls processImportedModules for each module imported in the source file. // - This calls resolveModuleNames, and then calls findSourceFile for each resolved module. // As all these operations happen - and are nested - within the createProgram call, they close over the below variables. // The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses. var maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0; var currentNodeModulesDepth = 0; // If a module has some of its imports skipped due to being at the depth limit under node_modules, then track // this, as it may be imported at a shallower depth later, and then it will need its skipped imports processed. var modulesWithElidedImports = ts.createMap(); // Track source files that are source files found by searching under node_modules, as these shouldn't be compiled. var sourceFilesFoundSearchingNodeModules = ts.createMap(); ts.performance.mark("beforeProgram"); host = host || createCompilerHost(options); var skipDefaultLib = options.noLib; var getDefaultLibraryFileName = ts.memoize(function () { return host.getDefaultLibFileName(options); }); var defaultLibraryPath = host.getDefaultLibLocation ? host.getDefaultLibLocation() : ts.getDirectoryPath(getDefaultLibraryFileName()); var programDiagnostics = ts.createDiagnosticCollection(); var currentDirectory = host.getCurrentDirectory(); var supportedExtensions = ts.getSupportedExtensions(options); // Map storing if there is emit blocking diagnostics for given input var hasEmitBlockingDiagnostics = ts.createMap(); var _compilerOptionsObjectLiteralSyntax; var moduleResolutionCache; var resolveModuleNamesWorker; var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse; if (host.resolveModuleNames) { resolveModuleNamesWorker = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(checkAllDefined(moduleNames), containingFile, reusedNames).map(function (resolved) { // An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName. if (!resolved || resolved.extension !== undefined) { return resolved; } var withExtension = ts.clone(resolved); withExtension.extension = ts.extensionFromPath(resolved.resolvedFileName); return withExtension; }); }; } else { moduleResolutionCache = ts.createModuleResolutionCache(currentDirectory, function (x) { return host.getCanonicalFileName(x); }); var loader_1 = function (moduleName, containingFile) { return ts.resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule; }; resolveModuleNamesWorker = function (moduleNames, containingFile) { return loadWithLocalCache(checkAllDefined(moduleNames), containingFile, loader_1); }; } var resolveTypeReferenceDirectiveNamesWorker; if (host.resolveTypeReferenceDirectives) { resolveTypeReferenceDirectiveNamesWorker = function (typeDirectiveNames, containingFile) { return host.resolveTypeReferenceDirectives(checkAllDefined(typeDirectiveNames), containingFile); }; } else { var loader_2 = function (typesRef, containingFile) { return ts.resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective; }; resolveTypeReferenceDirectiveNamesWorker = function (typeReferenceDirectiveNames, containingFile) { return loadWithLocalCache(checkAllDefined(typeReferenceDirectiveNames), containingFile, loader_2); }; } // Map from a stringified PackageId to the source file with that id. // Only one source file may have a given packageId. Others become redirects (see createRedirectSourceFile). // `packageIdToSourceFile` is only used while building the program, while `sourceFileToPackageName` and `isSourceFileTargetOfRedirect` are kept around. var packageIdToSourceFile = ts.createMap(); // Maps from a SourceFile's `.path` to the name of the package it was imported with. var sourceFileToPackageName = ts.createMap(); // See `sourceFileIsRedirectedTo`. var redirectTargetsSet = ts.createMap(); var filesByName = ts.createMap(); var missingFilePaths; // stores 'filename -> file association' ignoring case // used to track cases when two file names differ only in casing var filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? ts.createMap() : undefined; var shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options); var structuralIsReused = tryReuseStructureFromOldProgram(); if (structuralIsReused !== 2 /* Completely */) { ts.forEach(rootNames, function (name) { return processRootFile(name, /*isDefaultLib*/ false); }); // load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders var typeReferences = ts.getAutomaticTypeDirectiveNames(options, host); if (typeReferences.length) { // This containingFilename needs to match with the one used in managed-side var containingDirectory = options.configFilePath ? ts.getDirectoryPath(options.configFilePath) : host.getCurrentDirectory(); var containingFilename = ts.combinePaths(containingDirectory, "__inferred type names__.ts"); var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeReferences, containingFilename); for (var i = 0; i < typeReferences.length; i++) { processTypeReferenceDirective(typeReferences[i], resolutions[i]); } } // Do not process the default library if: // - The '--noLib' flag is used. // - A 'no-default-lib' reference comment is encountered in // processing the root files. if (!skipDefaultLib) { // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file if (!options.lib) { processRootFile(getDefaultLibraryFileName(), /*isDefaultLib*/ true); } else { ts.forEach(options.lib, function (libFileName) { processRootFile(ts.combinePaths(defaultLibraryPath, libFileName), /*isDefaultLib*/ true); }); } } missingFilePaths = ts.arrayFrom(filesByName.keys(), function (p) { return p; }).filter(function (p) { return !filesByName.get(p); }); } ts.Debug.assert(!!missingFilePaths); // unconditionally set moduleResolutionCache to undefined to avoid unnecessary leaks moduleResolutionCache = undefined; // Release any files we have acquired in the old program but are // not part of the new program. if (oldProgram && host.onReleaseOldSourceFile) { var oldSourceFiles = oldProgram.getSourceFiles(); for (var _i = 0, oldSourceFiles_1 = oldSourceFiles; _i < oldSourceFiles_1.length; _i++) { var oldSourceFile = oldSourceFiles_1[_i]; if (!getSourceFile(oldSourceFile.path) || shouldCreateNewSourceFile) { host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions()); } } } // unconditionally set oldProgram to undefined to prevent it from being captured in closure oldProgram = undefined; program = { getRootFileNames: function () { return rootNames; }, getSourceFile: getSourceFile, getSourceFileByPath: getSourceFileByPath, getSourceFiles: function () { return files; }, getMissingFilePaths: function () { return missingFilePaths; }, getCompilerOptions: function () { return options; }, getSyntacticDiagnostics: getSyntacticDiagnostics, getOptionsDiagnostics: getOptionsDiagnostics, getGlobalDiagnostics: getGlobalDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getDeclarationDiagnostics: getDeclarationDiagnostics, getTypeChecker: getTypeChecker, getClassifiableNames: getClassifiableNames, getDiagnosticsProducingTypeChecker: getDiagnosticsProducingTypeChecker, getCommonSourceDirectory: getCommonSourceDirectory, emit: emit, getCurrentDirectory: function () { return currentDirectory; }, getNodeCount: function () { return getDiagnosticsProducingTypeChecker().getNodeCount(); }, getIdentifierCount: function () { return getDiagnosticsProducingTypeChecker().getIdentifierCount(); }, getSymbolCount: function () { return getDiagnosticsProducingTypeChecker().getSymbolCount(); }, getTypeCount: function () { return getDiagnosticsProducingTypeChecker().getTypeCount(); }, getFileProcessingDiagnostics: function () { return fileProcessingDiagnostics; }, getResolvedTypeReferenceDirectives: function () { return resolvedTypeReferenceDirectives; }, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, isSourceFileDefaultLibrary: isSourceFileDefaultLibrary, dropDiagnosticsProducingTypeChecker: dropDiagnosticsProducingTypeChecker, getSourceFileFromReference: getSourceFileFromReference, sourceFileToPackageName: sourceFileToPackageName, redirectTargetsSet: redirectTargetsSet }; verifyCompilerOptions(); ts.performance.mark("afterProgram"); ts.performance.measure("Program", "beforeProgram", "afterProgram"); return program; function toPath(fileName) { return ts.toPath(fileName, currentDirectory, getCanonicalFileName); } function getCommonSourceDirectory() { if (commonSourceDirectory === undefined) { var emittedFiles = ts.filter(files, function (file) { return ts.sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary); }); if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) { // If a rootDir is specified and is valid use it as the commonSourceDirectory commonSourceDirectory = ts.getNormalizedAbsolutePath(options.rootDir, currentDirectory); } else { commonSourceDirectory = computeCommonSourceDirectory(emittedFiles); } if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== ts.directorySeparator) { // Make sure directory path ends with directory separator so this string can directly // used to replace with "" to get the relative path of the source file and the relative path doesn't // start with / making it rooted path commonSourceDirectory += ts.directorySeparator; } } return commonSourceDirectory; } function getClassifiableNames() { if (!classifiableNames) { // Initialize a checker so that all our files are bound. getTypeChecker(); classifiableNames = ts.createUnderscoreEscapedMap(); for (var _i = 0, files_1 = files; _i < files_1.length; _i++) { var sourceFile = files_1[_i]; ts.copyEntries(sourceFile.classifiableNames, classifiableNames); } } return classifiableNames; } function resolveModuleNamesReusingOldState(moduleNames, containingFile, file, oldProgramState) { if (structuralIsReused === 0 /* Not */ && !file.ambientModuleNames.length) { // If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules, // the best we can do is fallback to the default logic. return resolveModuleNamesWorker(moduleNames, containingFile); } var oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile); if (oldSourceFile !== file && file.resolvedModules) { // `file` was created for the new program. // // We only set `file.resolvedModules` via work from the current function, // so it is defined iff we already called the current function on `file`. // That call happened no later than the creation of the `file` object, // which per above occured during the current program creation. // Since we assume the filesystem does not change during program creation, // it is safe to reuse resolutions from the earlier call. var result_3 = []; for (var _i = 0, moduleNames_1 = moduleNames; _i < moduleNames_1.length; _i++) { var moduleName = moduleNames_1[_i]; var resolvedModule = file.resolvedModules.get(moduleName); result_3.push(resolvedModule); } return result_3; } // At this point, we know at least one of the following hold: // - file has local declarations for ambient modules // - old program state is available // With this information, we can infer some module resolutions without performing resolution. /** An ordered list of module names for which we cannot recover the resolution. */ var unknownModuleNames; /** * The indexing of elements in this list matches that of `moduleNames`. * * Before combining results, result[i] is in one of the following states: * * undefined: needs to be recomputed, * * predictedToResolveToAmbientModuleMarker: known to be an ambient module. * Needs to be reset to undefined before returning, * * ResolvedModuleFull instance: can be reused. */ var result; var reusedNames; /** A transient placeholder used to mark predicted resolution in the result list. */ var predictedToResolveToAmbientModuleMarker = {}; for (var i = 0; i < moduleNames.length; i++) { var moduleName = moduleNames[i]; // If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions if (file === oldSourceFile && !hasInvalidatedResolution(oldSourceFile.path)) { var oldResolvedModule = oldSourceFile && oldSourceFile.resolvedModules.get(moduleName); if (oldResolvedModule) { if (ts.isTraceEnabled(options, host)) { ts.trace(host, ts.Diagnostics.Reusing_resolution_of_module_0_to_file_1_from_old_program, moduleName, containingFile); } (result || (result = new Array(moduleNames.length)))[i] = oldResolvedModule; (reusedNames || (reusedNames = [])).push(moduleName); continue; } } // We know moduleName resolves to an ambient module provided that moduleName: // - is in the list of ambient modules locally declared in the current source file. // - resolved to an ambient module in the old program whose declaration is in an unmodified file // (so the same module declaration will land in the new program) var resolvesToAmbientModuleInNonModifiedFile = false; if (ts.contains(file.ambientModuleNames, moduleName)) { resolvesToAmbientModuleInNonModifiedFile = true; if (ts.isTraceEnabled(options, host)) { ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile); } } else { resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState); } if (resolvesToAmbientModuleInNonModifiedFile) { (result || (result = new Array(moduleNames.length)))[i] = predictedToResolveToAmbientModuleMarker; } else { // Resolution failed in the old program, or resolved to an ambient module for which we can't reuse the result. (unknownModuleNames || (unknownModuleNames = [])).push(moduleName); } } var resolutions = unknownModuleNames && unknownModuleNames.length ? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames) : ts.emptyArray; // Combine results of resolutions and predicted results if (!result) { // There were no unresolved/ambient resolutions. ts.Debug.assert(resolutions.length === moduleNames.length); return resolutions; } var j = 0; for (var i = 0; i < result.length; i++) { if (result[i]) { // `result[i]` is either a `ResolvedModuleFull` or a marker. // If it is the former, we can leave it as is. if (result[i] === predictedToResolveToAmbientModuleMarker) { result[i] = undefined; } } else { result[i] = resolutions[j]; j++; } } ts.Debug.assert(j === resolutions.length); return result; // If we change our policy of rechecking failed lookups on each program create, // we should adjust the value returned here. function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState) { var resolutionToFile = ts.getResolvedModule(oldProgramState.file, moduleName); if (resolutionToFile) { // module used to be resolved to file - ignore it return false; } var ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName); if (!(ambientModule && ambientModule.declarations)) { return false; } // at least one of declarations should come from non-modified source file var firstUnmodifiedFile = ts.forEach(ambientModule.declarations, function (d) { var f = ts.getSourceFileOfNode(d); return !ts.contains(oldProgramState.modifiedFilePaths, f.path) && f; }); if (!firstUnmodifiedFile) { return false; } if (ts.isTraceEnabled(options, host)) { ts.trace(host, ts.Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName); } return true; } } function tryReuseStructureFromOldProgram() { if (!oldProgram) { return 0 /* Not */; } // check properties that can affect structure of the program or module resolution strategy // if any of these properties has changed - structure cannot be reused var oldOptions = oldProgram.getCompilerOptions(); if (ts.changesAffectModuleResolution(oldOptions, options)) { return oldProgram.structureIsReused = 0 /* Not */; } ts.Debug.assert(!(oldProgram.structureIsReused & (2 /* Completely */ | 1 /* SafeModules */))); // there is an old program, check if we can reuse its structure var oldRootNames = oldProgram.getRootFileNames(); if (!ts.arrayIsEqualTo(oldRootNames, rootNames)) { return oldProgram.structureIsReused = 0 /* Not */; } if (!ts.arrayIsEqualTo(options.types, oldOptions.types)) { return oldProgram.structureIsReused = 0 /* Not */; } // check if program source files has changed in the way that can affect structure of the program var newSourceFiles = []; var filePaths = []; var modifiedSourceFiles = []; oldProgram.structureIsReused = 2 /* Completely */; // If the missing file paths are now present, it can change the progam structure, // and hence cant reuse the structure. // This is same as how we dont reuse the structure if one of the file from old program is now missing if (oldProgram.getMissingFilePaths().some(function (missingFilePath) { return host.fileExists(missingFilePath); })) { return oldProgram.structureIsReused = 0 /* Not */; } var oldSourceFiles = oldProgram.getSourceFiles(); var SeenPackageName; (function (SeenPackageName) { SeenPackageName[SeenPackageName["Exists"] = 0] = "Exists"; SeenPackageName[SeenPackageName["Modified"] = 1] = "Modified"; })(SeenPackageName || (SeenPackageName = {})); var seenPackageNames = ts.createMap(); for (var _i = 0, oldSourceFiles_2 = oldSourceFiles; _i < oldSourceFiles_2.length; _i++) { var oldSourceFile = oldSourceFiles_2[_i]; var newSourceFile = host.getSourceFileByPath ? host.getSourceFileByPath(oldSourceFile.fileName, oldSourceFile.path, options.target, /*onError*/ undefined, shouldCreateNewSourceFile) : host.getSourceFile(oldSourceFile.fileName, options.target, /*onError*/ undefined, shouldCreateNewSourceFile); if (!newSourceFile) { return oldProgram.structureIsReused = 0 /* Not */; } ts.Debug.assert(!newSourceFile.redirectInfo, "Host should not return a redirect source file from `getSourceFile`"); var fileChanged = void 0; if (oldSourceFile.redirectInfo) { // We got `newSourceFile` by path, so it is actually for the unredirected file. // This lets us know if the unredirected file has changed. If it has we should break the redirect. if (newSourceFile !== oldSourceFile.redirectInfo.unredirected) { // Underlying file has changed. Might not redirect anymore. Must rebuild program. return oldProgram.structureIsReused = 0 /* Not */; } fileChanged = false; newSourceFile = oldSourceFile; // Use the redirect. } else if (oldProgram.redirectTargetsSet.has(oldSourceFile.path)) { // If a redirected-to source file changes, the redirect may be broken. if (newSourceFile !== oldSourceFile) { return oldProgram.structureIsReused = 0 /* Not */; } fileChanged = false; } else { fileChanged = newSourceFile !== oldSourceFile; } newSourceFile.path = oldSourceFile.path; filePaths.push(newSourceFile.path); var packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path); if (packageName !== undefined) { // If there are 2 different source files for the same package name and at least one of them changes, // they might become redirects. So we must rebuild the program. var prevKind = seenPackageNames.get(packageName); var newKind = fileChanged ? 1 /* Modified */ : 0 /* Exists */; if ((prevKind !== undefined && newKind === 1 /* Modified */) || prevKind === 1 /* Modified */) { return oldProgram.structureIsReused = 0 /* Not */; } seenPackageNames.set(packageName, newKind); } if (fileChanged) { // The `newSourceFile` object was created for the new program. if (oldSourceFile.hasNoDefaultLib !== newSourceFile.hasNoDefaultLib) { // value of no-default-lib has changed // this will affect if default library is injected into the list of files oldProgram.structureIsReused = 1 /* SafeModules */; } // check tripleslash references if (!ts.arrayIsEqualTo(oldSourceFile.referencedFiles, newSourceFile.referencedFiles, fileReferenceIsEqualTo)) { // tripleslash references has changed oldProgram.structureIsReused = 1 /* SafeModules */; } // check imports and module augmentations collectExternalModuleReferences(newSourceFile); if (!ts.arrayIsEqualTo(oldSourceFile.imports, newSourceFile.imports, moduleNameIsEqualTo)) { // imports has changed oldProgram.structureIsReused = 1 /* SafeModules */; } if (!ts.arrayIsEqualTo(oldSourceFile.moduleAugmentations, newSourceFile.moduleAugmentations, moduleNameIsEqualTo)) { // moduleAugmentations has changed oldProgram.structureIsReused = 1 /* SafeModules */; } if ((oldSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */) !== (newSourceFile.flags & 524288 /* PossiblyContainsDynamicImport */)) { // dynamicImport has changed oldProgram.structureIsReused = 1 /* SafeModules */; } if (!ts.arrayIsEqualTo(oldSourceFile.typeReferenceDirectives, newSourceFile.typeReferenceDirectives, fileReferenceIsEqualTo)) { // 'types' references has changed oldProgram.structureIsReused = 1 /* SafeModules */; } // tentatively approve the file modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile }); } else if (hasInvalidatedResolution(oldSourceFile.path)) { // 'module/types' references could have changed oldProgram.structureIsReused = 1 /* SafeModules */; // add file to the modified list so that we will resolve it later modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile }); } // if file has passed all checks it should be safe to reuse it newSourceFiles.push(newSourceFile); } if (oldProgram.structureIsReused !== 2 /* Completely */) { return oldProgram.structureIsReused; } modifiedFilePaths = modifiedSourceFiles.map(function (f) { return f.newFile.path; }); // try to verify results of module resolution for (var _a = 0, modifiedSourceFiles_1 = modifiedSourceFiles; _a < modifiedSourceFiles_1.length; _a++) { var _b = modifiedSourceFiles_1[_a], oldSourceFile = _b.oldFile, newSourceFile = _b.newFile; var newSourceFilePath = ts.getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory); if (resolveModuleNamesWorker) { var moduleNames = getModuleNames(newSourceFile); var oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths: modifiedFilePaths }; var resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState); // ensure that module resolution results are still correct var resolutionsChanged = ts.hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, ts.moduleResolutionIsEqualTo); if (resolutionsChanged) { oldProgram.structureIsReused = 1 /* SafeModules */; newSourceFile.resolvedModules = ts.zipToMap(moduleNames, resolutions); } else { newSourceFile.resolvedModules = oldSourceFile.resolvedModules; } } if (resolveTypeReferenceDirectiveNamesWorker) { var typesReferenceDirectives = ts.map(newSourceFile.typeReferenceDirectives, function (x) { return x.fileName; }); var resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath); // ensure that types resolutions are still correct var resolutionsChanged = ts.hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, ts.typeDirectiveIsEqualTo); if (resolutionsChanged) { oldProgram.structureIsReused = 1 /* SafeModules */; newSourceFile.resolvedTypeReferenceDirectiveNames = ts.zipToMap(typesReferenceDirectives, resolutions); } else { newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames; } } } if (oldProgram.structureIsReused !== 2 /* Completely */) { return oldProgram.structureIsReused; } if (host.hasChangedAutomaticTypeDirectiveNames) { return oldProgram.structureIsReused = 1 /* SafeModules */; } missingFilePaths = oldProgram.getMissingFilePaths(); // update fileName -> file mapping for (var i = 0; i < newSourceFiles.length; i++) { filesByName.set(filePaths[i], newSourceFiles[i]); // Set the file as found during node modules search if it was found that way in old progra, if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i]))) { sourceFilesFoundSearchingNodeModules.set(filePaths[i], true); } } files = newSourceFiles; fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics(); for (var _c = 0, modifiedSourceFiles_2 = modifiedSourceFiles; _c < modifiedSourceFiles_2.length; _c++) { var modifiedFile = modifiedSourceFiles_2[_c]; fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile); } resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives(); sourceFileToPackageName = oldProgram.sourceFileToPackageName; redirectTargetsSet = oldProgram.redirectTargetsSet; return oldProgram.structureIsReused = 2 /* Completely */; } function getEmitHost(writeFileCallback) { return { getCanonicalFileName: getCanonicalFileName, getCommonSourceDirectory: program.getCommonSourceDirectory, getCompilerOptions: program.getCompilerOptions, getCurrentDirectory: function () { return currentDirectory; }, getNewLine: function () { return host.getNewLine(); }, getSourceFile: program.getSourceFile, getSourceFileByPath: program.getSourceFileByPath, getSourceFiles: program.getSourceFiles, isSourceFileFromExternalLibrary: isSourceFileFromExternalLibrary, writeFile: writeFileCallback || (function (fileName, data, writeByteOrderMark, onError, sourceFiles) { return host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles); }), isEmitBlocked: isEmitBlocked, }; } function isSourceFileFromExternalLibrary(file) { return sourceFilesFoundSearchingNodeModules.get(file.path); } function isSourceFileDefaultLibrary(file) { if (file.hasNoDefaultLib) { return true; } if (!options.noLib) { return false; } // If '--lib' is not specified, include default library file according to '--target' // otherwise, using options specified in '--lib' instead of '--target' default library file var equalityComparer = host.useCaseSensitiveFileNames() ? ts.equateStringsCaseSensitive : ts.equateStringsCaseInsensitive; if (!options.lib) { return equalityComparer(file.fileName, getDefaultLibraryFileName()); } else { return ts.forEach(options.lib, function (libFileName) { return equalityComparer(file.fileName, ts.combinePaths(defaultLibraryPath, libFileName)); }); } } function getDiagnosticsProducingTypeChecker() { return diagnosticsProducingTypeChecker || (diagnosticsProducingTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ true)); } function dropDiagnosticsProducingTypeChecker() { diagnosticsProducingTypeChecker = undefined; } function getTypeChecker() { return noDiagnosticsTypeChecker || (noDiagnosticsTypeChecker = ts.createTypeChecker(program, /*produceDiagnostics:*/ false)); } function emit(sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers) { return runWithCancellationToken(function () { return emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, transformers); }); } function isEmitBlocked(emitFileName) { return hasEmitBlockingDiagnostics.has(toPath(emitFileName)); } function emitWorker(program, sourceFile, writeFileCallback, cancellationToken, emitOnlyDtsFiles, customTransformers) { var declarationDiagnostics = []; if (options.noEmit) { return { diagnostics: declarationDiagnostics, sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true }; } // If the noEmitOnError flag is set, then check if we have any errors so far. If so, // immediately bail out. Note that we pass 'undefined' for 'sourceFile' so that we // get any preEmit diagnostics, not just the ones if (options.noEmitOnError) { var diagnostics = program.getOptionsDiagnostics(cancellationToken).concat(program.getSyntacticDiagnostics(sourceFile, cancellationToken), program.getGlobalDiagnostics(cancellationToken), program.getSemanticDiagnostics(sourceFile, cancellationToken)); if (diagnostics.length === 0 && program.getCompilerOptions().declaration) { declarationDiagnostics = program.getDeclarationDiagnostics(/*sourceFile*/ undefined, cancellationToken); } if (diagnostics.length > 0 || declarationDiagnostics.length > 0) { return { diagnostics: ts.concatenate(diagnostics, declarationDiagnostics), sourceMaps: undefined, emittedFiles: undefined, emitSkipped: true }; } } // Create the emit resolver outside of the "emitTime" tracking code below. That way // any cost associated with it (like type checking) are appropriate associated with // the type-checking counter. // // If the -out option is specified, we should not pass the source file to getEmitResolver. // This is because in the -out scenario all files need to be emitted, and therefore all // files need to be type checked. And the way to specify that all files need to be type // checked is to not pass the file to getEmitResolver. var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver((options.outFile || options.out) ? undefined : sourceFile); ts.performance.mark("beforeEmit"); var transformers = emitOnlyDtsFiles ? [] : ts.getTransformers(options, customTransformers); var emitResult = ts.emitFiles(emitResolver, getEmitHost(writeFileCallback), sourceFile, emitOnlyDtsFiles, transformers); ts.performance.mark("afterEmit"); ts.performance.measure("Emit", "beforeEmit", "afterEmit"); return emitResult; } function getSourceFile(fileName) { return getSourceFileByPath(toPath(fileName)); } function getSourceFileByPath(path) { return filesByName.get(path); } function getDiagnosticsHelper(sourceFile, getDiagnostics, cancellationToken) { if (sourceFile) { return getDiagnostics(sourceFile, cancellationToken); } return ts.sortAndDeduplicateDiagnostics(ts.flatMap(program.getSourceFiles(), function (sourceFile) { if (cancellationToken) { cancellationToken.throwIfCancellationRequested(); } return getDiagnostics(sourceFile, cancellationToken); })); } function getSyntacticDiagnostics(sourceFile, cancellationToken) { return getDiagnosticsHelper(sourceFile, getSyntacticDiagnosticsForFile, cancellationToken); } function getSemanticDiagnostics(sourceFile, cancellationToken) { return getDiagnosticsHelper(sourceFile, getSemanticDiagnosticsForFile, cancellationToken); } function getDeclarationDiagnostics(sourceFile, cancellationToken) { var options = program.getCompilerOptions(); // collect diagnostics from the program only once if either no source file was specified or out/outFile is set (bundled emit) if (!sourceFile || options.out || options.outFile) { return getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } else { return getDiagnosticsHelper(sourceFile, getDeclarationDiagnosticsForFile, cancellationToken); } } function getSyntacticDiagnosticsForFile(sourceFile) { // For JavaScript files, we report semantic errors for using TypeScript-only // constructs from within a JavaScript file as syntactic errors. if (ts.isSourceFileJavaScript(sourceFile)) { if (!sourceFile.additionalSyntacticDiagnostics) { sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile); } return ts.concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics); } return sourceFile.parseDiagnostics; } function runWithCancellationToken(func) { try { return func(); } catch (e) { if (e instanceof ts.OperationCanceledException) { // We were canceled while performing the operation. Because our type checker // might be a bad state, we need to throw it away. // // Note: we are overly aggressive here. We do not actually *have* to throw away // the "noDiagnosticsTypeChecker". However, for simplicity, i'd like to keep // the lifetimes of these two TypeCheckers the same. Also, we generally only // cancel when the user has made a change anyways. And, in that case, we (the // program instance) will get thrown away anyways. So trying to keep one of // these type checkers alive doesn't serve much purpose. noDiagnosticsTypeChecker = undefined; diagnosticsProducingTypeChecker = undefined; } throw e; } } function getSemanticDiagnosticsForFile(sourceFile, cancellationToken) { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedSemanticDiagnosticsForFile, getSemanticDiagnosticsForFileNoCache); } function getSemanticDiagnosticsForFileNoCache(sourceFile, cancellationToken) { return runWithCancellationToken(function () { // If skipLibCheck is enabled, skip reporting errors if file is a declaration file. // If skipDefaultLibCheck is enabled, skip reporting errors if file contains a // '/// ' directive. if (options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib) { return ts.emptyArray; } var typeChecker = getDiagnosticsProducingTypeChecker(); ts.Debug.assert(!!sourceFile.bindDiagnostics); var isCheckJs = ts.isCheckJsEnabledForFile(sourceFile, options); // By default, only type-check .ts, .tsx, and 'External' files (external files are added by plugins) var includeBindAndCheckDiagnostics = sourceFile.scriptKind === 3 /* TS */ || sourceFile.scriptKind === 4 /* TSX */ || sourceFile.scriptKind === 5 /* External */ || isCheckJs; var bindDiagnostics = includeBindAndCheckDiagnostics ? sourceFile.bindDiagnostics : ts.emptyArray; var checkDiagnostics = includeBindAndCheckDiagnostics ? typeChecker.getDiagnostics(sourceFile, cancellationToken) : ts.emptyArray; var fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName); var programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName); var diagnostics = bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile); if (isCheckJs) { diagnostics = ts.concatenate(diagnostics, sourceFile.jsDocDiagnostics); } return ts.filter(diagnostics, shouldReportDiagnostic); }); } /** * Skip errors if previous line start with '// @ts-ignore' comment, not counting non-empty non-comment lines */ function shouldReportDiagnostic(diagnostic) { var file = diagnostic.file, start = diagnostic.start; if (file) { var lineStarts = ts.getLineStarts(file); var line = ts.computeLineAndCharacterOfPosition(lineStarts, start).line; while (line > 0) { var previousLineText = file.text.slice(lineStarts[line - 1], lineStarts[line]); var result = ignoreDiagnosticCommentRegEx.exec(previousLineText); if (!result) { // non-empty line return true; } if (result[3]) { // @ts-ignore return false; } line--; } } return true; } function getJavaScriptSyntacticDiagnosticsForFile(sourceFile) { return runWithCancellationToken(function () { var diagnostics = []; var parent = sourceFile; walk(sourceFile); return diagnostics; function walk(node) { // Return directly from the case if the given node doesnt want to visit each child // Otherwise break to visit each child switch (parent.kind) { case 147 /* Parameter */: case 150 /* PropertyDeclaration */: if (parent.questionToken === node) { diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, "?")); return; } // falls through case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: case 227 /* VariableDeclaration */: // type annotation if (parent.type === node) { diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.types_can_only_be_used_in_a_ts_file)); return; } } switch (node.kind) { case 238 /* ImportEqualsDeclaration */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.import_can_only_be_used_in_a_ts_file)); return; case 244 /* ExportAssignment */: if (node.isExportEquals) { diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.export_can_only_be_used_in_a_ts_file)); return; } break; case 263 /* HeritageClause */: var heritageClause = node; if (heritageClause.token === 108 /* ImplementsKeyword */) { diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.implements_clauses_can_only_be_used_in_a_ts_file)); return; } break; case 231 /* InterfaceDeclaration */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.interface_declarations_can_only_be_used_in_a_ts_file)); return; case 234 /* ModuleDeclaration */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.module_declarations_can_only_be_used_in_a_ts_file)); return; case 232 /* TypeAliasDeclaration */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.type_aliases_can_only_be_used_in_a_ts_file)); return; case 233 /* EnumDeclaration */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.enum_declarations_can_only_be_used_in_a_ts_file)); return; case 204 /* NonNullExpression */: diagnostics.push(createDiagnosticForNode(node, ts.Diagnostics.non_null_assertions_can_only_be_used_in_a_ts_file)); return; case 203 /* AsExpression */: diagnostics.push(createDiagnosticForNode(node.type, ts.Diagnostics.type_assertion_expressions_can_only_be_used_in_a_ts_file)); return; case 185 /* TypeAssertionExpression */: ts.Debug.fail(); // Won't parse these in a JS file anyway, as they are interpreted as JSX. } var prevParent = parent; parent = node; ts.forEachChild(node, walk, walkArray); parent = prevParent; } function walkArray(nodes) { if (parent.decorators === nodes && !options.experimentalDecorators) { diagnostics.push(createDiagnosticForNode(parent, ts.Diagnostics.Experimental_support_for_decorators_is_a_feature_that_is_subject_to_change_in_a_future_release_Set_the_experimentalDecorators_option_to_remove_this_warning)); } switch (parent.kind) { case 230 /* ClassDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: // Check type parameters if (nodes === parent.typeParameters) { diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_parameter_declarations_can_only_be_used_in_a_ts_file)); return; } // falls through case 209 /* VariableStatement */: // Check modifiers if (nodes === parent.modifiers) { return checkModifiers(nodes, parent.kind === 209 /* VariableStatement */); } break; case 150 /* PropertyDeclaration */: // Check modifiers of property declaration if (nodes === parent.modifiers) { for (var _i = 0, _a = nodes; _i < _a.length; _i++) { var modifier = _a[_i]; if (modifier.kind !== 115 /* StaticKeyword */) { diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind))); } } return; } break; case 147 /* Parameter */: // Check modifiers of parameter declaration if (nodes === parent.modifiers) { diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.parameter_modifiers_can_only_be_used_in_a_ts_file)); return; } break; case 182 /* CallExpression */: case 183 /* NewExpression */: case 202 /* ExpressionWithTypeArguments */: // Check type arguments if (nodes === parent.typeArguments) { diagnostics.push(createDiagnosticForNodeArray(nodes, ts.Diagnostics.type_arguments_can_only_be_used_in_a_ts_file)); return; } break; } for (var _b = 0, nodes_8 = nodes; _b < nodes_8.length; _b++) { var node = nodes_8[_b]; walk(node); } } function checkModifiers(modifiers, isConstValid) { for (var _i = 0, modifiers_1 = modifiers; _i < modifiers_1.length; _i++) { var modifier = modifiers_1[_i]; switch (modifier.kind) { case 76 /* ConstKeyword */: if (isConstValid) { continue; } // to report error, // falls through case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 131 /* ReadonlyKeyword */: case 124 /* DeclareKeyword */: case 117 /* AbstractKeyword */: diagnostics.push(createDiagnosticForNode(modifier, ts.Diagnostics._0_can_only_be_used_in_a_ts_file, ts.tokenToString(modifier.kind))); break; // These are all legal modifiers. case 115 /* StaticKeyword */: case 84 /* ExportKeyword */: case 79 /* DefaultKeyword */: } } } function createDiagnosticForNodeArray(nodes, message, arg0, arg1, arg2) { var start = nodes.pos; return ts.createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2); } // Since these are syntactic diagnostics, parent might not have been set // this means the sourceFile cannot be infered from the node function createDiagnosticForNode(node, message, arg0, arg1, arg2) { return ts.createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); } }); } function getDeclarationDiagnosticsWorker(sourceFile, cancellationToken) { return getAndCacheDiagnostics(sourceFile, cancellationToken, cachedDeclarationDiagnosticsForFile, getDeclarationDiagnosticsForFileNoCache); } function getDeclarationDiagnosticsForFileNoCache(sourceFile, cancellationToken) { return runWithCancellationToken(function () { var resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken); // Don't actually write any files since we're just getting diagnostics. return ts.getDeclarationDiagnostics(getEmitHost(ts.noop), resolver, sourceFile); }); } function getAndCacheDiagnostics(sourceFile, cancellationToken, cache, getDiagnostics) { var cachedResult = sourceFile ? cache.perFile && cache.perFile.get(sourceFile.path) : cache.allDiagnostics; if (cachedResult) { return cachedResult; } var result = getDiagnostics(sourceFile, cancellationToken) || ts.emptyArray; if (sourceFile) { if (!cache.perFile) { cache.perFile = ts.createMap(); } cache.perFile.set(sourceFile.path, result); } else { cache.allDiagnostics = result; } return result; } function getDeclarationDiagnosticsForFile(sourceFile, cancellationToken) { return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken); } function getOptionsDiagnostics() { return ts.sortAndDeduplicateDiagnostics(ts.concatenate(fileProcessingDiagnostics.getGlobalDiagnostics(), ts.concatenate(programDiagnostics.getGlobalDiagnostics(), options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : []))); } function getGlobalDiagnostics() { return ts.sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()); } function processRootFile(fileName, isDefaultLib) { processSourceFile(ts.normalizePath(fileName), isDefaultLib, /*packageId*/ undefined); } function fileReferenceIsEqualTo(a, b) { return a.fileName === b.fileName; } function moduleNameIsEqualTo(a, b) { return a.kind === 9 /* StringLiteral */ ? b.kind === 9 /* StringLiteral */ && a.text === b.text : b.kind === 71 /* Identifier */ && a.escapedText === b.escapedText; } function collectExternalModuleReferences(file) { if (file.imports) { return; } var isJavaScriptFile = ts.isSourceFileJavaScript(file); var isExternalModuleFile = ts.isExternalModule(file); // file.imports may not be undefined if there exists dynamic import var imports; var moduleAugmentations; var ambientModules; // If we are importing helpers, we need to add a synthetic reference to resolve the // helpers library. if (options.importHelpers && (options.isolatedModules || isExternalModuleFile) && !file.isDeclarationFile) { // synthesize 'import "tslib"' declaration var externalHelpersModuleReference = ts.createLiteral(ts.externalHelpersModuleNameText); var importDecl = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined); externalHelpersModuleReference.parent = importDecl; importDecl.parent = file; imports = [externalHelpersModuleReference]; } for (var _i = 0, _a = file.statements; _i < _a.length; _i++) { var node = _a[_i]; collectModuleReferences(node, /*inAmbientModule*/ false); if ((file.flags & 524288 /* PossiblyContainsDynamicImport */) || isJavaScriptFile) { collectDynamicImportOrRequireCalls(node); } } file.imports = imports || ts.emptyArray; file.moduleAugmentations = moduleAugmentations || ts.emptyArray; file.ambientModuleNames = ambientModules || ts.emptyArray; return; function collectModuleReferences(node, inAmbientModule) { switch (node.kind) { case 239 /* ImportDeclaration */: case 238 /* ImportEqualsDeclaration */: case 245 /* ExportDeclaration */: var moduleNameExpr = ts.getExternalModuleName(node); if (!moduleNameExpr || !ts.isStringLiteral(moduleNameExpr)) { break; } if (!moduleNameExpr.text) { break; } // TypeScript 1.0 spec (April 2014): 12.1.6 // An ExternalImportDeclaration in an AmbientExternalModuleDeclaration may reference other external modules // only through top - level external module names. Relative external module names are not permitted. if (!inAmbientModule || !ts.isExternalModuleNameRelative(moduleNameExpr.text)) { (imports || (imports = [])).push(moduleNameExpr); } break; case 234 /* ModuleDeclaration */: if (ts.isAmbientModule(node) && (inAmbientModule || ts.hasModifier(node, 2 /* Ambient */) || file.isDeclarationFile)) { var moduleName = node.name; var nameText = ts.getTextOfIdentifierOrLiteral(moduleName); // Ambient module declarations can be interpreted as augmentations for some existing external modules. // This will happen in two cases: // - if current file is external module then module augmentation is a ambient module declaration defined in the top level scope // - if current file is not external module then module augmentation is an ambient module declaration with non-relative module name // immediately nested in top level ambient module declaration . if (isExternalModuleFile || (inAmbientModule && !ts.isExternalModuleNameRelative(nameText))) { (moduleAugmentations || (moduleAugmentations = [])).push(moduleName); } else if (!inAmbientModule) { if (file.isDeclarationFile) { // for global .d.ts files record name of ambient module (ambientModules || (ambientModules = [])).push(nameText); } // An AmbientExternalModuleDeclaration declares an external module. // This type of declaration is permitted only in the global module. // The StringLiteral must specify a top - level external module name. // Relative external module names are not permitted // NOTE: body of ambient module is always a module block, if it exists var body = node.body; if (body) { for (var _i = 0, _a = body.statements; _i < _a.length; _i++) { var statement = _a[_i]; collectModuleReferences(statement, /*inAmbientModule*/ true); } } } } } } function collectDynamicImportOrRequireCalls(node) { if (ts.isRequireCall(node, /*checkArgumentIsStringLiteral*/ true)) { (imports || (imports = [])).push(node.arguments[0]); } else if (ts.isImportCall(node) && node.arguments.length === 1 && node.arguments[0].kind === 9 /* StringLiteral */) { (imports || (imports = [])).push(node.arguments[0]); } else { ts.forEachChild(node, collectDynamicImportOrRequireCalls); } } } /** This should have similar behavior to 'processSourceFile' without diagnostics or mutation. */ function getSourceFileFromReference(referencingFile, ref) { return getSourceFileFromReferenceWorker(resolveTripleslashReference(ref.fileName, referencingFile.fileName), function (fileName) { return filesByName.get(toPath(fileName)); }); } function getSourceFileFromReferenceWorker(fileName, getSourceFile, fail, refFile) { if (ts.hasExtension(fileName)) { if (!options.allowNonTsExtensions && !ts.forEach(supportedExtensions, function (extension) { return ts.fileExtensionIs(host.getCanonicalFileName(fileName), extension); })) { if (fail) fail(ts.Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'"); return undefined; } var sourceFile = getSourceFile(fileName); if (fail) { if (!sourceFile) { fail(ts.Diagnostics.File_0_not_found, fileName); } else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) { fail(ts.Diagnostics.A_file_cannot_have_a_reference_to_itself); } } return sourceFile; } else { var sourceFileNoExtension = options.allowNonTsExtensions && getSourceFile(fileName); if (sourceFileNoExtension) return sourceFileNoExtension; if (fail && options.allowNonTsExtensions) { fail(ts.Diagnostics.File_0_not_found, fileName); return undefined; } var sourceFileWithAddedExtension = ts.forEach(supportedExtensions, function (extension) { return getSourceFile(fileName + extension); }); if (fail && !sourceFileWithAddedExtension) fail(ts.Diagnostics.File_0_not_found, fileName + ".ts" /* Ts */); return sourceFileWithAddedExtension; } } /** This has side effects through `findSourceFile`. */ function processSourceFile(fileName, isDefaultLib, packageId, refFile, refPos, refEnd) { getSourceFileFromReferenceWorker(fileName, function (fileName) { return findSourceFile(fileName, toPath(fileName), isDefaultLib, refFile, refPos, refEnd, packageId); }, function (diagnostic) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } fileProcessingDiagnostics.add(refFile !== undefined && refEnd !== undefined && refPos !== undefined ? ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, diagnostic].concat(args)) : ts.createCompilerDiagnostic.apply(void 0, [diagnostic].concat(args))); }, refFile); } function reportFileNamesDifferOnlyInCasingError(fileName, existingFileName, refFile, refPos, refEnd) { if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) { fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } else { fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_name_0_differs_from_already_included_file_name_1_only_in_casing, fileName, existingFileName)); } } function createRedirectSourceFile(redirectTarget, unredirected, fileName, path) { var redirect = Object.create(redirectTarget); redirect.fileName = fileName; redirect.path = path; redirect.redirectInfo = { redirectTarget: redirectTarget, unredirected: unredirected }; Object.defineProperties(redirect, { id: { get: function () { return this.redirectInfo.redirectTarget.id; }, set: function (value) { this.redirectInfo.redirectTarget.id = value; }, }, symbol: { get: function () { return this.redirectInfo.redirectTarget.symbol; }, set: function (value) { this.redirectInfo.redirectTarget.symbol = value; }, }, }); return redirect; } // Get source file from normalized fileName function findSourceFile(fileName, path, isDefaultLib, refFile, refPos, refEnd, packageId) { if (filesByName.has(path)) { var file_1 = filesByName.get(path); // try to check if we've already seen this file but with a different casing in path // NOTE: this only makes sense for case-insensitive file systems if (file_1 && options.forceConsistentCasingInFileNames && ts.getNormalizedAbsolutePath(file_1.fileName, currentDirectory) !== ts.getNormalizedAbsolutePath(fileName, currentDirectory)) { reportFileNamesDifferOnlyInCasingError(fileName, file_1.fileName, refFile, refPos, refEnd); } // If the file was previously found via a node_modules search, but is now being processed as a root file, // then everything it sucks in may also be marked incorrectly, and needs to be checked again. if (file_1 && sourceFilesFoundSearchingNodeModules.get(file_1.path) && currentNodeModulesDepth === 0) { sourceFilesFoundSearchingNodeModules.set(file_1.path, false); if (!options.noResolve) { processReferencedFiles(file_1, isDefaultLib); processTypeReferenceDirectives(file_1); } modulesWithElidedImports.set(file_1.path, false); processImportedModules(file_1); } else if (file_1 && modulesWithElidedImports.get(file_1.path)) { if (currentNodeModulesDepth < maxNodeModuleJsDepth) { modulesWithElidedImports.set(file_1.path, false); processImportedModules(file_1); } } return file_1; } // We haven't looked for this file, do so now and cache result var file = host.getSourceFile(fileName, options.target, function (hostErrorMessage) { if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) { fileProcessingDiagnostics.add(ts.createFileDiagnostic(refFile, refPos, refEnd - refPos, ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } else { fileProcessingDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_read_file_0_Colon_1, fileName, hostErrorMessage)); } }, shouldCreateNewSourceFile); if (packageId) { var packageIdKey = packageId.name + "/" + packageId.subModuleName + "@" + packageId.version; var fileFromPackageId = packageIdToSourceFile.get(packageIdKey); if (fileFromPackageId) { // Some other SourceFile already exists with this package name and version. // Instead of creating a duplicate, just redirect to the existing one. var dupFile = createRedirectSourceFile(fileFromPackageId, file, fileName, path); redirectTargetsSet.set(fileFromPackageId.path, true); filesByName.set(path, dupFile); sourceFileToPackageName.set(path, packageId.name); files.push(dupFile); return dupFile; } else if (file) { // This is the first source file to have this packageId. packageIdToSourceFile.set(packageIdKey, file); sourceFileToPackageName.set(path, packageId.name); } } filesByName.set(path, file); if (file) { sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0); file.path = path; if (host.useCaseSensitiveFileNames()) { var pathLowerCase = path.toLowerCase(); // for case-sensitive file systems check if we've already seen some file with similar filename ignoring case var existingFile = filesByNameIgnoreCase.get(pathLowerCase); if (existingFile) { reportFileNamesDifferOnlyInCasingError(fileName, existingFile.fileName, refFile, refPos, refEnd); } else { filesByNameIgnoreCase.set(pathLowerCase, file); } } skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib; if (!options.noResolve) { processReferencedFiles(file, isDefaultLib); processTypeReferenceDirectives(file); } // always process imported modules to record module name resolutions processImportedModules(file); if (isDefaultLib) { files.unshift(file); } else { files.push(file); } } return file; } function processReferencedFiles(file, isDefaultLib) { ts.forEach(file.referencedFiles, function (ref) { var referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName); processSourceFile(referencedFileName, isDefaultLib, /*packageId*/ undefined, file, ref.pos, ref.end); }); } function processTypeReferenceDirectives(file) { // We lower-case all type references because npm automatically lowercases all packages. See GH#9824. var typeDirectives = ts.map(file.typeReferenceDirectives, function (ref) { return ref.fileName.toLocaleLowerCase(); }); var resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName); for (var i = 0; i < typeDirectives.length; i++) { var ref = file.typeReferenceDirectives[i]; var resolvedTypeReferenceDirective = resolutions[i]; // store resolved type directive on the file var fileName = ref.fileName.toLocaleLowerCase(); ts.setResolvedTypeReferenceDirective(file, fileName, resolvedTypeReferenceDirective); processTypeReferenceDirective(fileName, resolvedTypeReferenceDirective, file, ref.pos, ref.end); } } function processTypeReferenceDirective(typeReferenceDirective, resolvedTypeReferenceDirective, refFile, refPos, refEnd) { // If we already found this library as a primary reference - nothing to do var previousResolution = resolvedTypeReferenceDirectives.get(typeReferenceDirective); if (previousResolution && previousResolution.primary) { return; } var saveResolution = true; if (resolvedTypeReferenceDirective) { if (resolvedTypeReferenceDirective.primary) { // resolved from the primary path processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); } else { // If we already resolved to this file, it must have been a secondary reference. Check file contents // for sameness and possibly issue an error if (previousResolution) { // Don't bother reading the file again if it's the same file. if (resolvedTypeReferenceDirective.resolvedFileName !== previousResolution.resolvedFileName) { var otherFileText = host.readFile(resolvedTypeReferenceDirective.resolvedFileName); if (otherFileText !== getSourceFile(previousResolution.resolvedFileName).text) { fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName)); } } // don't overwrite previous resolution result saveResolution = false; } else { // First resolution of this library processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); } } } else { fileProcessingDiagnostics.add(createDiagnostic(refFile, refPos, refEnd, ts.Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective)); } if (saveResolution) { resolvedTypeReferenceDirectives.set(typeReferenceDirective, resolvedTypeReferenceDirective); } } function createDiagnostic(refFile, refPos, refEnd, message) { var args = []; for (var _i = 4; _i < arguments.length; _i++) { args[_i - 4] = arguments[_i]; } if (refFile === undefined || refPos === undefined || refEnd === undefined) { return ts.createCompilerDiagnostic.apply(void 0, [message].concat(args)); } else { return ts.createFileDiagnostic.apply(void 0, [refFile, refPos, refEnd - refPos, message].concat(args)); } } function getCanonicalFileName(fileName) { return host.getCanonicalFileName(fileName); } function processImportedModules(file) { collectExternalModuleReferences(file); if (file.imports.length || file.moduleAugmentations.length) { // Because global augmentation doesn't have string literal name, we can check for global augmentation as such. var moduleNames = getModuleNames(file); var oldProgramState = { program: oldProgram, file: file, modifiedFilePaths: modifiedFilePaths }; var resolutions = resolveModuleNamesReusingOldState(moduleNames, ts.getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState); ts.Debug.assert(resolutions.length === moduleNames.length); for (var i = 0; i < moduleNames.length; i++) { var resolution = resolutions[i]; ts.setResolvedModule(file, moduleNames[i], resolution); if (!resolution) { continue; } var isFromNodeModulesSearch = resolution.isExternalLibraryImport; var isJsFile = !ts.extensionIsTypeScript(resolution.extension); var isJsFileFromNodeModules = isFromNodeModulesSearch && isJsFile; var resolvedFileName = resolution.resolvedFileName; if (isFromNodeModulesSearch) { currentNodeModulesDepth++; } // add file to program only if: // - resolution was successful // - noResolve is falsy // - module name comes from the list of imports // - it's not a top level JavaScript module that exceeded the search max var elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth; // Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs') // This may still end up being an untyped module -- the file won't be included but imports will be allowed. var shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport && !(isJsFile && !options.allowJs); if (elideImport) { modulesWithElidedImports.set(file.path, true); } else if (shouldAddFile) { var path = toPath(resolvedFileName); var pos = ts.skipTrivia(file.text, file.imports[i].pos); findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end, resolution.packageId); } if (isFromNodeModulesSearch) { currentNodeModulesDepth--; } } } else { // no imports - drop cached module resolutions file.resolvedModules = undefined; } } function computeCommonSourceDirectory(sourceFiles) { var fileNames = []; for (var _i = 0, sourceFiles_2 = sourceFiles; _i < sourceFiles_2.length; _i++) { var file = sourceFiles_2[_i]; if (!file.isDeclarationFile) { fileNames.push(file.fileName); } } return computeCommonSourceDirectoryOfFilenames(fileNames, currentDirectory, getCanonicalFileName); } function checkSourceFilesBelongToPath(sourceFiles, rootDirectory) { var allFilesBelongToPath = true; if (sourceFiles) { var absoluteRootDirectoryPath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(rootDirectory, currentDirectory)); for (var _i = 0, sourceFiles_3 = sourceFiles; _i < sourceFiles_3.length; _i++) { var sourceFile = sourceFiles_3[_i]; if (!sourceFile.isDeclarationFile) { var absoluteSourceFilePath = host.getCanonicalFileName(ts.getNormalizedAbsolutePath(sourceFile.fileName, currentDirectory)); if (absoluteSourceFilePath.indexOf(absoluteRootDirectoryPath) !== 0) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files, sourceFile.fileName, options.rootDir)); allFilesBelongToPath = false; } } } } return allFilesBelongToPath; } function verifyCompilerOptions() { if (options.isolatedModules) { if (options.declaration) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declaration", "isolatedModules"); } if (options.noEmitOnError) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noEmitOnError", "isolatedModules"); } if (options.out) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "isolatedModules"); } if (options.outFile) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "outFile", "isolatedModules"); } } if (options.inlineSourceMap) { if (options.sourceMap) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "sourceMap", "inlineSourceMap"); } if (options.mapRoot) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "mapRoot", "inlineSourceMap"); } } if (options.paths && options.baseUrl === undefined) { createDiagnosticForOptionName(ts.Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths"); } if (options.paths) { for (var key in options.paths) { if (!ts.hasProperty(options.paths, key)) { continue; } if (!ts.hasZeroOrOneAsteriskCharacter(key)) { createDiagnosticForOptionPaths(/*onKey*/ true, key, ts.Diagnostics.Pattern_0_can_have_at_most_one_Asterisk_character, key); } if (ts.isArray(options.paths[key])) { var len = options.paths[key].length; if (len === 0) { createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_shouldn_t_be_an_empty_array, key); } for (var i = 0; i < len; i++) { var subst = options.paths[key][i]; var typeOfSubst = typeof subst; if (typeOfSubst === "string") { if (!ts.hasZeroOrOneAsteriskCharacter(subst)) { createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_in_pattern_1_in_can_have_at_most_one_Asterisk_character, subst, key); } } else { createDiagnosticForOptionPathKeyValue(key, i, ts.Diagnostics.Substitution_0_for_pattern_1_has_incorrect_type_expected_string_got_2, subst, key, typeOfSubst); } } } else { createDiagnosticForOptionPaths(/*onKey*/ false, key, ts.Diagnostics.Substitutions_for_pattern_0_should_be_an_array, key); } } } if (!options.sourceMap && !options.inlineSourceMap) { if (options.inlineSources) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "inlineSources"); } if (options.sourceRoot) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided, "sourceRoot"); } } if (options.out && options.outFile) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "out", "outFile"); } if (options.mapRoot && !options.sourceMap) { // Error to specify --mapRoot without --sourcemap createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "mapRoot", "sourceMap"); } if (options.declarationDir) { if (!options.declaration) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "declarationDir", "declaration"); } if (options.out || options.outFile) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "declarationDir", options.out ? "out" : "outFile"); } } if (options.lib && options.noLib) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "lib", "noLib"); } if (options.noImplicitUseStrict && ts.getStrictOptionValue(options, "alwaysStrict")) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "noImplicitUseStrict", "alwaysStrict"); } var languageVersion = options.target || 0 /* ES3 */; var outFile = options.outFile || options.out; var firstNonAmbientExternalModuleSourceFile = ts.forEach(files, function (f) { return ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; }); if (options.isolatedModules) { if (options.module === ts.ModuleKind.None && languageVersion < 2 /* ES2015 */) { createDiagnosticForOptionName(ts.Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target"); } var firstNonExternalModuleSourceFile = ts.forEach(files, function (f) { return !ts.isExternalModule(f) && !f.isDeclarationFile ? f : undefined; }); if (firstNonExternalModuleSourceFile) { var span_7 = ts.getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile); programDiagnostics.add(ts.createFileDiagnostic(firstNonExternalModuleSourceFile, span_7.start, span_7.length, ts.Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided)); } } else if (firstNonAmbientExternalModuleSourceFile && languageVersion < 2 /* ES2015 */ && options.module === ts.ModuleKind.None) { // We cannot use createDiagnosticFromNode because nodes do not have parents yet var span_8 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator); programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_8.start, span_8.length, ts.Diagnostics.Cannot_use_imports_exports_or_module_augmentations_when_module_is_none)); } // Cannot specify module gen that isn't amd or system with --out if (outFile) { if (options.module && !(options.module === ts.ModuleKind.AMD || options.module === ts.ModuleKind.System)) { createDiagnosticForOptionName(ts.Diagnostics.Only_amd_and_system_modules_are_supported_alongside_0, options.out ? "out" : "outFile", "module"); } else if (options.module === undefined && firstNonAmbientExternalModuleSourceFile) { var span_9 = ts.getErrorSpanForNode(firstNonAmbientExternalModuleSourceFile, firstNonAmbientExternalModuleSourceFile.externalModuleIndicator); programDiagnostics.add(ts.createFileDiagnostic(firstNonAmbientExternalModuleSourceFile, span_9.start, span_9.length, ts.Diagnostics.Cannot_compile_modules_using_option_0_unless_the_module_flag_is_amd_or_system, options.out ? "out" : "outFile")); } } // there has to be common source directory if user specified --outdir || --sourceRoot // if user specified --mapRoot, there needs to be common source directory if there would be multiple files being emitted if (options.outDir || // there is --outDir specified options.sourceRoot || // there is --sourceRoot specified options.mapRoot) { // Precalculate and cache the common source directory var dir = getCommonSourceDirectory(); // If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure if (options.outDir && dir === "" && ts.forEach(files, function (file) { return ts.getRootLength(file.fileName) > 1; })) { createDiagnosticForOptionName(ts.Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir"); } } if (!options.noEmit && options.allowJs && options.declaration) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "allowJs", "declaration"); } if (options.checkJs && !options.allowJs) { programDiagnostics.add(ts.createCompilerDiagnostic(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "checkJs", "allowJs")); } if (options.emitDecoratorMetadata && !options.experimentalDecorators) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "emitDecoratorMetadata", "experimentalDecorators"); } if (options.jsxFactory) { if (options.reactNamespace) { createDiagnosticForOptionName(ts.Diagnostics.Option_0_cannot_be_specified_with_option_1, "reactNamespace", "jsxFactory"); } if (!ts.parseIsolatedEntityName(options.jsxFactory, languageVersion)) { createOptionValueDiagnostic("jsxFactory", ts.Diagnostics.Invalid_value_for_jsxFactory_0_is_not_a_valid_identifier_or_qualified_name, options.jsxFactory); } } else if (options.reactNamespace && !ts.isIdentifierText(options.reactNamespace, languageVersion)) { createOptionValueDiagnostic("reactNamespace", ts.Diagnostics.Invalid_value_for_reactNamespace_0_is_not_a_valid_identifier, options.reactNamespace); } // If the emit is enabled make sure that every output file is unique and not overwriting any of the input files if (!options.noEmit && !options.suppressOutputPathCheck) { var emitHost = getEmitHost(); var emitFilesSeen_1 = ts.createMap(); ts.forEachEmittedFile(emitHost, function (emitFileNames) { verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen_1); verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen_1); }); } // Verify that all the emit files are unique and don't overwrite input files function verifyEmitFilePath(emitFileName, emitFilesSeen) { if (emitFileName) { var emitFilePath = toPath(emitFileName); // Report error if the output overwrites input file if (filesByName.has(emitFilePath)) { var chain_1; if (!options.configFilePath) { // The program is from either an inferred project or an external project chain_1 = ts.chainDiagnosticMessages(/*details*/ undefined, ts.Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig); } chain_1 = ts.chainDiagnosticMessages(chain_1, ts.Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName); blockEmittingOfFile(emitFileName, ts.createCompilerDiagnosticFromMessageChain(chain_1)); } var emitFileKey = !host.useCaseSensitiveFileNames() ? emitFilePath.toLocaleLowerCase() : emitFilePath; // Report error if multiple files write into same file if (emitFilesSeen.has(emitFileKey)) { // Already seen the same emit file - report error blockEmittingOfFile(emitFileName, ts.createCompilerDiagnostic(ts.Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName)); } else { emitFilesSeen.set(emitFileKey, true); } } } } function createDiagnosticForOptionPathKeyValue(key, valueIndex, message, arg0, arg1, arg2) { var needCompilerDiagnostic = true; var pathsSyntax = getOptionPathsSyntax(); for (var _i = 0, pathsSyntax_1 = pathsSyntax; _i < pathsSyntax_1.length; _i++) { var pathProp = pathsSyntax_1[_i]; if (ts.isObjectLiteralExpression(pathProp.initializer)) { for (var _a = 0, _b = ts.getPropertyAssignment(pathProp.initializer, key); _a < _b.length; _a++) { var keyProps = _b[_a]; if (ts.isArrayLiteralExpression(keyProps.initializer) && keyProps.initializer.elements.length > valueIndex) { programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, keyProps.initializer.elements[valueIndex], message, arg0, arg1, arg2)); needCompilerDiagnostic = false; } } } } if (needCompilerDiagnostic) { programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1, arg2)); } } function createDiagnosticForOptionPaths(onKey, key, message, arg0) { var needCompilerDiagnostic = true; var pathsSyntax = getOptionPathsSyntax(); for (var _i = 0, pathsSyntax_2 = pathsSyntax; _i < pathsSyntax_2.length; _i++) { var pathProp = pathsSyntax_2[_i]; if (ts.isObjectLiteralExpression(pathProp.initializer) && createOptionDiagnosticInObjectLiteralSyntax(pathProp.initializer, onKey, key, /*key2*/ undefined, message, arg0)) { needCompilerDiagnostic = false; } } if (needCompilerDiagnostic) { programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0)); } } function getOptionPathsSyntax() { var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); if (compilerOptionsObjectLiteralSyntax) { return ts.getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths"); } return ts.emptyArray; } function createDiagnosticForOptionName(message, option1, option2) { createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2); } function createOptionValueDiagnostic(option1, message, arg0) { createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0); } function createDiagnosticForOption(onKey, option1, option2, message, arg0, arg1) { var compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); var needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1); if (needCompilerDiagnostic) { programDiagnostics.add(ts.createCompilerDiagnostic(message, arg0, arg1)); } } function getCompilerOptionsObjectLiteralSyntax() { if (_compilerOptionsObjectLiteralSyntax === undefined) { _compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword if (options.configFile && options.configFile.jsonObject) { for (var _i = 0, _a = ts.getPropertyAssignment(options.configFile.jsonObject, "compilerOptions"); _i < _a.length; _i++) { var prop = _a[_i]; if (ts.isObjectLiteralExpression(prop.initializer)) { _compilerOptionsObjectLiteralSyntax = prop.initializer; break; } } } } return _compilerOptionsObjectLiteralSyntax; } function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral, onKey, key1, key2, message, arg0, arg1) { var props = ts.getPropertyAssignment(objectLiteral, key1, key2); for (var _i = 0, props_2 = props; _i < props_2.length; _i++) { var prop = props_2[_i]; programDiagnostics.add(ts.createDiagnosticForNodeInSourceFile(options.configFile, onKey ? prop.name : prop.initializer, message, arg0, arg1)); } return !!props.length; } function blockEmittingOfFile(emitFileName, diag) { hasEmitBlockingDiagnostics.set(toPath(emitFileName), true); programDiagnostics.add(diag); } } ts.createProgram = createProgram; /* @internal */ /** * Returns a DiagnosticMessage if we won't include a resolved module due to its extension. * The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to. * This returns a diagnostic even if the module will be an untyped module. */ function getResolutionDiagnostic(options, _a) { var extension = _a.extension; switch (extension) { case ".ts" /* Ts */: case ".d.ts" /* Dts */: // These are always allowed. return undefined; case ".tsx" /* Tsx */: return needJsx(); case ".jsx" /* Jsx */: return needJsx() || needAllowJs(); case ".js" /* Js */: return needAllowJs(); } function needJsx() { return options.jsx ? undefined : ts.Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set; } function needAllowJs() { return options.allowJs || !ts.getStrictOptionValue(options, "noImplicitAny") ? undefined : ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type; } } ts.getResolutionDiagnostic = getResolutionDiagnostic; function checkAllDefined(names) { ts.Debug.assert(names.every(function (name) { return name !== undefined; }), "A name is undefined.", function () { return JSON.stringify(names); }); return names; } function getModuleNames(_a) { var imports = _a.imports, moduleAugmentations = _a.moduleAugmentations; var res = imports.map(function (i) { return i.text; }); for (var _i = 0, moduleAugmentations_1 = moduleAugmentations; _i < moduleAugmentations_1.length; _i++) { var aug = moduleAugmentations_1[_i]; if (aug.kind === 9 /* StringLiteral */) { res.push(aug.text); } // Do nothing if it's an Identifier; we don't need to do module resolution for `declare global`. } return res; } })(ts || (ts = {})); var ts; (function (ts) { var ScriptSnapshot; (function (ScriptSnapshot) { var StringScriptSnapshot = /** @class */ (function () { function StringScriptSnapshot(text) { this.text = text; } StringScriptSnapshot.prototype.getText = function (start, end) { return start === 0 && end === this.text.length ? this.text : this.text.substring(start, end); }; StringScriptSnapshot.prototype.getLength = function () { return this.text.length; }; StringScriptSnapshot.prototype.getChangeRange = function () { // Text-based snapshots do not support incremental parsing. Return undefined // to signal that to the caller. return undefined; }; return StringScriptSnapshot; }()); function fromString(text) { return new StringScriptSnapshot(text); } ScriptSnapshot.fromString = fromString; })(ScriptSnapshot = ts.ScriptSnapshot || (ts.ScriptSnapshot = {})); var TextChange = /** @class */ (function () { function TextChange() { } return TextChange; }()); ts.TextChange = TextChange; var HighlightSpanKind; (function (HighlightSpanKind) { HighlightSpanKind["none"] = "none"; HighlightSpanKind["definition"] = "definition"; HighlightSpanKind["reference"] = "reference"; HighlightSpanKind["writtenReference"] = "writtenReference"; })(HighlightSpanKind = ts.HighlightSpanKind || (ts.HighlightSpanKind = {})); var IndentStyle; (function (IndentStyle) { IndentStyle[IndentStyle["None"] = 0] = "None"; IndentStyle[IndentStyle["Block"] = 1] = "Block"; IndentStyle[IndentStyle["Smart"] = 2] = "Smart"; })(IndentStyle = ts.IndentStyle || (ts.IndentStyle = {})); var SymbolDisplayPartKind; (function (SymbolDisplayPartKind) { SymbolDisplayPartKind[SymbolDisplayPartKind["aliasName"] = 0] = "aliasName"; SymbolDisplayPartKind[SymbolDisplayPartKind["className"] = 1] = "className"; SymbolDisplayPartKind[SymbolDisplayPartKind["enumName"] = 2] = "enumName"; SymbolDisplayPartKind[SymbolDisplayPartKind["fieldName"] = 3] = "fieldName"; SymbolDisplayPartKind[SymbolDisplayPartKind["interfaceName"] = 4] = "interfaceName"; SymbolDisplayPartKind[SymbolDisplayPartKind["keyword"] = 5] = "keyword"; SymbolDisplayPartKind[SymbolDisplayPartKind["lineBreak"] = 6] = "lineBreak"; SymbolDisplayPartKind[SymbolDisplayPartKind["numericLiteral"] = 7] = "numericLiteral"; SymbolDisplayPartKind[SymbolDisplayPartKind["stringLiteral"] = 8] = "stringLiteral"; SymbolDisplayPartKind[SymbolDisplayPartKind["localName"] = 9] = "localName"; SymbolDisplayPartKind[SymbolDisplayPartKind["methodName"] = 10] = "methodName"; SymbolDisplayPartKind[SymbolDisplayPartKind["moduleName"] = 11] = "moduleName"; SymbolDisplayPartKind[SymbolDisplayPartKind["operator"] = 12] = "operator"; SymbolDisplayPartKind[SymbolDisplayPartKind["parameterName"] = 13] = "parameterName"; SymbolDisplayPartKind[SymbolDisplayPartKind["propertyName"] = 14] = "propertyName"; SymbolDisplayPartKind[SymbolDisplayPartKind["punctuation"] = 15] = "punctuation"; SymbolDisplayPartKind[SymbolDisplayPartKind["space"] = 16] = "space"; SymbolDisplayPartKind[SymbolDisplayPartKind["text"] = 17] = "text"; SymbolDisplayPartKind[SymbolDisplayPartKind["typeParameterName"] = 18] = "typeParameterName"; SymbolDisplayPartKind[SymbolDisplayPartKind["enumMemberName"] = 19] = "enumMemberName"; SymbolDisplayPartKind[SymbolDisplayPartKind["functionName"] = 20] = "functionName"; SymbolDisplayPartKind[SymbolDisplayPartKind["regularExpressionLiteral"] = 21] = "regularExpressionLiteral"; })(SymbolDisplayPartKind = ts.SymbolDisplayPartKind || (ts.SymbolDisplayPartKind = {})); var OutputFileType; (function (OutputFileType) { OutputFileType[OutputFileType["JavaScript"] = 0] = "JavaScript"; OutputFileType[OutputFileType["SourceMap"] = 1] = "SourceMap"; OutputFileType[OutputFileType["Declaration"] = 2] = "Declaration"; })(OutputFileType = ts.OutputFileType || (ts.OutputFileType = {})); var EndOfLineState; (function (EndOfLineState) { EndOfLineState[EndOfLineState["None"] = 0] = "None"; EndOfLineState[EndOfLineState["InMultiLineCommentTrivia"] = 1] = "InMultiLineCommentTrivia"; EndOfLineState[EndOfLineState["InSingleQuoteStringLiteral"] = 2] = "InSingleQuoteStringLiteral"; EndOfLineState[EndOfLineState["InDoubleQuoteStringLiteral"] = 3] = "InDoubleQuoteStringLiteral"; EndOfLineState[EndOfLineState["InTemplateHeadOrNoSubstitutionTemplate"] = 4] = "InTemplateHeadOrNoSubstitutionTemplate"; EndOfLineState[EndOfLineState["InTemplateMiddleOrTail"] = 5] = "InTemplateMiddleOrTail"; EndOfLineState[EndOfLineState["InTemplateSubstitutionPosition"] = 6] = "InTemplateSubstitutionPosition"; })(EndOfLineState = ts.EndOfLineState || (ts.EndOfLineState = {})); var TokenClass; (function (TokenClass) { TokenClass[TokenClass["Punctuation"] = 0] = "Punctuation"; TokenClass[TokenClass["Keyword"] = 1] = "Keyword"; TokenClass[TokenClass["Operator"] = 2] = "Operator"; TokenClass[TokenClass["Comment"] = 3] = "Comment"; TokenClass[TokenClass["Whitespace"] = 4] = "Whitespace"; TokenClass[TokenClass["Identifier"] = 5] = "Identifier"; TokenClass[TokenClass["NumberLiteral"] = 6] = "NumberLiteral"; TokenClass[TokenClass["StringLiteral"] = 7] = "StringLiteral"; TokenClass[TokenClass["RegExpLiteral"] = 8] = "RegExpLiteral"; })(TokenClass = ts.TokenClass || (ts.TokenClass = {})); var ScriptElementKind; (function (ScriptElementKind) { ScriptElementKind["unknown"] = ""; ScriptElementKind["warning"] = "warning"; /** predefined type (void) or keyword (class) */ ScriptElementKind["keyword"] = "keyword"; /** top level script node */ ScriptElementKind["scriptElement"] = "script"; /** module foo {} */ ScriptElementKind["moduleElement"] = "module"; /** class X {} */ ScriptElementKind["classElement"] = "class"; /** var x = class X {} */ ScriptElementKind["localClassElement"] = "local class"; /** interface Y {} */ ScriptElementKind["interfaceElement"] = "interface"; /** type T = ... */ ScriptElementKind["typeElement"] = "type"; /** enum E */ ScriptElementKind["enumElement"] = "enum"; ScriptElementKind["enumMemberElement"] = "enum member"; /** * Inside module and script only * const v = .. */ ScriptElementKind["variableElement"] = "var"; /** Inside function */ ScriptElementKind["localVariableElement"] = "local var"; /** * Inside module and script only * function f() { } */ ScriptElementKind["functionElement"] = "function"; /** Inside function */ ScriptElementKind["localFunctionElement"] = "local function"; /** class X { [public|private]* foo() {} } */ ScriptElementKind["memberFunctionElement"] = "method"; /** class X { [public|private]* [get|set] foo:number; } */ ScriptElementKind["memberGetAccessorElement"] = "getter"; ScriptElementKind["memberSetAccessorElement"] = "setter"; /** * class X { [public|private]* foo:number; } * interface Y { foo:number; } */ ScriptElementKind["memberVariableElement"] = "property"; /** class X { constructor() { } } */ ScriptElementKind["constructorImplementationElement"] = "constructor"; /** interface Y { ():number; } */ ScriptElementKind["callSignatureElement"] = "call"; /** interface Y { []:number; } */ ScriptElementKind["indexSignatureElement"] = "index"; /** interface Y { new():Y; } */ ScriptElementKind["constructSignatureElement"] = "construct"; /** function foo(*Y*: string) */ ScriptElementKind["parameterElement"] = "parameter"; ScriptElementKind["typeParameterElement"] = "type parameter"; ScriptElementKind["primitiveType"] = "primitive type"; ScriptElementKind["label"] = "label"; ScriptElementKind["alias"] = "alias"; ScriptElementKind["constElement"] = "const"; ScriptElementKind["letElement"] = "let"; ScriptElementKind["directory"] = "directory"; ScriptElementKind["externalModuleName"] = "external module name"; /** * */ ScriptElementKind["jsxAttribute"] = "JSX attribute"; })(ScriptElementKind = ts.ScriptElementKind || (ts.ScriptElementKind = {})); var ScriptElementKindModifier; (function (ScriptElementKindModifier) { ScriptElementKindModifier["none"] = ""; ScriptElementKindModifier["publicMemberModifier"] = "public"; ScriptElementKindModifier["privateMemberModifier"] = "private"; ScriptElementKindModifier["protectedMemberModifier"] = "protected"; ScriptElementKindModifier["exportedModifier"] = "export"; ScriptElementKindModifier["ambientModifier"] = "declare"; ScriptElementKindModifier["staticModifier"] = "static"; ScriptElementKindModifier["abstractModifier"] = "abstract"; })(ScriptElementKindModifier = ts.ScriptElementKindModifier || (ts.ScriptElementKindModifier = {})); var ClassificationTypeNames; (function (ClassificationTypeNames) { ClassificationTypeNames["comment"] = "comment"; ClassificationTypeNames["identifier"] = "identifier"; ClassificationTypeNames["keyword"] = "keyword"; ClassificationTypeNames["numericLiteral"] = "number"; ClassificationTypeNames["operator"] = "operator"; ClassificationTypeNames["stringLiteral"] = "string"; ClassificationTypeNames["whiteSpace"] = "whitespace"; ClassificationTypeNames["text"] = "text"; ClassificationTypeNames["punctuation"] = "punctuation"; ClassificationTypeNames["className"] = "class name"; ClassificationTypeNames["enumName"] = "enum name"; ClassificationTypeNames["interfaceName"] = "interface name"; ClassificationTypeNames["moduleName"] = "module name"; ClassificationTypeNames["typeParameterName"] = "type parameter name"; ClassificationTypeNames["typeAliasName"] = "type alias name"; ClassificationTypeNames["parameterName"] = "parameter name"; ClassificationTypeNames["docCommentTagName"] = "doc comment tag name"; ClassificationTypeNames["jsxOpenTagName"] = "jsx open tag name"; ClassificationTypeNames["jsxCloseTagName"] = "jsx close tag name"; ClassificationTypeNames["jsxSelfClosingTagName"] = "jsx self closing tag name"; ClassificationTypeNames["jsxAttribute"] = "jsx attribute"; ClassificationTypeNames["jsxText"] = "jsx text"; ClassificationTypeNames["jsxAttributeStringLiteralValue"] = "jsx attribute string literal value"; })(ClassificationTypeNames = ts.ClassificationTypeNames || (ts.ClassificationTypeNames = {})); var ClassificationType; (function (ClassificationType) { ClassificationType[ClassificationType["comment"] = 1] = "comment"; ClassificationType[ClassificationType["identifier"] = 2] = "identifier"; ClassificationType[ClassificationType["keyword"] = 3] = "keyword"; ClassificationType[ClassificationType["numericLiteral"] = 4] = "numericLiteral"; ClassificationType[ClassificationType["operator"] = 5] = "operator"; ClassificationType[ClassificationType["stringLiteral"] = 6] = "stringLiteral"; ClassificationType[ClassificationType["regularExpressionLiteral"] = 7] = "regularExpressionLiteral"; ClassificationType[ClassificationType["whiteSpace"] = 8] = "whiteSpace"; ClassificationType[ClassificationType["text"] = 9] = "text"; ClassificationType[ClassificationType["punctuation"] = 10] = "punctuation"; ClassificationType[ClassificationType["className"] = 11] = "className"; ClassificationType[ClassificationType["enumName"] = 12] = "enumName"; ClassificationType[ClassificationType["interfaceName"] = 13] = "interfaceName"; ClassificationType[ClassificationType["moduleName"] = 14] = "moduleName"; ClassificationType[ClassificationType["typeParameterName"] = 15] = "typeParameterName"; ClassificationType[ClassificationType["typeAliasName"] = 16] = "typeAliasName"; ClassificationType[ClassificationType["parameterName"] = 17] = "parameterName"; ClassificationType[ClassificationType["docCommentTagName"] = 18] = "docCommentTagName"; ClassificationType[ClassificationType["jsxOpenTagName"] = 19] = "jsxOpenTagName"; ClassificationType[ClassificationType["jsxCloseTagName"] = 20] = "jsxCloseTagName"; ClassificationType[ClassificationType["jsxSelfClosingTagName"] = 21] = "jsxSelfClosingTagName"; ClassificationType[ClassificationType["jsxAttribute"] = 22] = "jsxAttribute"; ClassificationType[ClassificationType["jsxText"] = 23] = "jsxText"; ClassificationType[ClassificationType["jsxAttributeStringLiteralValue"] = 24] = "jsxAttributeStringLiteralValue"; })(ClassificationType = ts.ClassificationType || (ts.ClassificationType = {})); })(ts || (ts = {})); // These utilities are common to multiple language service features. /* @internal */ var ts; (function (ts) { ts.scanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ true); var SemanticMeaning; (function (SemanticMeaning) { SemanticMeaning[SemanticMeaning["None"] = 0] = "None"; SemanticMeaning[SemanticMeaning["Value"] = 1] = "Value"; SemanticMeaning[SemanticMeaning["Type"] = 2] = "Type"; SemanticMeaning[SemanticMeaning["Namespace"] = 4] = "Namespace"; SemanticMeaning[SemanticMeaning["All"] = 7] = "All"; })(SemanticMeaning = ts.SemanticMeaning || (ts.SemanticMeaning = {})); function getMeaningFromDeclaration(node) { switch (node.kind) { case 147 /* Parameter */: case 227 /* VariableDeclaration */: case 177 /* BindingElement */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 265 /* PropertyAssignment */: case 266 /* ShorthandPropertyAssignment */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 264 /* CatchClause */: case 257 /* JsxAttribute */: return 1 /* Value */; case 146 /* TypeParameter */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 164 /* TypeLiteral */: return 2 /* Type */; case 288 /* JSDocTypedefTag */: // If it has no name node, it shares the name with the value declaration below it. return node.name === undefined ? 1 /* Value */ | 2 /* Type */ : 2 /* Type */; case 268 /* EnumMember */: case 230 /* ClassDeclaration */: return 1 /* Value */ | 2 /* Type */; case 234 /* 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 /* EnumDeclaration */: case 242 /* NamedImports */: case 243 /* ImportSpecifier */: case 238 /* ImportEqualsDeclaration */: case 239 /* ImportDeclaration */: case 244 /* ExportAssignment */: case 245 /* ExportDeclaration */: return 7 /* All */; // An external module can be a Value case 269 /* SourceFile */: return 4 /* Namespace */ | 1 /* Value */; } return 7 /* All */; } ts.getMeaningFromDeclaration = getMeaningFromDeclaration; function getMeaningFromLocation(node) { if (node.kind === 269 /* SourceFile */) { return 1 /* Value */; } else if (node.parent.kind === 244 /* ExportAssignment */) { return 7 /* All */; } else if (isInRightSideOfInternalImportEqualsDeclaration(node)) { return getMeaningFromRightHandSideOfImportEquals(node); } else if (ts.isDeclarationName(node)) { return getMeaningFromDeclaration(node.parent); } else if (isTypeReference(node)) { return 2 /* Type */; } else if (isNamespaceReference(node)) { return 4 /* Namespace */; } else if (ts.isTypeParameterDeclaration(node.parent)) { ts.Debug.assert(ts.isJSDocTemplateTag(node.parent.parent)); // Else would be handled by isDeclarationName return 2 /* Type */; } else { return 1 /* Value */; } } ts.getMeaningFromLocation = getMeaningFromLocation; function getMeaningFromRightHandSideOfImportEquals(node) { ts.Debug.assert(node.kind === 71 /* Identifier */); // import a = |b|; // Namespace // import a = |b.c|; // Value, type, namespace // import a = |b.c|.d; // Namespace if (node.parent.kind === 144 /* QualifiedName */ && node.parent.right === node && node.parent.parent.kind === 238 /* ImportEqualsDeclaration */) { return 1 /* Value */ | 2 /* Type */ | 4 /* Namespace */; } return 4 /* Namespace */; } function isInRightSideOfInternalImportEqualsDeclaration(node) { while (node.parent.kind === 144 /* QualifiedName */) { node = node.parent; } return ts.isInternalModuleImportEqualsDeclaration(node.parent) && node.parent.moduleReference === node; } ts.isInRightSideOfInternalImportEqualsDeclaration = isInRightSideOfInternalImportEqualsDeclaration; function isNamespaceReference(node) { return isQualifiedNameNamespaceReference(node) || isPropertyAccessNamespaceReference(node); } function isQualifiedNameNamespaceReference(node) { var root = node; var isLastClause = true; if (root.parent.kind === 144 /* QualifiedName */) { while (root.parent && root.parent.kind === 144 /* QualifiedName */) { root = root.parent; } isLastClause = root.right === node; } return root.parent.kind === 160 /* TypeReference */ && !isLastClause; } function isPropertyAccessNamespaceReference(node) { var root = node; var isLastClause = true; if (root.parent.kind === 180 /* PropertyAccessExpression */) { while (root.parent && root.parent.kind === 180 /* PropertyAccessExpression */) { root = root.parent; } isLastClause = root.name === node; } if (!isLastClause && root.parent.kind === 202 /* ExpressionWithTypeArguments */ && root.parent.parent.kind === 263 /* HeritageClause */) { var decl = root.parent.parent.parent; return (decl.kind === 230 /* ClassDeclaration */ && root.parent.parent.token === 108 /* ImplementsKeyword */) || (decl.kind === 231 /* InterfaceDeclaration */ && root.parent.parent.token === 85 /* ExtendsKeyword */); } return false; } function isTypeReference(node) { if (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } switch (node.kind) { case 99 /* ThisKeyword */: return !ts.isExpressionNode(node); case 170 /* ThisType */: return true; } switch (node.parent.kind) { case 160 /* TypeReference */: return true; case 202 /* ExpressionWithTypeArguments */: return !ts.isExpressionWithTypeArgumentsInClassExtendsClause(node.parent); } return false; } function isCallExpressionTarget(node) { return isCallOrNewExpressionTarget(node, 182 /* CallExpression */); } ts.isCallExpressionTarget = isCallExpressionTarget; function isNewExpressionTarget(node) { return isCallOrNewExpressionTarget(node, 183 /* NewExpression */); } ts.isNewExpressionTarget = isNewExpressionTarget; function isCallOrNewExpressionTarget(node, kind) { var target = climbPastPropertyAccess(node); return target && target.parent && target.parent.kind === kind && target.parent.expression === target; } function climbPastPropertyAccess(node) { return isRightSideOfPropertyAccess(node) ? node.parent : node; } ts.climbPastPropertyAccess = climbPastPropertyAccess; function getTargetLabel(referenceNode, labelName) { while (referenceNode) { if (referenceNode.kind === 223 /* LabeledStatement */ && referenceNode.label.escapedText === labelName) { return referenceNode.label; } referenceNode = referenceNode.parent; } return undefined; } ts.getTargetLabel = getTargetLabel; function isJumpStatementTarget(node) { return node.kind === 71 /* Identifier */ && (node.parent.kind === 219 /* BreakStatement */ || node.parent.kind === 218 /* ContinueStatement */) && node.parent.label === node; } ts.isJumpStatementTarget = isJumpStatementTarget; function isLabelOfLabeledStatement(node) { return node.kind === 71 /* Identifier */ && node.parent.kind === 223 /* LabeledStatement */ && node.parent.label === node; } function isLabelName(node) { return isLabelOfLabeledStatement(node) || isJumpStatementTarget(node); } ts.isLabelName = isLabelName; function isRightSideOfQualifiedName(node) { return node.parent.kind === 144 /* QualifiedName */ && node.parent.right === node; } ts.isRightSideOfQualifiedName = isRightSideOfQualifiedName; function isRightSideOfPropertyAccess(node) { return node && node.parent && node.parent.kind === 180 /* PropertyAccessExpression */ && node.parent.name === node; } ts.isRightSideOfPropertyAccess = isRightSideOfPropertyAccess; function isNameOfModuleDeclaration(node) { return node.parent.kind === 234 /* ModuleDeclaration */ && node.parent.name === node; } ts.isNameOfModuleDeclaration = isNameOfModuleDeclaration; function isNameOfFunctionDeclaration(node) { return node.kind === 71 /* Identifier */ && ts.isFunctionLike(node.parent) && node.parent.name === node; } ts.isNameOfFunctionDeclaration = isNameOfFunctionDeclaration; function isLiteralNameOfPropertyDeclarationOrIndexAccess(node) { switch (node.parent.kind) { case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 265 /* PropertyAssignment */: case 268 /* EnumMember */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 234 /* ModuleDeclaration */: return ts.getNameOfDeclaration(node.parent) === node; case 181 /* ElementAccessExpression */: return node.parent.argumentExpression === node; case 145 /* ComputedPropertyName */: return true; case 174 /* LiteralType */: return node.parent.parent.kind === 172 /* IndexedAccessType */; } } ts.isLiteralNameOfPropertyDeclarationOrIndexAccess = isLiteralNameOfPropertyDeclarationOrIndexAccess; function isExpressionOfExternalModuleImportEqualsDeclaration(node) { return ts.isExternalModuleImportEqualsDeclaration(node.parent.parent) && ts.getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node; } ts.isExpressionOfExternalModuleImportEqualsDeclaration = isExpressionOfExternalModuleImportEqualsDeclaration; function getContainerNode(node) { if (node.kind === 288 /* JSDocTypedefTag */) { // This doesn't just apply to the node immediately under the comment, but to everything in its parent's scope. // node.parent = the JSDoc comment, node.parent.parent = the node having the comment. // Then we get parent again in the loop. node = node.parent.parent; } while (true) { node = node.parent; if (!node) { return undefined; } switch (node.kind) { case 269 /* SourceFile */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 234 /* ModuleDeclaration */: return node; } } } ts.getContainerNode = getContainerNode; function getNodeKind(node) { switch (node.kind) { case 269 /* SourceFile */: return ts.isExternalModule(node) ? "module" /* moduleElement */ : "script" /* scriptElement */; case 234 /* ModuleDeclaration */: return "module" /* moduleElement */; case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return "class" /* classElement */; case 231 /* InterfaceDeclaration */: return "interface" /* interfaceElement */; case 232 /* TypeAliasDeclaration */: return "type" /* typeElement */; case 233 /* EnumDeclaration */: return "enum" /* enumElement */; case 227 /* VariableDeclaration */: return getKindOfVariableDeclaration(node); case 177 /* BindingElement */: return getKindOfVariableDeclaration(ts.getRootDeclaration(node)); case 188 /* ArrowFunction */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: return "function" /* functionElement */; case 154 /* GetAccessor */: return "getter" /* memberGetAccessorElement */; case 155 /* SetAccessor */: return "setter" /* memberSetAccessorElement */; case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: return "method" /* memberFunctionElement */; case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return "property" /* memberVariableElement */; case 158 /* IndexSignature */: return "index" /* indexSignatureElement */; case 157 /* ConstructSignature */: return "construct" /* constructSignatureElement */; case 156 /* CallSignature */: return "call" /* callSignatureElement */; case 153 /* Constructor */: return "constructor" /* constructorImplementationElement */; case 146 /* TypeParameter */: return "type parameter" /* typeParameterElement */; case 268 /* EnumMember */: return "enum member" /* enumMemberElement */; case 147 /* Parameter */: return ts.hasModifier(node, 92 /* ParameterPropertyModifier */) ? "property" /* memberVariableElement */ : "parameter" /* parameterElement */; case 238 /* ImportEqualsDeclaration */: case 243 /* ImportSpecifier */: case 240 /* ImportClause */: case 247 /* ExportSpecifier */: case 241 /* NamespaceImport */: return "alias" /* alias */; case 288 /* JSDocTypedefTag */: return "type" /* typeElement */; case 195 /* BinaryExpression */: var kind = ts.getSpecialPropertyAssignmentKind(node); var right = node.right; switch (kind) { case 0 /* None */: return "" /* unknown */; case 1 /* ExportsProperty */: case 2 /* ModuleExports */: var rightKind = getNodeKind(right); return rightKind === "" /* unknown */ ? "const" /* constElement */ : rightKind; case 3 /* PrototypeProperty */: return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */; case 4 /* ThisProperty */: return "property" /* memberVariableElement */; // property case 5 /* Property */: // static method / property return ts.isFunctionExpression(right) ? "method" /* memberFunctionElement */ : "property" /* memberVariableElement */; default: { ts.assertTypeIsNever(kind); return "" /* unknown */; } } default: return "" /* unknown */; } function getKindOfVariableDeclaration(v) { return ts.isConst(v) ? "const" /* constElement */ : ts.isLet(v) ? "let" /* letElement */ : "var" /* variableElement */; } } ts.getNodeKind = getNodeKind; function isThis(node) { switch (node.kind) { case 99 /* ThisKeyword */: // case SyntaxKind.ThisType: TODO: GH#9267 return true; case 71 /* Identifier */: // 'this' as a parameter return ts.identifierIsThisKeyword(node) && node.parent.kind === 147 /* Parameter */; default: return false; } } ts.isThis = isThis; // Matches the beginning of a triple slash directive var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*= range.end; } ts.startEndContainsRange = startEndContainsRange; function rangeContainsStartEnd(range, start, end) { return range.pos <= start && range.end >= end; } ts.rangeContainsStartEnd = rangeContainsStartEnd; function rangeOverlapsWithStartEnd(r1, start, end) { return startEndOverlapsWithStartEnd(r1.pos, r1.end, start, end); } ts.rangeOverlapsWithStartEnd = rangeOverlapsWithStartEnd; function startEndOverlapsWithStartEnd(start1, end1, start2, end2) { var start = Math.max(start1, start2); var end = Math.min(end1, end2); return start < end; } ts.startEndOverlapsWithStartEnd = startEndOverlapsWithStartEnd; /** * Assumes `candidate.start <= position` holds. */ function positionBelongsToNode(candidate, position, sourceFile) { ts.Debug.assert(candidate.pos <= position); return position < candidate.end || !isCompletedNode(candidate, sourceFile); } ts.positionBelongsToNode = positionBelongsToNode; function isCompletedNode(n, sourceFile) { if (ts.nodeIsMissing(n)) { return false; } switch (n.kind) { case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 179 /* ObjectLiteralExpression */: case 175 /* ObjectBindingPattern */: case 164 /* TypeLiteral */: case 208 /* Block */: case 235 /* ModuleBlock */: case 236 /* CaseBlock */: case 242 /* NamedImports */: case 246 /* NamedExports */: return nodeEndsWith(n, 18 /* CloseBraceToken */, sourceFile); case 264 /* CatchClause */: return isCompletedNode(n.block, sourceFile); case 183 /* NewExpression */: if (!n.arguments) { return true; } // falls through case 182 /* CallExpression */: case 186 /* ParenthesizedExpression */: case 169 /* ParenthesizedType */: return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile); case 161 /* FunctionType */: case 162 /* ConstructorType */: return isCompletedNode(n.type, sourceFile); case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 157 /* ConstructSignature */: case 156 /* CallSignature */: case 188 /* ArrowFunction */: if (n.body) { return isCompletedNode(n.body, sourceFile); } if (n.type) { return isCompletedNode(n.type, sourceFile); } // Even though type parameters can be unclosed, we can get away with // having at least a closing paren. return hasChildOfKind(n, 20 /* CloseParenToken */, sourceFile); case 234 /* ModuleDeclaration */: return n.body && isCompletedNode(n.body, sourceFile); case 212 /* IfStatement */: if (n.elseStatement) { return isCompletedNode(n.elseStatement, sourceFile); } return isCompletedNode(n.thenStatement, sourceFile); case 211 /* ExpressionStatement */: return isCompletedNode(n.expression, sourceFile) || hasChildOfKind(n, 25 /* SemicolonToken */); case 178 /* ArrayLiteralExpression */: case 176 /* ArrayBindingPattern */: case 181 /* ElementAccessExpression */: case 145 /* ComputedPropertyName */: case 166 /* TupleType */: return nodeEndsWith(n, 22 /* CloseBracketToken */, sourceFile); case 158 /* IndexSignature */: if (n.type) { return isCompletedNode(n.type, sourceFile); } return hasChildOfKind(n, 22 /* CloseBracketToken */, sourceFile); case 261 /* CaseClause */: case 262 /* DefaultClause */: // there is no such thing as terminator token for CaseClause/DefaultClause so for simplicity always consider them non-completed return false; case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 214 /* WhileStatement */: return isCompletedNode(n.statement, sourceFile); case 213 /* DoStatement */: // rough approximation: if DoStatement has While keyword - then if node is completed is checking the presence of ')'; var hasWhileKeyword = findChildOfKind(n, 106 /* WhileKeyword */, sourceFile); if (hasWhileKeyword) { return nodeEndsWith(n, 20 /* CloseParenToken */, sourceFile); } return isCompletedNode(n.statement, sourceFile); case 163 /* TypeQuery */: return isCompletedNode(n.exprName, sourceFile); case 190 /* TypeOfExpression */: case 189 /* DeleteExpression */: case 191 /* VoidExpression */: case 198 /* YieldExpression */: case 199 /* SpreadElement */: var unaryWordExpression = n; return isCompletedNode(unaryWordExpression.expression, sourceFile); case 184 /* TaggedTemplateExpression */: return isCompletedNode(n.template, sourceFile); case 197 /* TemplateExpression */: var lastSpan = ts.lastOrUndefined(n.templateSpans); return isCompletedNode(lastSpan, sourceFile); case 206 /* TemplateSpan */: return ts.nodeIsPresent(n.literal); case 245 /* ExportDeclaration */: case 239 /* ImportDeclaration */: return ts.nodeIsPresent(n.moduleSpecifier); case 193 /* PrefixUnaryExpression */: return isCompletedNode(n.operand, sourceFile); case 195 /* BinaryExpression */: return isCompletedNode(n.right, sourceFile); case 196 /* ConditionalExpression */: return isCompletedNode(n.whenFalse, sourceFile); default: return true; } } ts.isCompletedNode = isCompletedNode; /* * Checks if node ends with 'expectedLastToken'. * If child at position 'length - 1' is 'SemicolonToken' it is skipped and 'expectedLastToken' is compared with child at position 'length - 2'. */ function nodeEndsWith(n, expectedLastToken, sourceFile) { var children = n.getChildren(sourceFile); if (children.length) { var last_2 = ts.lastOrUndefined(children); if (last_2.kind === expectedLastToken) { return true; } else if (last_2.kind === 25 /* SemicolonToken */ && children.length !== 1) { return children[children.length - 2].kind === expectedLastToken; } } return false; } function findListItemInfo(node) { var list = findContainingList(node); // It is possible at this point for syntaxList to be undefined, either if // node.parent had no list child, or if none of its list children contained // the span of node. If this happens, return undefined. The caller should // handle this case. if (!list) { return undefined; } var children = list.getChildren(); var listItemIndex = ts.indexOfNode(children, node); return { listItemIndex: listItemIndex, list: list }; } ts.findListItemInfo = findListItemInfo; function hasChildOfKind(n, kind, sourceFile) { return !!findChildOfKind(n, kind, sourceFile); } ts.hasChildOfKind = hasChildOfKind; function findChildOfKind(n, kind, sourceFile) { return ts.forEach(n.getChildren(sourceFile), function (c) { return c.kind === kind && c; }); } ts.findChildOfKind = findChildOfKind; function findContainingList(node) { // The node might be a list element (nonsynthetic) or a comma (synthetic). Either way, it will // be parented by the container of the SyntaxList, not the SyntaxList itself. // In order to find the list item index, we first need to locate SyntaxList itself and then search // for the position of the relevant node (or comma). var syntaxList = ts.forEach(node.parent.getChildren(), function (c) { // find syntax list that covers the span of the node if (ts.isSyntaxList(c) && c.pos <= node.pos && c.end >= node.end) { return c; } }); // Either we didn't find an appropriate list, or the list must contain us. ts.Debug.assert(!syntaxList || ts.contains(syntaxList.getChildren(), node)); return syntaxList; } ts.findContainingList = findContainingList; /* Gets the token whose text has range [start, end) and * position >= start and (position < end or (position === end && token is keyword or identifier)) */ function getTouchingWord(sourceFile, position, includeJsDocComment) { return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isWord(n.kind); }); } ts.getTouchingWord = getTouchingWord; /* Gets the token whose text has range [start, end) and position >= start * and (position < end or (position === end && token is keyword or identifier or numeric/string literal)) */ function getTouchingPropertyName(sourceFile, position, includeJsDocComment) { return getTouchingToken(sourceFile, position, includeJsDocComment, function (n) { return isPropertyName(n.kind); }); } ts.getTouchingPropertyName = getTouchingPropertyName; /** * Returns the token if position is in [start, end). * If position === end, returns the preceding token if includeItemAtEndPosition(previousToken) === true */ function getTouchingToken(sourceFile, position, includeJsDocComment, includePrecedingTokenAtEndPosition) { return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ false, includePrecedingTokenAtEndPosition, /*includeEndPosition*/ false, includeJsDocComment); } ts.getTouchingToken = getTouchingToken; /** Returns a token if position is in [start-of-leading-trivia, end) */ function getTokenAtPosition(sourceFile, position, includeJsDocComment, includeEndPosition) { return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, includeEndPosition, includeJsDocComment); } ts.getTokenAtPosition = getTokenAtPosition; /** Get the token whose text contains the position */ function getTokenAtPositionWorker(sourceFile, position, allowPositionInLeadingTrivia, includePrecedingTokenAtEndPosition, includeEndPosition, includeJsDocComment) { var current = sourceFile; outer: while (true) { if (ts.isToken(current)) { // exit early return current; } // find the child that contains 'position' for (var _i = 0, _a = current.getChildren(); _i < _a.length; _i++) { var child = _a[_i]; if (!includeJsDocComment && ts.isJSDocNode(child)) { continue; } var start = allowPositionInLeadingTrivia ? child.getFullStart() : child.getStart(sourceFile, includeJsDocComment); if (start > position) { // If this child begins after position, then all subsequent children will as well. break; } var end = child.getEnd(); if (position < end || (position === end && (child.kind === 1 /* EndOfFileToken */ || includeEndPosition))) { current = child; continue outer; } else if (includePrecedingTokenAtEndPosition && end === position) { var previousToken = findPrecedingToken(position, sourceFile, child); if (previousToken && includePrecedingTokenAtEndPosition(previousToken)) { return previousToken; } } } return current; } } /** * The token on the left of the position is the token that strictly includes the position * or sits to the left of the cursor if it is on a boundary. For example * * fo|o -> will return foo * foo |bar -> will return foo * */ function findTokenOnLeftOfPosition(file, position) { // Ideally, getTokenAtPosition should return a token. However, it is currently // broken, so we do a check to make sure the result was indeed a token. var tokenAtPosition = getTokenAtPosition(file, position, /*includeJsDocComment*/ false); if (ts.isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) { return tokenAtPosition; } return findPrecedingToken(position, file); } ts.findTokenOnLeftOfPosition = findTokenOnLeftOfPosition; function findNextToken(previousToken, parent) { return find(parent); function find(n) { if (ts.isToken(n) && n.pos === previousToken.end) { // this is token that starts at the end of previous token - return it return n; } var children = n.getChildren(); for (var _i = 0, children_3 = children; _i < children_3.length; _i++) { var child = children_3[_i]; var shouldDiveInChildNode = // previous token is enclosed somewhere in the child (child.pos <= previousToken.pos && child.end > previousToken.end) || // previous token ends exactly at the beginning of child (child.pos === previousToken.end); if (shouldDiveInChildNode && nodeHasTokens(child)) { return find(child); } } return undefined; } } ts.findNextToken = findNextToken; /** * Finds the rightmost token satisfying `token.end <= position`, * excluding `JsxText` tokens containing only whitespace. */ function findPrecedingToken(position, sourceFile, startNode, includeJsDoc) { var result = find(startNode || sourceFile); ts.Debug.assert(!(result && isWhiteSpaceOnlyJsxText(result))); return result; function findRightmostToken(n) { if (ts.isToken(n)) { return n; } var children = n.getChildren(); var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); return candidate && findRightmostToken(candidate); } function find(n) { if (ts.isToken(n)) { return n; } var children = n.getChildren(); for (var i = 0; i < children.length; i++) { var child = children[i]; // Note that the span of a node's tokens is [node.getStart(...), node.end). // Given that `position < child.end` and child has constituent tokens, we distinguish these cases: // 1) `position` precedes `child`'s tokens or `child` has no tokens (ie: in a comment or whitespace preceding `child`): // we need to find the last token in a previous child. // 2) `position` is within the same span: we recurse on `child`. if (position < child.end) { var start = child.getStart(sourceFile, includeJsDoc); var lookInPreviousChild = (start >= position) || // cursor in the leading trivia !nodeHasTokens(child) || isWhiteSpaceOnlyJsxText(child); if (lookInPreviousChild) { // actual start of the node is past the position - previous token should be at the end of previous child var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i); return candidate && findRightmostToken(candidate); } else { // candidate should be in this node return find(child); } } } ts.Debug.assert(startNode !== undefined || n.kind === 269 /* SourceFile */ || ts.isJSDocCommentContainingNode(n)); // Here we know that none of child token nodes embrace the position, // the only known case is when position is at the end of the file. // Try to find the rightmost token in the file without filtering. // Namely we are skipping the check: 'position < node.end' if (children.length) { var candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length); return candidate && findRightmostToken(candidate); } } /** * Finds the rightmost child to the left of `children[exclusiveStartPosition]` which is a non-all-whitespace token or has constituent tokens. */ function findRightmostChildNodeWithTokens(children, exclusiveStartPosition) { for (var i = exclusiveStartPosition - 1; i >= 0; i--) { var child = children[i]; if (isWhiteSpaceOnlyJsxText(child)) { ts.Debug.assert(i > 0, "`JsxText` tokens should not be the first child of `JsxElement | JsxSelfClosingElement`"); } else if (nodeHasTokens(children[i])) { return children[i]; } } } } ts.findPrecedingToken = findPrecedingToken; function isInString(sourceFile, position) { var previousToken = findPrecedingToken(position, sourceFile); if (previousToken && ts.isStringTextContainingNode(previousToken)) { var start = previousToken.getStart(); var end = previousToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. // 2. at the end position of an unterminated token. // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). if (start < position && position < end) { return true; } if (position === end) { return !!previousToken.isUnterminated; } } return false; } ts.isInString = isInString; /** * returns true if the position is in between the open and close elements of an JSX expression. */ function isInsideJsxElementOrAttribute(sourceFile, position) { var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); if (!token) { return false; } if (token.kind === 10 /* JsxText */) { return true; } //
Hello |
if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 10 /* JsxText */) { return true; } //
{ |
or
if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 260 /* JsxExpression */) { return true; } //
{ // | // } < /div> if (token && token.kind === 18 /* CloseBraceToken */ && token.parent.kind === 260 /* JsxExpression */) { return true; } //
|
if (token.kind === 27 /* LessThanToken */ && token.parent.kind === 253 /* JsxClosingElement */) { return true; } return false; } ts.isInsideJsxElementOrAttribute = isInsideJsxElementOrAttribute; function isWhiteSpaceOnlyJsxText(node) { return ts.isJsxText(node) && node.containsOnlyWhiteSpaces; } ts.isWhiteSpaceOnlyJsxText = isWhiteSpaceOnlyJsxText; function isInTemplateString(sourceFile, position) { var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); return ts.isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile); } ts.isInTemplateString = isInTemplateString; /** * Returns true if the cursor at position in sourceFile is within a comment. * * @param tokenAtPosition Must equal `getTokenAtPosition(sourceFile, position) * @param predicate Additional predicate to test on the comment range. */ function isInComment(sourceFile, position, tokenAtPosition, predicate) { return !!ts.formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ false, /*precedingToken*/ undefined, tokenAtPosition, predicate); } ts.isInComment = isInComment; function hasDocComment(sourceFile, position) { var token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // First, we have to see if this position actually landed in a comment. var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos); return ts.forEach(commentRanges, jsDocPrefix); function jsDocPrefix(c) { var text = sourceFile.text; return text.length >= c.pos + 3 && text[c.pos] === "/" && text[c.pos + 1] === "*" && text[c.pos + 2] === "*"; } } ts.hasDocComment = hasDocComment; function nodeHasTokens(n) { // If we have a token or node that has a non-zero width, it must have tokens. // Note: getWidth() does not take trivia into account. return n.getWidth() !== 0; } function getNodeModifiers(node) { var flags = ts.getCombinedModifierFlags(node); var result = []; if (flags & 8 /* Private */) result.push("private" /* privateMemberModifier */); if (flags & 16 /* Protected */) result.push("protected" /* protectedMemberModifier */); if (flags & 4 /* Public */) result.push("public" /* publicMemberModifier */); if (flags & 32 /* Static */) result.push("static" /* staticModifier */); if (flags & 128 /* Abstract */) result.push("abstract" /* abstractModifier */); if (flags & 1 /* Export */) result.push("export" /* exportedModifier */); if (node.flags & 2097152 /* Ambient */) result.push("declare" /* ambientModifier */); return result.length > 0 ? result.join(",") : "" /* none */; } ts.getNodeModifiers = getNodeModifiers; function getTypeArgumentOrTypeParameterList(node) { if (node.kind === 160 /* TypeReference */ || node.kind === 182 /* CallExpression */) { return node.typeArguments; } if (ts.isFunctionLike(node) || node.kind === 230 /* ClassDeclaration */ || node.kind === 231 /* InterfaceDeclaration */) { return node.typeParameters; } return undefined; } ts.getTypeArgumentOrTypeParameterList = getTypeArgumentOrTypeParameterList; function isWord(kind) { return kind === 71 /* Identifier */ || ts.isKeyword(kind); } ts.isWord = isWord; function isPropertyName(kind) { return kind === 9 /* StringLiteral */ || kind === 8 /* NumericLiteral */ || isWord(kind); } function isComment(kind) { return kind === 2 /* SingleLineCommentTrivia */ || kind === 3 /* MultiLineCommentTrivia */; } ts.isComment = isComment; function isStringOrRegularExpressionOrTemplateLiteral(kind) { if (kind === 9 /* StringLiteral */ || kind === 12 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(kind)) { return true; } return false; } ts.isStringOrRegularExpressionOrTemplateLiteral = isStringOrRegularExpressionOrTemplateLiteral; function isPunctuation(kind) { return 17 /* FirstPunctuation */ <= kind && kind <= 70 /* LastPunctuation */; } ts.isPunctuation = isPunctuation; function isInsideTemplateLiteral(node, position) { return ts.isTemplateLiteralKind(node.kind) && (node.getStart() < position && position < node.getEnd()) || (!!node.isUnterminated && position === node.getEnd()); } ts.isInsideTemplateLiteral = isInsideTemplateLiteral; function isAccessibilityModifier(kind) { switch (kind) { case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: return true; } return false; } ts.isAccessibilityModifier = isAccessibilityModifier; function cloneCompilerOptions(options) { var result = ts.clone(options); ts.setConfigFileInOptions(result, options && options.configFile); return result; } ts.cloneCompilerOptions = cloneCompilerOptions; function isArrayLiteralOrObjectLiteralDestructuringPattern(node) { if (node.kind === 178 /* ArrayLiteralExpression */ || node.kind === 179 /* ObjectLiteralExpression */) { // [a,b,c] from: // [a, b, c] = someExpression; if (node.parent.kind === 195 /* BinaryExpression */ && node.parent.left === node && node.parent.operatorToken.kind === 58 /* EqualsToken */) { return true; } // [a, b, c] from: // for([a, b, c] of expression) if (node.parent.kind === 217 /* 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 === 265 /* PropertyAssignment */ ? node.parent.parent : node.parent)) { return true; } } return false; } ts.isArrayLiteralOrObjectLiteralDestructuringPattern = isArrayLiteralOrObjectLiteralDestructuringPattern; function hasTrailingDirectorySeparator(path) { var lastCharacter = path.charAt(path.length - 1); return lastCharacter === "/" || lastCharacter === "\\"; } ts.hasTrailingDirectorySeparator = hasTrailingDirectorySeparator; function isInReferenceComment(sourceFile, position) { return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) { var commentText = sourceFile.text.substring(c.pos, c.end); return tripleSlashDirectivePrefixRegex.test(commentText); }); } ts.isInReferenceComment = isInReferenceComment; function isInNonReferenceComment(sourceFile, position) { return isInComment(sourceFile, position, /*tokenAtPosition*/ undefined, function (c) { var commentText = sourceFile.text.substring(c.pos, c.end); return !tripleSlashDirectivePrefixRegex.test(commentText); }); } ts.isInNonReferenceComment = isInNonReferenceComment; function createTextSpanFromNode(node, sourceFile) { return ts.createTextSpanFromBounds(node.getStart(sourceFile), node.getEnd()); } ts.createTextSpanFromNode = createTextSpanFromNode; function createTextSpanFromRange(range) { return ts.createTextSpanFromBounds(range.pos, range.end); } ts.createTextSpanFromRange = createTextSpanFromRange; ts.typeKeywords = [ 119 /* AnyKeyword */, 122 /* BooleanKeyword */, 130 /* NeverKeyword */, 133 /* NumberKeyword */, 134 /* ObjectKeyword */, 136 /* StringKeyword */, 137 /* SymbolKeyword */, 105 /* VoidKeyword */, ]; function isTypeKeyword(kind) { return ts.contains(ts.typeKeywords, kind); } ts.isTypeKeyword = isTypeKeyword; /** True if the symbol is for an external module, as opposed to a namespace. */ function isExternalModuleSymbol(moduleSymbol) { ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */)); return moduleSymbol.name.charCodeAt(0) === 34 /* doubleQuote */; } ts.isExternalModuleSymbol = isExternalModuleSymbol; /** Returns `true` the first time it encounters a node and `false` afterwards. */ function nodeSeenTracker() { var seen = []; return function (node) { var id = ts.getNodeId(node); return !seen[id] && (seen[id] = true); }; } ts.nodeSeenTracker = nodeSeenTracker; })(ts || (ts = {})); // Display-part writer helpers /* @internal */ (function (ts) { function isFirstDeclarationOfSymbolParameter(symbol) { return symbol.declarations && symbol.declarations.length > 0 && symbol.declarations[0].kind === 147 /* Parameter */; } ts.isFirstDeclarationOfSymbolParameter = isFirstDeclarationOfSymbolParameter; var displayPartWriter = getDisplayPartWriter(); function getDisplayPartWriter() { var displayParts; var lineStart; var indent; resetWriter(); return { displayParts: function () { return displayParts; }, writeKeyword: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.keyword); }, writeOperator: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.operator); }, writePunctuation: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.punctuation); }, writeSpace: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.space); }, writeStringLiteral: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.stringLiteral); }, writeParameter: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.parameterName); }, writeProperty: function (text) { return writeKind(text, ts.SymbolDisplayPartKind.propertyName); }, writeSymbol: writeSymbol, writeLine: writeLine, increaseIndent: function () { indent++; }, decreaseIndent: function () { indent--; }, clear: resetWriter, trackSymbol: ts.noop, reportInaccessibleThisError: ts.noop, reportInaccessibleUniqueSymbolError: ts.noop, reportPrivateInBaseOfClassExpression: ts.noop, }; function writeIndent() { if (lineStart) { var indentString = ts.getIndentString(indent); if (indentString) { displayParts.push(displayPart(indentString, ts.SymbolDisplayPartKind.space)); } lineStart = false; } } function writeKind(text, kind) { writeIndent(); displayParts.push(displayPart(text, kind)); } function writeSymbol(text, symbol) { writeIndent(); displayParts.push(symbolPart(text, symbol)); } function writeLine() { displayParts.push(lineBreakPart()); lineStart = true; } function resetWriter() { displayParts = []; lineStart = true; indent = 0; } } function symbolPart(text, symbol) { return displayPart(text, displayPartKind(symbol)); function displayPartKind(symbol) { var flags = symbol.flags; if (flags & 3 /* Variable */) { return isFirstDeclarationOfSymbolParameter(symbol) ? ts.SymbolDisplayPartKind.parameterName : ts.SymbolDisplayPartKind.localName; } else if (flags & 4 /* Property */) { return ts.SymbolDisplayPartKind.propertyName; } else if (flags & 32768 /* GetAccessor */) { return ts.SymbolDisplayPartKind.propertyName; } else if (flags & 65536 /* SetAccessor */) { return ts.SymbolDisplayPartKind.propertyName; } else if (flags & 8 /* EnumMember */) { return ts.SymbolDisplayPartKind.enumMemberName; } else if (flags & 16 /* Function */) { return ts.SymbolDisplayPartKind.functionName; } else if (flags & 32 /* Class */) { return ts.SymbolDisplayPartKind.className; } else if (flags & 64 /* Interface */) { return ts.SymbolDisplayPartKind.interfaceName; } else if (flags & 384 /* Enum */) { return ts.SymbolDisplayPartKind.enumName; } else if (flags & 1536 /* Module */) { return ts.SymbolDisplayPartKind.moduleName; } else if (flags & 8192 /* Method */) { return ts.SymbolDisplayPartKind.methodName; } else if (flags & 262144 /* TypeParameter */) { return ts.SymbolDisplayPartKind.typeParameterName; } else if (flags & 524288 /* TypeAlias */) { return ts.SymbolDisplayPartKind.aliasName; } else if (flags & 2097152 /* Alias */) { return ts.SymbolDisplayPartKind.aliasName; } return ts.SymbolDisplayPartKind.text; } } ts.symbolPart = symbolPart; function displayPart(text, kind) { return { text: text, kind: ts.SymbolDisplayPartKind[kind] }; } ts.displayPart = displayPart; function spacePart() { return displayPart(" ", ts.SymbolDisplayPartKind.space); } ts.spacePart = spacePart; function keywordPart(kind) { return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.keyword); } ts.keywordPart = keywordPart; function punctuationPart(kind) { return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.punctuation); } ts.punctuationPart = punctuationPart; function operatorPart(kind) { return displayPart(ts.tokenToString(kind), ts.SymbolDisplayPartKind.operator); } ts.operatorPart = operatorPart; function textOrKeywordPart(text) { var kind = ts.stringToToken(text); return kind === undefined ? textPart(text) : keywordPart(kind); } ts.textOrKeywordPart = textOrKeywordPart; function textPart(text) { return displayPart(text, ts.SymbolDisplayPartKind.text); } ts.textPart = textPart; var carriageReturnLineFeed = "\r\n"; /** * The default is CRLF. */ function getNewLineOrDefaultFromHost(host) { return host.getNewLine ? host.getNewLine() : carriageReturnLineFeed; } ts.getNewLineOrDefaultFromHost = getNewLineOrDefaultFromHost; function lineBreakPart() { return displayPart("\n", ts.SymbolDisplayPartKind.lineBreak); } ts.lineBreakPart = lineBreakPart; function mapToDisplayParts(writeDisplayParts) { try { writeDisplayParts(displayPartWriter); return displayPartWriter.displayParts(); } finally { displayPartWriter.clear(); } } ts.mapToDisplayParts = mapToDisplayParts; function typeToDisplayParts(typechecker, type, enclosingDeclaration, flags) { return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags); }); } ts.typeToDisplayParts = typeToDisplayParts; function symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration, meaning, flags) { return mapToDisplayParts(function (writer) { typeChecker.getSymbolDisplayBuilder().buildSymbolDisplay(symbol, writer, enclosingDeclaration, meaning, flags); }); } ts.symbolToDisplayParts = symbolToDisplayParts; function signatureToDisplayParts(typechecker, signature, enclosingDeclaration, flags) { flags |= 65536 /* UseAliasDefinedOutsideCurrentScope */; return mapToDisplayParts(function (writer) { typechecker.getSymbolDisplayBuilder().buildSignatureDisplay(signature, writer, enclosingDeclaration, flags); }); } ts.signatureToDisplayParts = signatureToDisplayParts; function getDeclaredName(typeChecker, symbol, location) { // If this is an export or import specifier it could have been renamed using the 'as' syntax. // If so we want to search for whatever is under the cursor. if (isImportOrExportSpecifierName(location) || ts.isStringOrNumericLiteral(location) && location.parent.kind === 145 /* ComputedPropertyName */) { return ts.getTextOfIdentifierOrLiteral(location); } // Try to get the local symbol if we're dealing with an 'export default' // since that symbol has the "true" name. var localExportDefaultSymbol = ts.getLocalSymbolForExportDefault(symbol); return typeChecker.symbolToString(localExportDefaultSymbol || symbol); } ts.getDeclaredName = getDeclaredName; function isImportOrExportSpecifierName(location) { return location.parent && (location.parent.kind === 243 /* ImportSpecifier */ || location.parent.kind === 247 /* ExportSpecifier */) && location.parent.propertyName === location; } ts.isImportOrExportSpecifierName = isImportOrExportSpecifierName; /** * Strip off existed single quotes or double quotes from a given string * * @return non-quoted string */ function stripQuotes(name) { var length = name.length; if (length >= 2 && name.charCodeAt(0) === name.charCodeAt(length - 1) && ts.isSingleOrDoubleQuote(name.charCodeAt(0))) { return name.substring(1, length - 1); } return name; } ts.stripQuotes = stripQuotes; function scriptKindIs(fileName, host) { var scriptKinds = []; for (var _i = 2; _i < arguments.length; _i++) { scriptKinds[_i - 2] = arguments[_i]; } var scriptKind = getScriptKind(fileName, host); return ts.forEach(scriptKinds, function (k) { return k === scriptKind; }); } ts.scriptKindIs = scriptKindIs; function getScriptKind(fileName, host) { // First check to see if the script kind was specified by the host. Chances are the host // may override the default script kind for the file extension. return ts.ensureScriptKind(fileName, host && host.getScriptKind && host.getScriptKind(fileName)); } ts.getScriptKind = getScriptKind; function getUniqueSymbolId(symbol, checker) { return ts.getSymbolId(ts.skipAlias(symbol, checker)); } ts.getUniqueSymbolId = getUniqueSymbolId; function getFirstNonSpaceCharacterPosition(text, position) { while (ts.isWhiteSpaceLike(text.charCodeAt(position))) { position += 1; } return position; } ts.getFirstNonSpaceCharacterPosition = getFirstNonSpaceCharacterPosition; function getOpenBrace(constructor, sourceFile) { // First token is the open curly, this is where we want to put the 'super' call. return constructor.body.getFirstToken(sourceFile); } ts.getOpenBrace = getOpenBrace; function getOpenBraceOfClassLike(declaration, sourceFile) { return ts.getTokenAtPosition(sourceFile, declaration.members.pos - 1, /*includeJsDocComment*/ false); } ts.getOpenBraceOfClassLike = getOpenBraceOfClassLike; function getSourceFileImportLocation(_a) { var text = _a.text; var shebang = ts.getShebang(text); var position = 0; if (shebang !== undefined) { position = shebang.length; advancePastLineBreak(); } // For a source file, it is possible there are detached comments we should not skip var ranges = ts.getLeadingCommentRanges(text, position); if (!ranges) return position; // However we should still skip a pinned comment at the top if (ranges.length && ranges[0].kind === 3 /* MultiLineCommentTrivia */ && ts.isPinnedComment(text, ranges[0])) { position = ranges[0].end; advancePastLineBreak(); ranges = ranges.slice(1); } // As well as any triple slash references for (var _i = 0, ranges_1 = ranges; _i < ranges_1.length; _i++) { var range = ranges_1[_i]; if (range.kind === 2 /* SingleLineCommentTrivia */ && ts.isRecognizedTripleSlashComment(text, range.pos, range.end)) { position = range.end; advancePastLineBreak(); continue; } break; } return position; function advancePastLineBreak() { if (position < text.length) { var charCode = text.charCodeAt(position); if (ts.isLineBreak(charCode)) { position++; if (position < text.length && charCode === 13 /* carriageReturn */ && text.charCodeAt(position) === 10 /* lineFeed */) { position++; } } } } } ts.getSourceFileImportLocation = getSourceFileImportLocation; /** * Creates a deep, memberwise clone of a node with no source map location. * * WARNING: This is an expensive operation and is only intended to be used in refactorings * and code fixes (because those are triggered by explicit user actions). */ function getSynthesizedDeepClone(node) { if (node === undefined) { return undefined; } var visited = ts.visitEachChild(node, getSynthesizedDeepClone, ts.nullTransformationContext); if (visited === node) { // This only happens for leaf nodes - internal nodes always see their children change. var clone_7 = ts.getSynthesizedClone(node); if (ts.isStringLiteral(clone_7)) { clone_7.textSourceNode = node; } else if (ts.isNumericLiteral(clone_7)) { clone_7.numericLiteralFlags = node.numericLiteralFlags; } clone_7.pos = node.pos; clone_7.end = node.end; return clone_7; } // PERF: As an optimization, rather than calling getSynthesizedClone, we'll update // the new node created by visitEachChild with the extra changes getSynthesizedClone // would have made. visited.parent = undefined; return visited; } ts.getSynthesizedDeepClone = getSynthesizedDeepClone; /** * Sets EmitFlags to suppress leading and trailing trivia on the node. */ /* @internal */ function suppressLeadingAndTrailingTrivia(node) { ts.Debug.assert(node !== undefined); suppressLeading(node); suppressTrailing(node); function suppressLeading(node) { ts.addEmitFlags(node, 512 /* NoLeadingComments */); var firstChild = ts.forEachChild(node, function (child) { return child; }); if (firstChild) { suppressLeading(firstChild); } } function suppressTrailing(node) { ts.addEmitFlags(node, 1024 /* NoTrailingComments */); var lastChild = undefined; ts.forEachChild(node, function (child) { return (lastChild = child, undefined); }, function (children) { // As an optimization, jump straight to the end of the list. if (children.length) { lastChild = ts.last(children); } return undefined; }); if (lastChild) { suppressTrailing(lastChild); } } } ts.suppressLeadingAndTrailingTrivia = suppressLeadingAndTrailingTrivia; })(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. /// /* @internal */ var ts; (function (ts) { var BreakpointResolver; (function (BreakpointResolver) { /** * Get the breakpoint span in given sourceFile */ function spanInSourceFileAtLocation(sourceFile, position) { // Cannot set breakpoint in dts file if (sourceFile.isDeclarationFile) { return undefined; } var tokenAtLocation = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); var lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line; if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) { // Get previous token if the token is returned starts on new line // eg: let x =10; |--- cursor is here // let y = 10; // token at position will return let keyword on second line as the token but we would like to use // token on same line if trailing trivia (comments or white spaces on same line) part of the last token on that line tokenAtLocation = ts.findPrecedingToken(tokenAtLocation.pos, sourceFile); // It's a blank line if (!tokenAtLocation || sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getEnd()).line !== lineOfPosition) { return undefined; } } // Cannot set breakpoint in ambient declarations if (tokenAtLocation.flags & 2097152 /* Ambient */) { 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 209 /* VariableStatement */: // Span on first variable declaration return spanInVariableDeclaration(node.declarationList.declarations[0]); case 227 /* VariableDeclaration */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return spanInVariableDeclaration(node); case 147 /* Parameter */: return spanInParameterDeclaration(node); case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 153 /* Constructor */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return spanInFunctionDeclaration(node); case 208 /* Block */: if (ts.isFunctionBlock(node)) { return spanInFunctionBlock(node); } // falls through case 235 /* ModuleBlock */: return spanInBlock(node); case 264 /* CatchClause */: return spanInBlock(node.block); case 211 /* ExpressionStatement */: // span on the expression return textSpan(node.expression); case 220 /* ReturnStatement */: // span on return keyword and expression if present return textSpan(node.getChildAt(0), node.expression); case 214 /* WhileStatement */: // Span on while(...) return textSpanEndingAtNextToken(node, node.expression); case 213 /* DoStatement */: // span in statement of the do statement return spanInNode(node.statement); case 226 /* DebuggerStatement */: // span on debugger keyword return textSpan(node.getChildAt(0)); case 212 /* IfStatement */: // set on if(..) span return textSpanEndingAtNextToken(node, node.expression); case 223 /* LabeledStatement */: // span in statement return spanInNode(node.statement); case 219 /* BreakStatement */: case 218 /* ContinueStatement */: // On break or continue keyword and label if present return textSpan(node.getChildAt(0), node.label); case 215 /* ForStatement */: return spanInForStatement(node); case 216 /* ForInStatement */: // span of for (a in ...) return textSpanEndingAtNextToken(node, node.expression); case 217 /* ForOfStatement */: // span in initializer return spanInInitializerOfForLike(node); case 222 /* SwitchStatement */: // span on switch(...) return textSpanEndingAtNextToken(node, node.expression); case 261 /* CaseClause */: case 262 /* DefaultClause */: // span in first statement of the clause return spanInNode(node.statements[0]); case 225 /* TryStatement */: // span in try block return spanInBlock(node.tryBlock); case 224 /* ThrowStatement */: // span in throw ... return textSpan(node, node.expression); case 244 /* ExportAssignment */: // span on export = id return textSpan(node, node.expression); case 238 /* ImportEqualsDeclaration */: // import statement without including semicolon return textSpan(node, node.moduleReference); case 239 /* ImportDeclaration */: // import statement without including semicolon return textSpan(node, node.moduleSpecifier); case 245 /* ExportDeclaration */: // import statement without including semicolon return textSpan(node, node.moduleSpecifier); case 234 /* ModuleDeclaration */: // span on complete module if it is instantiated if (ts.getModuleInstanceState(node) !== 1 /* Instantiated */) { return undefined; } // falls through case 230 /* ClassDeclaration */: case 233 /* EnumDeclaration */: case 268 /* EnumMember */: case 177 /* BindingElement */: // span on complete node return textSpan(node); case 221 /* WithStatement */: // span in statement return spanInNode(node.statement); case 148 /* Decorator */: return spanInNodeArray(node.parent.decorators); case 175 /* ObjectBindingPattern */: case 176 /* ArrayBindingPattern */: return spanInBindingPattern(node); // No breakpoint in interface, type alias case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: return undefined; // Tokens: case 25 /* SemicolonToken */: case 1 /* EndOfFileToken */: return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile)); case 26 /* CommaToken */: return spanInPreviousNode(node); case 17 /* OpenBraceToken */: return spanInOpenBraceToken(node); case 18 /* CloseBraceToken */: return spanInCloseBraceToken(node); case 22 /* CloseBracketToken */: return spanInCloseBracketToken(node); case 19 /* OpenParenToken */: return spanInOpenParenToken(node); case 20 /* CloseParenToken */: return spanInCloseParenToken(node); case 56 /* ColonToken */: return spanInColonToken(node); case 29 /* GreaterThanToken */: case 27 /* LessThanToken */: return spanInGreaterThanOrLessThanToken(node); // Keywords: case 106 /* WhileKeyword */: return spanInWhileKeyword(node); case 82 /* ElseKeyword */: case 74 /* CatchKeyword */: case 87 /* FinallyKeyword */: return spanInNextNode(node); case 143 /* OfKeyword */: return spanInOfKeyword(node); default: // Destructuring pattern in destructuring assignment // [a, b, c] of // [a, b, c] = expression if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node)) { return spanInArrayLiteralOrObjectLiteralDestructuringPattern(node); } // Set breakpoint on identifier element of destructuring pattern // a or ...c or d: x from // [a, b, ...c] or { a, b } or { d: x } from destructuring pattern if ((node.kind === 71 /* Identifier */ || node.kind === 199 /* SpreadElement */ || node.kind === 265 /* PropertyAssignment */ || node.kind === 266 /* ShorthandPropertyAssignment */) && ts.isArrayLiteralOrObjectLiteralDestructuringPattern(node.parent)) { return textSpan(node); } if (node.kind === 195 /* BinaryExpression */) { var binaryExpression = node; // Set breakpoint in destructuring pattern if its destructuring assignment // [a, b, c] or {a, b, c} of // [a, b, c] = expression or // {a, b, c} = expression if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left)) { return spanInArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left); } if (binaryExpression.operatorToken.kind === 58 /* EqualsToken */ && ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.parent)) { // Set breakpoint on assignment expression element of destructuring pattern // a = expression of // [a = expression, b, c] = someExpression or // { a = expression, b, c } = someExpression return textSpan(node); } if (binaryExpression.operatorToken.kind === 26 /* CommaToken */) { return spanInNode(binaryExpression.left); } } if (ts.isExpressionNode(node)) { switch (node.parent.kind) { case 213 /* DoStatement */: // Set span as if on while keyword return spanInPreviousNode(node); case 148 /* Decorator */: // Set breakpoint on the decorator emit return spanInNode(node.parent); case 215 /* ForStatement */: case 217 /* ForOfStatement */: return textSpan(node); case 195 /* BinaryExpression */: if (node.parent.operatorToken.kind === 26 /* CommaToken */) { // If this is a comma expression, the breakpoint is possible in this expression return textSpan(node); } break; case 188 /* 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 === 265 /* 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 === 185 /* 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 === 227 /* VariableDeclaration */ || node.parent.kind === 147 /* Parameter */)) { var paramOrVarDecl = node.parent; if (paramOrVarDecl.initializer === node || paramOrVarDecl.type === node || ts.isAssignmentOperator(node.kind)) { return spanInPreviousNode(node); } } if (node.parent.kind === 195 /* BinaryExpression */) { var binaryExpression = node.parent; if (ts.isArrayLiteralOrObjectLiteralDestructuringPattern(binaryExpression.left) && (binaryExpression.right === node || binaryExpression.operatorToken === node)) { // If initializer of destructuring assignment move to previous token return spanInPreviousNode(node); } } // Default go to parent to set the breakpoint return spanInNode(node.parent); } } function textSpanFromVariableDeclaration(variableDeclaration) { if (variableDeclaration.parent.kind === 228 /* VariableDeclarationList */ && variableDeclaration.parent.declarations[0] === variableDeclaration) { // First declaration - include let keyword return textSpan(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent), variableDeclaration); } else { // Span only on this declaration return textSpan(variableDeclaration); } } function spanInVariableDeclaration(variableDeclaration) { // If declaration of for in statement, just set the span in parent if (variableDeclaration.parent.parent.kind === 216 /* ForInStatement */) { return spanInNode(variableDeclaration.parent.parent); } // If this is a destructuring pattern, set breakpoint in binding pattern if (ts.isBindingPattern(variableDeclaration.name)) { return spanInBindingPattern(variableDeclaration.name); } // Breakpoint is possible in variableDeclaration only if there is initialization // or its declaration from 'for of' if (variableDeclaration.initializer || ts.hasModifier(variableDeclaration, 1 /* Export */) || variableDeclaration.parent.parent.kind === 217 /* ForOfStatement */) { return textSpanFromVariableDeclaration(variableDeclaration); } if (variableDeclaration.parent.kind === 228 /* VariableDeclarationList */ && variableDeclaration.parent.declarations[0] !== variableDeclaration) { // If we cannot set breakpoint on this declaration, set it on previous one // Because the variable declaration may be binding pattern and // we would like to set breakpoint in last binding element if that's the case, // use preceding token instead return spanInNode(ts.findPrecedingToken(variableDeclaration.pos, sourceFile, variableDeclaration.parent)); } } function canHaveSpanInParameterDeclaration(parameter) { // Breakpoint is possible on parameter only if it has initializer, is a rest parameter, or has public or private modifier return !!parameter.initializer || parameter.dotDotDotToken !== undefined || ts.hasModifier(parameter, 4 /* Public */ | 8 /* Private */); } function spanInParameterDeclaration(parameter) { if (ts.isBindingPattern(parameter.name)) { // Set breakpoint in binding pattern return spanInBindingPattern(parameter.name); } else if (canHaveSpanInParameterDeclaration(parameter)) { return textSpan(parameter); } else { var functionDeclaration = parameter.parent; var indexOfParameter = ts.indexOf(functionDeclaration.parameters, parameter); if (indexOfParameter) { // Not a first parameter, go to previous parameter return spanInParameterDeclaration(functionDeclaration.parameters[indexOfParameter - 1]); } else { // Set breakpoint in the function declaration body return spanInNode(functionDeclaration.body); } } } function canFunctionHaveSpanInWholeDeclaration(functionDeclaration) { return ts.hasModifier(functionDeclaration, 1 /* Export */) || (functionDeclaration.parent.kind === 230 /* ClassDeclaration */ && functionDeclaration.kind !== 153 /* 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 234 /* ModuleDeclaration */: if (ts.getModuleInstanceState(block.parent) !== 1 /* Instantiated */) { return undefined; } // falls through // Set on parent if on same line otherwise on first statement case 214 /* WhileStatement */: case 212 /* IfStatement */: case 216 /* 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 215 /* ForStatement */: case 217 /* 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 === 228 /* 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 !== 201 /* OmittedExpression */ ? element : undefined; }); if (firstBindingElement) { return spanInNode(firstBindingElement); } // Empty binding pattern of binding element, set breakpoint on binding element if (bindingPattern.parent.kind === 177 /* BindingElement */) { return textSpan(bindingPattern.parent); } // Variable declaration is used as the span return textSpanFromVariableDeclaration(bindingPattern.parent); } function spanInArrayLiteralOrObjectLiteralDestructuringPattern(node) { ts.Debug.assert(node.kind !== 176 /* ArrayBindingPattern */ && node.kind !== 175 /* ObjectBindingPattern */); var elements = node.kind === 178 /* ArrayLiteralExpression */ ? node.elements : node.properties; var firstBindingElement = ts.forEach(elements, function (element) { return element.kind !== 201 /* 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 === 195 /* BinaryExpression */ ? node.parent : node); } // Tokens: function spanInOpenBraceToken(node) { switch (node.parent.kind) { case 233 /* EnumDeclaration */: var enumDeclaration = node.parent; return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), enumDeclaration.members.length ? enumDeclaration.members[0] : enumDeclaration.getLastToken(sourceFile)); case 230 /* ClassDeclaration */: var classDeclaration = node.parent; return spanInNodeIfStartsOnSameLine(ts.findPrecedingToken(node.pos, sourceFile, node.parent), classDeclaration.members.length ? classDeclaration.members[0] : classDeclaration.getLastToken(sourceFile)); case 236 /* 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 235 /* ModuleBlock */: // If this is not an instantiated module block, no bp span if (ts.getModuleInstanceState(node.parent.parent) !== 1 /* Instantiated */) { return undefined; } // falls through case 233 /* EnumDeclaration */: case 230 /* ClassDeclaration */: // Span on close brace token return textSpan(node); case 208 /* Block */: if (ts.isFunctionBlock(node.parent)) { // Span on close brace token return textSpan(node); } // falls through case 264 /* CatchClause */: return spanInNode(ts.lastOrUndefined(node.parent.statements)); case 236 /* 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 175 /* 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 176 /* 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 === 213 /* DoStatement */ || // Go to while keyword and do action instead node.parent.kind === 182 /* CallExpression */ || node.parent.kind === 183 /* NewExpression */) { return spanInPreviousNode(node); } if (node.parent.kind === 186 /* 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 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 153 /* Constructor */: case 214 /* WhileStatement */: case 213 /* DoStatement */: case 215 /* ForStatement */: case 217 /* ForOfStatement */: case 182 /* CallExpression */: case 183 /* NewExpression */: case 186 /* 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 === 265 /* PropertyAssignment */ || node.parent.kind === 147 /* Parameter */) { return spanInPreviousNode(node); } return spanInNode(node.parent); } function spanInGreaterThanOrLessThanToken(node) { if (node.parent.kind === 185 /* TypeAssertionExpression */) { return spanInNextNode(node); } return spanInNode(node.parent); } function spanInWhileKeyword(node) { if (node.parent.kind === 213 /* 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 === 217 /* 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 = {})); var ts; (function (ts) { function createClassifier() { var scanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ false); function getClassificationsForLine(text, lexState, syntacticClassifierAbsent) { return convertClassificationsToResult(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 token = 0 /* Unknown */; var lastNonTriviaToken = 0 /* Unknown */; // 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 = []; var _a = getPrefixFromLexState(lexState), prefix = _a.prefix, pushTemplate = _a.pushTemplate; text = prefix + text; var offset = prefix.length; if (pushTemplate) { templateStack.push(14 /* TemplateHead */); } scanner.setText(text); var endOfLineState = 0 /* None */; var 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 tokens. It's a weak heuristic, but should // work well enough in practice. var angleBracketStack = 0; do { token = scanner.scan(); if (!ts.isTrivia(token)) { handleToken(); lastNonTriviaToken = token; } var end = scanner.getTextPos(); pushEncodedClassification(scanner.getTokenPos(), end, offset, classFromKind(token), spans); if (end >= text.length) { var end_1 = getNewEndOfLineState(scanner, token, ts.lastOrUndefined(templateStack)); if (end_1 !== undefined) { endOfLineState = end_1; } } } while (token !== 1 /* EndOfFileToken */); function handleToken() { switch (token) { case 41 /* SlashToken */: case 63 /* SlashEqualsToken */: if (!noRegexTable[lastNonTriviaToken] && scanner.reScanSlashToken() === 12 /* RegularExpressionLiteral */) { token = 12 /* RegularExpressionLiteral */; } break; case 27 /* LessThanToken */: if (lastNonTriviaToken === 71 /* Identifier */) { // 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++; } break; case 29 /* GreaterThanToken */: if (angleBracketStack > 0) { // If we think we're currently in something generic, then mark that that // generic entity is complete. angleBracketStack--; } break; case 119 /* AnyKeyword */: case 136 /* StringKeyword */: case 133 /* NumberKeyword */: case 122 /* BooleanKeyword */: case 137 /* SymbolKeyword */: if (angleBracketStack > 0 && !syntacticClassifierAbsent) { // If it looks like we're could be in something generic, don't classify this // as a keyword. We may just get overwritten by the syntactic classifier, // causing a noisy experience for the user. token = 71 /* Identifier */; } break; case 14 /* TemplateHead */: templateStack.push(token); break; case 17 /* OpenBraceToken */: // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { templateStack.push(token); } break; case 18 /* CloseBraceToken */: // If we don't have anything on the template stack, // then we aren't trying to keep track of a previously scanned template head. if (templateStack.length > 0) { var lastTemplateStackToken = ts.lastOrUndefined(templateStack); if (lastTemplateStackToken === 14 /* TemplateHead */) { token = scanner.reScanTemplateToken(); // Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us. if (token === 16 /* TemplateTail */) { templateStack.pop(); } else { ts.Debug.assertEqual(token, 15 /* TemplateMiddle */, "Should have been a template middle."); } } else { ts.Debug.assertEqual(lastTemplateStackToken, 17 /* OpenBraceToken */, "Should have been an open brace"); templateStack.pop(); } } break; default: if (!ts.isKeyword(token)) { break; } if (lastNonTriviaToken === 23 /* DotToken */) { token = 71 /* Identifier */; } else if (ts.isKeyword(lastNonTriviaToken) && ts.isKeyword(token) && !canFollow(lastNonTriviaToken, token)) { // We have two keywords in a row. Only treat the second as a keyword if // it's a sequence that could legally occur in the language. Otherwise // treat it as an identifier. This way, if someone writes "private var" // we recognize that 'var' is actually an identifier here. token = 71 /* Identifier */; } } } return { endOfLineState: endOfLineState, spans: spans }; } return { getClassificationsForLine: getClassificationsForLine, getEncodedLexicalClassifications: getEncodedLexicalClassifications }; } ts.createClassifier = createClassifier; /// 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 = ts.arrayToNumericMap([ 71 /* Identifier */, 9 /* StringLiteral */, 8 /* NumericLiteral */, 12 /* RegularExpressionLiteral */, 99 /* ThisKeyword */, 43 /* PlusPlusToken */, 44 /* MinusMinusToken */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 18 /* CloseBraceToken */, 101 /* TrueKeyword */, 86 /* FalseKeyword */, ], function (token) { return token; }, function () { return true; }); function getNewEndOfLineState(scanner, token, lastOnTemplateStack) { switch (token) { case 9 /* StringLiteral */: { // Check to see if we finished up on a multiline string literal. if (!scanner.isUnterminated()) return undefined; var tokenText = scanner.getTokenText(); 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) === 0) return undefined; return tokenText.charCodeAt(0) === 34 /* doubleQuote */ ? 3 /* InDoubleQuoteStringLiteral */ : 2 /* InSingleQuoteStringLiteral */; } case 3 /* MultiLineCommentTrivia */: // Check to see if the multiline comment was unclosed. return scanner.isUnterminated() ? 1 /* InMultiLineCommentTrivia */ : undefined; default: if (ts.isTemplateLiteralKind(token)) { if (!scanner.isUnterminated()) { return undefined; } switch (token) { case 16 /* TemplateTail */: return 5 /* InTemplateMiddleOrTail */; case 13 /* NoSubstitutionTemplateLiteral */: return 4 /* InTemplateHeadOrNoSubstitutionTemplate */; default: throw ts.Debug.fail("Only 'NoSubstitutionTemplateLiteral's and 'TemplateTail's can be unterminated; got SyntaxKind #" + token); } } return lastOnTemplateStack === 14 /* TemplateHead */ ? 6 /* InTemplateSubstitutionPosition */ : undefined; } } function pushEncodedClassification(start, end, offset, classification, result) { 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; } var length = end - start; if (length > 0) { // All our tokens are in relation to the augmented text. Move them back to be // relative to the original text. result.push(start - offset, length, classification); } } function convertClassificationsToResult(classifications, text) { var entries = []; var dense = classifications.spans; var lastEnd = 0; for (var i = 0; i < dense.length; i += 3) { var start = dense[i]; var length_6 = dense[i + 1]; var type = dense[i + 2]; // Make a whitespace entry between the last item and this one. if (lastEnd >= 0) { var whitespaceLength_1 = start - lastEnd; if (whitespaceLength_1 > 0) { entries.push({ length: whitespaceLength_1, classification: ts.TokenClass.Whitespace }); } } entries.push({ length: length_6, classification: convertClassification(type) }); lastEnd = start + length_6; } var whitespaceLength = text.length - lastEnd; if (whitespaceLength > 0) { entries.push({ length: whitespaceLength, classification: ts.TokenClass.Whitespace }); } return { entries: entries, finalLexState: classifications.endOfLineState }; } function convertClassification(type) { switch (type) { case 1 /* comment */: return ts.TokenClass.Comment; case 3 /* keyword */: return ts.TokenClass.Keyword; case 4 /* numericLiteral */: return ts.TokenClass.NumberLiteral; case 5 /* operator */: return ts.TokenClass.Operator; case 6 /* stringLiteral */: return ts.TokenClass.StringLiteral; case 8 /* whiteSpace */: return ts.TokenClass.Whitespace; case 10 /* punctuation */: return ts.TokenClass.Punctuation; case 2 /* identifier */: case 11 /* className */: case 12 /* enumName */: case 13 /* interfaceName */: case 14 /* moduleName */: case 15 /* typeParameterName */: case 16 /* typeAliasName */: case 9 /* text */: case 17 /* parameterName */: return ts.TokenClass.Identifier; } } /** Returns true if 'keyword2' can legally follow 'keyword1' in any language construct. */ function canFollow(keyword1, keyword2) { if (!ts.isAccessibilityModifier(keyword1)) { // 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; } switch (keyword2) { case 125 /* GetKeyword */: case 135 /* SetKeyword */: case 123 /* ConstructorKeyword */: case 115 /* StaticKeyword */: return true; // Allow things like "public get", "public constructor" and "public static". default: return false; // Any other keyword following "public" is actually an identifier, not a real keyword. } } function getPrefixFromLexState(lexState) { // 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 */: return { prefix: "\"\\\n" }; case 2 /* InSingleQuoteStringLiteral */: return { prefix: "'\\\n" }; case 1 /* InMultiLineCommentTrivia */: return { prefix: "/*\n" }; case 4 /* InTemplateHeadOrNoSubstitutionTemplate */: return { prefix: "`\n" }; case 5 /* InTemplateMiddleOrTail */: return { prefix: "}\n", pushTemplate: true }; case 6 /* InTemplateSubstitutionPosition */: return { prefix: "", pushTemplate: true }; case 0 /* None */: return { prefix: "" }; default: throw ts.Debug.assertNever(lexState); } } function isBinaryExpressionOperatorToken(token) { switch (token) { case 39 /* AsteriskToken */: case 41 /* SlashToken */: case 42 /* PercentToken */: case 37 /* PlusToken */: case 38 /* MinusToken */: case 45 /* LessThanLessThanToken */: case 46 /* GreaterThanGreaterThanToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: case 27 /* LessThanToken */: case 29 /* GreaterThanToken */: case 30 /* LessThanEqualsToken */: case 31 /* GreaterThanEqualsToken */: case 93 /* InstanceOfKeyword */: case 92 /* InKeyword */: case 118 /* AsKeyword */: case 32 /* EqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: case 48 /* AmpersandToken */: case 50 /* CaretToken */: case 49 /* BarToken */: case 53 /* AmpersandAmpersandToken */: case 54 /* BarBarToken */: case 69 /* BarEqualsToken */: case 68 /* AmpersandEqualsToken */: case 70 /* CaretEqualsToken */: case 65 /* LessThanLessThanEqualsToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 59 /* PlusEqualsToken */: case 60 /* MinusEqualsToken */: case 61 /* AsteriskEqualsToken */: case 63 /* SlashEqualsToken */: case 64 /* PercentEqualsToken */: case 58 /* EqualsToken */: case 26 /* CommaToken */: return true; default: return false; } } function isPrefixUnaryExpressionOperatorToken(token) { switch (token) { case 37 /* PlusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: case 51 /* ExclamationToken */: case 43 /* PlusPlusToken */: case 44 /* MinusMinusToken */: return true; default: return false; } } function classFromKind(token) { if (ts.isKeyword(token)) { return 3 /* keyword */; } else if (isBinaryExpressionOperatorToken(token) || isPrefixUnaryExpressionOperatorToken(token)) { return 5 /* operator */; } else if (token >= 17 /* FirstPunctuation */ && token <= 70 /* LastPunctuation */) { return 10 /* punctuation */; } switch (token) { case 8 /* NumericLiteral */: return 4 /* numericLiteral */; case 9 /* StringLiteral */: return 6 /* stringLiteral */; case 12 /* RegularExpressionLiteral */: return 7 /* regularExpressionLiteral */; case 7 /* ConflictMarkerTrivia */: case 3 /* MultiLineCommentTrivia */: case 2 /* SingleLineCommentTrivia */: return 1 /* comment */; case 5 /* WhitespaceTrivia */: case 4 /* NewLineTrivia */: return 8 /* whiteSpace */; case 71 /* Identifier */: default: if (ts.isTemplateLiteralKind(token)) { return 6 /* stringLiteral */; } return 2 /* identifier */; } } /* @internal */ function getSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) { return convertClassificationsToSpans(getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span)); } ts.getSemanticClassifications = getSemanticClassifications; function checkForClassificationCancellation(cancellationToken, kind) { // We don't want to actually call back into our host on every node to find out if we've // been canceled. That would be an enormous amount of chattyness, along with the all // the overhead of marshalling the data to/from the host. So instead we pick a few // reasonable node kinds to bother checking on. These node kinds represent high level // constructs that we would expect to see commonly, but just at a far less frequent // interval. // // For example, in checker.ts (around 750k) we only have around 600 of these constructs. // That means we're calling back into the host around every 1.2k of the file we process. // Lib.d.ts has similar numbers. switch (kind) { case 234 /* ModuleDeclaration */: case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 229 /* FunctionDeclaration */: cancellationToken.throwIfCancellationRequested(); } } /* @internal */ function getEncodedSemanticClassifications(typeChecker, cancellationToken, sourceFile, classifiableNames, span) { var spans = []; sourceFile.forEachChild(function cb(node) { // Only walk into nodes that intersect the requested span. if (!node || !ts.textSpanIntersectsWith(span, node.pos, node.getFullWidth())) { return; } checkForClassificationCancellation(cancellationToken, node.kind); // 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 (ts.isIdentifier(node) && !ts.nodeIsMissing(node) && classifiableNames.has(node.escapedText)) { var symbol = typeChecker.getSymbolAtLocation(node); var type = symbol && classifySymbol(symbol, ts.getMeaningFromLocation(node), typeChecker); if (type) { pushClassification(node.getStart(sourceFile), node.getEnd(), type); } } node.forEachChild(cb); }); return { spans: spans, endOfLineState: 0 /* None */ }; function pushClassification(start, end, type) { spans.push(start); spans.push(end - start); spans.push(type); } } ts.getEncodedSemanticClassifications = getEncodedSemanticClassifications; function classifySymbol(symbol, meaningAtPosition, checker) { var flags = symbol.getFlags(); if ((flags & 2885600 /* Classifiable */) === 0 /* None */) { return undefined; } else 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 (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. return meaningAtPosition & 4 /* Namespace */ || meaningAtPosition & 1 /* Value */ && hasValueSideModule(symbol) ? 14 /* moduleName */ : undefined; } else if (flags & 2097152 /* Alias */) { return classifySymbol(checker.getAliasedSymbol(symbol), meaningAtPosition, checker); } else if (meaningAtPosition & 2 /* Type */) { return flags & 64 /* Interface */ ? 13 /* interfaceName */ : flags & 262144 /* TypeParameter */ ? 15 /* typeParameterName */ : undefined; } else { return undefined; } } /** Returns true if there exists a module that introduces entities on the value side. */ function hasValueSideModule(symbol) { return ts.some(symbol.declarations, function (declaration) { return ts.isModuleDeclaration(declaration) && ts.getModuleInstanceState(declaration) === 1 /* Instantiated */; }); } function getClassificationTypeName(type) { switch (type) { case 1 /* comment */: return "comment" /* comment */; case 2 /* identifier */: return "identifier" /* identifier */; case 3 /* keyword */: return "keyword" /* keyword */; case 4 /* numericLiteral */: return "number" /* numericLiteral */; case 5 /* operator */: return "operator" /* operator */; case 6 /* stringLiteral */: return "string" /* stringLiteral */; case 8 /* whiteSpace */: return "whitespace" /* whiteSpace */; case 9 /* text */: return "text" /* text */; case 10 /* punctuation */: return "punctuation" /* punctuation */; case 11 /* className */: return "class name" /* className */; case 12 /* enumName */: return "enum name" /* enumName */; case 13 /* interfaceName */: return "interface name" /* interfaceName */; case 14 /* moduleName */: return "module name" /* moduleName */; case 15 /* typeParameterName */: return "type parameter name" /* typeParameterName */; case 16 /* typeAliasName */: return "type alias name" /* typeAliasName */; case 17 /* parameterName */: return "parameter name" /* parameterName */; case 18 /* docCommentTagName */: return "doc comment tag name" /* docCommentTagName */; case 19 /* jsxOpenTagName */: return "jsx open tag name" /* jsxOpenTagName */; case 20 /* jsxCloseTagName */: return "jsx close tag name" /* jsxCloseTagName */; case 21 /* jsxSelfClosingTagName */: return "jsx self closing tag name" /* jsxSelfClosingTagName */; case 22 /* jsxAttribute */: return "jsx attribute" /* jsxAttribute */; case 23 /* jsxText */: return "jsx text" /* jsxText */; case 24 /* jsxAttributeStringLiteralValue */: return "jsx attribute string literal value" /* jsxAttributeStringLiteralValue */; } } function convertClassificationsToSpans(classifications) { ts.Debug.assert(classifications.spans.length % 3 === 0); var dense = classifications.spans; var result = []; for (var i = 0; i < dense.length; i += 3) { result.push({ textSpan: ts.createTextSpan(dense[i], dense[i + 1]), classificationType: getClassificationTypeName(dense[i + 2]) }); } return result; } /* @internal */ function getSyntacticClassifications(cancellationToken, sourceFile, span) { return convertClassificationsToSpans(getEncodedSyntacticClassifications(cancellationToken, sourceFile, span)); } ts.getSyntacticClassifications = getSyntacticClassifications; /* @internal */ function getEncodedSyntacticClassifications(cancellationToken, sourceFile, span) { var spanStart = span.start; var spanLength = span.length; // Make a scanner we can get trivia from. var triviaScanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); var mergeConflictScanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ false, sourceFile.languageVariant, sourceFile.text); var result = []; processElement(sourceFile); return { spans: result, endOfLineState: 0 /* None */ }; function pushClassification(start, length, type) { result.push(start); result.push(length); result.push(type); } function classifyLeadingTriviaAndGetTokenStart(token) { triviaScanner.setTextPos(token.pos); while (true) { var start = triviaScanner.getTextPos(); // only bother scanning if we have something that could be trivia. if (!ts.couldStartTrivia(sourceFile.text, start)) { return start; } var kind = triviaScanner.scan(); var end = triviaScanner.getTextPos(); var width = end - start; // The moment we get something that isn't trivia, then stop processing. if (!ts.isTrivia(kind)) { return start; } // Don't bother with newlines/whitespace. if (kind === 4 /* NewLineTrivia */ || kind === 5 /* WhitespaceTrivia */) { continue; } // Only bother with the trivia if it at least intersects the span of interest. if (ts.isComment(kind)) { classifyComment(token, kind, start, width); // Classifying a comment might cause us to reuse the trivia scanner // (because of jsdoc comments). So after we classify the comment make // sure we set the scanner position back to where it needs to be. triviaScanner.setTextPos(end); continue; } if (kind === 7 /* ConflictMarkerTrivia */) { var text = sourceFile.text; var ch = text.charCodeAt(start); // for the <<<<<<< and >>>>>>> markers, we just add them in as comments // in the classification stream. if (ch === 60 /* lessThan */ || ch === 62 /* greaterThan */) { pushClassification(start, width, 1 /* comment */); continue; } // for the ||||||| and ======== markers, add a comment for the first line, // and then lex all subsequent lines up until the end of the conflict marker. ts.Debug.assert(ch === 124 /* bar */ || ch === 61 /* equals */); classifyDisabledMergeCode(text, start, end); } } } function classifyComment(token, kind, start, width) { if (kind === 3 /* MultiLineCommentTrivia */) { // See if this is a doc comment. If so, we'll classify certain portions of it // specially. var docCommentAndDiagnostics = ts.parseIsolatedJSDocComment(sourceFile.text, start, width); if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) { // TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]` docCommentAndDiagnostics.jsDoc.parent = token; classifyJSDocComment(docCommentAndDiagnostics.jsDoc); return; } } // Simple comment. Just add as is. pushCommentRange(start, width); } function pushCommentRange(start, width) { pushClassification(start, width, 1 /* comment */); } function classifyJSDocComment(docComment) { var pos = docComment.pos; if (docComment.tags) { for (var _i = 0, _a = docComment.tags; _i < _a.length; _i++) { var tag = _a[_i]; // As we walk through each tag, classify the portion of text from the end of // the last tag (or the start of the entire doc comment) as 'comment'. if (tag.pos !== pos) { pushCommentRange(pos, tag.pos - pos); } pushClassification(tag.atToken.pos, tag.atToken.end - tag.atToken.pos, 10 /* punctuation */); // "@" pushClassification(tag.tagName.pos, tag.tagName.end - tag.tagName.pos, 18 /* docCommentTagName */); // e.g. "param" pos = tag.tagName.end; switch (tag.kind) { case 284 /* JSDocParameterTag */: processJSDocParameterTag(tag); break; case 287 /* JSDocTemplateTag */: processJSDocTemplateTag(tag); break; case 286 /* JSDocTypeTag */: processElement(tag.typeExpression); break; case 285 /* JSDocReturnTag */: processElement(tag.typeExpression); break; } pos = tag.end; } } if (pos !== docComment.end) { pushCommentRange(pos, docComment.end - pos); } return; function processJSDocParameterTag(tag) { if (tag.isNameFirst) { pushCommentRange(pos, tag.name.pos - pos); pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */); pos = tag.name.end; } if (tag.typeExpression) { pushCommentRange(pos, tag.typeExpression.pos - pos); processElement(tag.typeExpression); pos = tag.typeExpression.end; } if (!tag.isNameFirst) { pushCommentRange(pos, tag.name.pos - pos); pushClassification(tag.name.pos, tag.name.end - tag.name.pos, 17 /* parameterName */); pos = tag.name.end; } } } function processJSDocTemplateTag(tag) { for (var _i = 0, _a = tag.getChildren(); _i < _a.length; _i++) { var child = _a[_i]; processElement(child); } } function classifyDisabledMergeCode(text, start, end) { // Classify the line that the ||||||| or ======= marker is on as a comment. // Then just lex all further tokens and add them to the result. var i; for (i = start; i < end; i++) { if (ts.isLineBreak(text.charCodeAt(i))) { break; } } pushClassification(start, i - start, 1 /* comment */); mergeConflictScanner.setTextPos(i); while (mergeConflictScanner.getTextPos() < end) { classifyDisabledCodeToken(); } } function classifyDisabledCodeToken() { var start = mergeConflictScanner.getTextPos(); var tokenKind = mergeConflictScanner.scan(); var end = mergeConflictScanner.getTextPos(); var type = classifyTokenType(tokenKind); if (type) { pushClassification(start, end - start, type); } } /** * Returns true if node should be treated as classified and no further processing is required. * False will mean that node is not classified and traverse routine should recurse into node contents. */ function tryClassifyNode(node) { if (ts.isJSDoc(node)) { return true; } if (ts.nodeIsMissing(node)) { return true; } var classifiedElementName = tryClassifyJsxElementName(node); if (!ts.isToken(node) && node.kind !== 10 /* JsxText */ && classifiedElementName === undefined) { return false; } var tokenStart = node.kind === 10 /* JsxText */ ? node.pos : classifyLeadingTriviaAndGetTokenStart(node); var tokenWidth = node.end - tokenStart; ts.Debug.assert(tokenWidth >= 0); if (tokenWidth > 0) { var type = classifiedElementName || classifyTokenType(node.kind, node); if (type) { pushClassification(tokenStart, tokenWidth, type); } } return true; } function tryClassifyJsxElementName(token) { switch (token.parent && token.parent.kind) { case 252 /* JsxOpeningElement */: if (token.parent.tagName === token) { return 19 /* jsxOpenTagName */; } break; case 253 /* JsxClosingElement */: if (token.parent.tagName === token) { return 20 /* jsxCloseTagName */; } break; case 251 /* JsxSelfClosingElement */: if (token.parent.tagName === token) { return 21 /* jsxSelfClosingTagName */; } break; case 257 /* JsxAttribute */: if (token.parent.name === token) { return 22 /* jsxAttribute */; } break; } return undefined; } // for accurate classification, the actual token should be passed in. however, for // cases like 'disabled merge code' classification, we just get the token kind and // classify based on that instead. function classifyTokenType(tokenKind, token) { if (ts.isKeyword(tokenKind)) { return 3 /* keyword */; } // Special case < and > If they appear in a generic context they are punctuation, // not operators. if (tokenKind === 27 /* LessThanToken */ || tokenKind === 29 /* GreaterThanToken */) { // If the node owning the token has a type argument list or type parameter list, then // we can effectively assume that a '<' and '>' belong to those lists. if (token && ts.getTypeArgumentOrTypeParameterList(token.parent)) { return 10 /* punctuation */; } } if (ts.isPunctuation(tokenKind)) { if (token) { if (tokenKind === 58 /* EqualsToken */) { // the '=' in a variable declaration is special cased here. if (token.parent.kind === 227 /* VariableDeclaration */ || token.parent.kind === 150 /* PropertyDeclaration */ || token.parent.kind === 147 /* Parameter */ || token.parent.kind === 257 /* JsxAttribute */) { return 5 /* operator */; } } if (token.parent.kind === 195 /* BinaryExpression */ || token.parent.kind === 193 /* PrefixUnaryExpression */ || token.parent.kind === 194 /* PostfixUnaryExpression */ || token.parent.kind === 196 /* ConditionalExpression */) { return 5 /* operator */; } } return 10 /* punctuation */; } else if (tokenKind === 8 /* NumericLiteral */) { return 4 /* numericLiteral */; } else if (tokenKind === 9 /* StringLiteral */) { return token.parent.kind === 257 /* JsxAttribute */ ? 24 /* jsxAttributeStringLiteralValue */ : 6 /* stringLiteral */; } else if (tokenKind === 12 /* RegularExpressionLiteral */) { // TODO: we should get another classification type for these literals. return 6 /* stringLiteral */; } else if (ts.isTemplateLiteralKind(tokenKind)) { // TODO (drosen): we should *also* get another classification type for these literals. return 6 /* stringLiteral */; } else if (tokenKind === 10 /* JsxText */) { return 23 /* jsxText */; } else if (tokenKind === 71 /* Identifier */) { if (token) { switch (token.parent.kind) { case 230 /* ClassDeclaration */: if (token.parent.name === token) { return 11 /* className */; } return; case 146 /* TypeParameter */: if (token.parent.name === token) { return 15 /* typeParameterName */; } return; case 231 /* InterfaceDeclaration */: if (token.parent.name === token) { return 13 /* interfaceName */; } return; case 233 /* EnumDeclaration */: if (token.parent.name === token) { return 12 /* enumName */; } return; case 234 /* ModuleDeclaration */: if (token.parent.name === token) { return 14 /* moduleName */; } return; case 147 /* Parameter */: if (token.parent.name === token) { return ts.isThisIdentifier(token) ? 3 /* keyword */ : 17 /* parameterName */; } return; } } return 2 /* identifier */; } } function processElement(element) { if (!element) { return; } // Ignore nodes that don't intersect the original span to classify. if (ts.decodedTextSpanIntersectsWith(spanStart, spanLength, element.pos, element.getFullWidth())) { checkForClassificationCancellation(cancellationToken, element.kind); for (var _i = 0, _a = element.getChildren(sourceFile); _i < _a.length; _i++) { var child = _a[_i]; if (!tryClassifyNode(child)) { // Recurse into our child nodes. processElement(child); } } } } } ts.getEncodedSyntacticClassifications = getEncodedSyntacticClassifications; })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var Completions; (function (Completions) { var PathCompletions; (function (PathCompletions) { function getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker) { var literalValue = ts.normalizeSlashes(node.text); var scriptPath = node.getSourceFile().path; var scriptDirectory = ts.getDirectoryPath(scriptPath); var span = getDirectoryFragmentTextSpan(node.text, node.getStart() + 1); if (isPathRelativeToScript(literalValue) || ts.isRootedDiskPath(literalValue)) { var extensions = ts.getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { return getCompletionEntriesForDirectoryFragmentWithRootDirs(compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, compilerOptions, host, scriptPath); } else { return getCompletionEntriesForDirectoryFragment(literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, span, host, scriptPath); } } else { // Check for node modules return getCompletionEntriesForNonRelativeModules(literalValue, scriptDirectory, span, compilerOptions, host, typeChecker); } } PathCompletions.getStringLiteralCompletionsFromModuleNames = getStringLiteralCompletionsFromModuleNames; /** * Takes a script path and returns paths for all potential folders that could be merged with its * containing folder via the "rootDirs" compiler option */ function getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase) { // Make all paths absolute/normalized if they are not already rootDirs = rootDirs.map(function (rootDirectory) { return ts.normalizePath(ts.isRootedDiskPath(rootDirectory) ? rootDirectory : ts.combinePaths(basePath, rootDirectory)); }); // Determine the path to the directory containing the script relative to the root directory it is contained within var relativeDirectory = ts.firstDefined(rootDirs, function (rootDirectory) { return ts.containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined; }); // Now find a path for each potential directory that is to be merged with the one containing the script return ts.deduplicate(rootDirs.map(function (rootDirectory) { return ts.combinePaths(rootDirectory, relativeDirectory); }), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive); } function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs, fragment, scriptPath, extensions, includeExtensions, span, compilerOptions, host, exclude) { var basePath = compilerOptions.project || host.getCurrentDirectory(); var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); var baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase); var result = []; for (var _i = 0, baseDirectories_1 = baseDirectories; _i < baseDirectories_1.length; _i++) { var baseDirectory = baseDirectories_1[_i]; getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensions, includeExtensions, span, host, exclude, result); } return result; } /** * Given a path ending at a directory, gets the completions for the path, and filters for those entries containing the basename. */ function getCompletionEntriesForDirectoryFragment(fragment, scriptPath, extensions, includeExtensions, span, host, exclude, result) { if (result === void 0) { result = []; } if (fragment === undefined) { fragment = ""; } fragment = ts.normalizeSlashes(fragment); /** * Remove the basename from the path. Note that we don't use the basename to filter completions; * the client is responsible for refining completions. */ fragment = ts.getDirectoryPath(fragment); if (fragment === "") { fragment = "." + ts.directorySeparator; } fragment = ts.ensureTrailingDirectorySeparator(fragment); var absolutePath = normalizeAndPreserveTrailingSlash(ts.isRootedDiskPath(fragment) ? fragment : ts.combinePaths(scriptPath, fragment)); var baseDirectory = ts.getDirectoryPath(absolutePath); var ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); if (tryDirectoryExists(host, baseDirectory)) { // Enumerate the available files if possible var files = tryReadDirectory(host, baseDirectory, extensions, /*exclude*/ undefined, /*include*/ ["./*"]); if (files) { /** * Multiple file entries might map to the same truncated name once we remove extensions * (happens iff includeExtensions === false)so we use a set-like data structure. Eg: * * both foo.ts and foo.tsx become foo */ var foundFiles = ts.createMap(); for (var _i = 0, files_2 = files; _i < files_2.length; _i++) { var filePath = files_2[_i]; filePath = ts.normalizePath(filePath); if (exclude && ts.comparePaths(filePath, exclude, scriptPath, ignoreCase) === 0 /* EqualTo */) { continue; } var foundFileName = includeExtensions ? ts.getBaseFileName(filePath) : ts.removeFileExtension(ts.getBaseFileName(filePath)); if (!foundFiles.get(foundFileName)) { foundFiles.set(foundFileName, true); } } ts.forEachKey(foundFiles, function (foundFile) { result.push(createCompletionEntryForModule(foundFile, "script" /* scriptElement */, span)); }); } // If possible, get folder completion as well var directories = tryGetDirectories(host, baseDirectory); if (directories) { for (var _a = 0, directories_1 = directories; _a < directories_1.length; _a++) { var directory = directories_1[_a]; var directoryName = ts.getBaseFileName(ts.normalizePath(directory)); result.push(createCompletionEntryForModule(directoryName, "directory" /* directory */, span)); } } } return result; } /** * Check all of the declared modules and those in node modules. Possible sources of modules: * Modules that are found by the type checker * Modules found relative to "baseUrl" compliler options (including patterns from "paths" compiler option) * Modules from node_modules (i.e. those listed in package.json) * This includes all files that are found in node_modules/moduleName/ with acceptable file extensions */ function getCompletionEntriesForNonRelativeModules(fragment, scriptPath, span, compilerOptions, host, typeChecker) { var baseUrl = compilerOptions.baseUrl, paths = compilerOptions.paths; var result = []; var fileExtensions = ts.getSupportedExtensions(compilerOptions); if (baseUrl) { var projectDir = compilerOptions.project || host.getCurrentDirectory(); var absolute = ts.isRootedDiskPath(baseUrl) ? baseUrl : ts.combinePaths(projectDir, baseUrl); getCompletionEntriesForDirectoryFragment(fragment, ts.normalizePath(absolute), fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result); var _loop_6 = function (path) { if (!paths.hasOwnProperty(path)) return "continue"; var patterns = paths[path]; if (!patterns) return "continue"; if (path === "*") { for (var _i = 0, patterns_1 = patterns; _i < patterns_1.length; _i++) { var pattern = patterns_1[_i]; var _loop_7 = function (match) { // Path mappings may provide a duplicate way to get to something we've already added, so don't add again. if (result.some(function (entry) { return entry.name === match; })) return "continue"; result.push(createCompletionEntryForModule(match, "external module name" /* externalModuleName */, span)); }; for (var _a = 0, _b = getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host); _a < _b.length; _a++) { var match = _b[_a]; _loop_7(match); } } } else if (ts.startsWith(path, fragment)) { if (patterns.length === 1) { if (result.some(function (entry) { return entry.name === path; })) return "continue"; result.push(createCompletionEntryForModule(path, "external module name" /* externalModuleName */, span)); } } }; for (var path in paths) { _loop_6(path); } } if (compilerOptions.moduleResolution === ts.ModuleResolutionKind.NodeJs) { ts.forEachAncestorDirectory(scriptPath, function (ancestor) { var nodeModules = ts.combinePaths(ancestor, "node_modules"); if (host.directoryExists(nodeModules)) { getCompletionEntriesForDirectoryFragment(fragment, nodeModules, fileExtensions, /*includeExtensions*/ false, span, host, /*exclude*/ undefined, result); } }); } getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span, result); for (var _i = 0, _a = enumeratePotentialNonRelativeModules(fragment, scriptPath, compilerOptions, typeChecker, host); _i < _a.length; _i++) { var moduleName = _a[_i]; result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span)); } return result; } function getModulesForPathsPattern(fragment, baseUrl, pattern, fileExtensions, host) { if (host.readDirectory) { var parsed = ts.hasZeroOrOneAsteriskCharacter(pattern) ? ts.tryParsePattern(pattern) : undefined; if (parsed) { // The prefix has two effective parts: the directory path and the base component after the filepath that is not a // full directory component. For example: directory/path/of/prefix/base* var normalizedPrefix = normalizeAndPreserveTrailingSlash(parsed.prefix); var normalizedPrefixDirectory = ts.getDirectoryPath(normalizedPrefix); var normalizedPrefixBase = ts.getBaseFileName(normalizedPrefix); var fragmentHasPath = ts.stringContains(fragment, ts.directorySeparator); // Try and expand the prefix to include any path from the fragment so that we can limit the readDirectory call var expandedPrefixDirectory = fragmentHasPath ? ts.combinePaths(normalizedPrefixDirectory, normalizedPrefixBase + ts.getDirectoryPath(fragment)) : normalizedPrefixDirectory; var normalizedSuffix = ts.normalizePath(parsed.suffix); var baseDirectory = ts.combinePaths(baseUrl, expandedPrefixDirectory); var completePrefix = fragmentHasPath ? baseDirectory : ts.ensureTrailingDirectorySeparator(baseDirectory) + normalizedPrefixBase; // If we have a suffix, then we need to read the directory all the way down. We could create a glob // that encodes the suffix, but we would have to escape the character "?" which readDirectory // doesn't support. For now, this is safer but slower var includeGlob = normalizedSuffix ? "**/*" : "./*"; var matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); if (matches) { var result = []; // Trim away prefix and suffix for (var _i = 0, matches_1 = matches; _i < matches_1.length; _i++) { var match = matches_1[_i]; var normalizedMatch = ts.normalizePath(match); if (!ts.endsWith(normalizedMatch, normalizedSuffix) || !ts.startsWith(normalizedMatch, completePrefix)) { continue; } var start = completePrefix.length; var length_7 = normalizedMatch.length - start - normalizedSuffix.length; result.push(ts.removeFileExtension(normalizedMatch.substr(start, length_7))); } return result; } } } return undefined; } function enumeratePotentialNonRelativeModules(fragment, scriptPath, options, typeChecker, host) { // Check If this is a nested module var isNestedModule = ts.stringContains(fragment, ts.directorySeparator); var moduleNameFragment = isNestedModule ? fragment.substr(0, fragment.lastIndexOf(ts.directorySeparator)) : undefined; // Get modules that the type checker picked up var ambientModules = ts.map(typeChecker.getAmbientModules(), function (sym) { return ts.stripQuotes(sym.name); }); var nonRelativeModuleNames = ts.filter(ambientModules, function (moduleName) { return ts.startsWith(moduleName, fragment); }); // Nested modules of the form "module-name/sub" need to be adjusted to only return the string // after the last '/' that appears in the fragment because that's where the replacement span // starts if (isNestedModule) { var moduleNameWithSeperator_1 = ts.ensureTrailingDirectorySeparator(moduleNameFragment); nonRelativeModuleNames = ts.map(nonRelativeModuleNames, function (nonRelativeModuleName) { return ts.removePrefix(nonRelativeModuleName, moduleNameWithSeperator_1); }); } if (!options.moduleResolution || options.moduleResolution === ts.ModuleResolutionKind.NodeJs) { for (var _i = 0, _a = enumerateNodeModulesVisibleToScript(host, scriptPath); _i < _a.length; _i++) { var visibleModule = _a[_i]; if (!isNestedModule) { nonRelativeModuleNames.push(visibleModule.moduleName); } else if (ts.startsWith(visibleModule.moduleName, moduleNameFragment)) { var nestedFiles = tryReadDirectory(host, visibleModule.moduleDir, ts.supportedTypeScriptExtensions, /*exclude*/ undefined, /*include*/ ["./*"]); if (nestedFiles) { for (var _b = 0, nestedFiles_1 = nestedFiles; _b < nestedFiles_1.length; _b++) { var f = nestedFiles_1[_b]; f = ts.normalizePath(f); var nestedModule = ts.removeFileExtension(ts.getBaseFileName(f)); nonRelativeModuleNames.push(nestedModule); } } } } } return ts.deduplicate(nonRelativeModuleNames, ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive); } function getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host) { var token = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); var commentRanges = ts.getLeadingCommentRanges(sourceFile.text, token.pos); var range = commentRanges && ts.find(commentRanges, function (commentRange) { return position >= commentRange.pos && position <= commentRange.end; }); if (!range) { return undefined; } var text = sourceFile.text.slice(range.pos, position); var match = tripleSlashDirectiveFragmentRegex.exec(text); if (!match) { return undefined; } var prefix = match[1], kind = match[2], toComplete = match[3]; var scriptPath = ts.getDirectoryPath(sourceFile.path); switch (kind) { case "path": { // Give completions for a relative path var span_10 = getDirectoryFragmentTextSpan(toComplete, range.pos + prefix.length); return getCompletionEntriesForDirectoryFragment(toComplete, scriptPath, ts.getSupportedExtensions(compilerOptions), /*includeExtensions*/ true, span_10, host, sourceFile.path); } case "types": { // Give completions based on the typings available var span_11 = ts.createTextSpan(range.pos + prefix.length, match[0].length - prefix.length); return getCompletionEntriesFromTypings(host, compilerOptions, scriptPath, span_11); } default: return undefined; } } PathCompletions.getTripleSlashReferenceCompletion = getTripleSlashReferenceCompletion; function getCompletionEntriesFromTypings(host, options, scriptPath, span, result) { if (result === void 0) { result = []; } // Check for typings specified in compiler options if (options.types) { for (var _i = 0, _a = options.types; _i < _a.length; _i++) { var moduleName = _a[_i]; result.push(createCompletionEntryForModule(moduleName, "external module name" /* externalModuleName */, span)); } } else if (host.getDirectories) { var typeRoots = void 0; try { typeRoots = ts.getEffectiveTypeRoots(options, host); } catch (_b) { } if (typeRoots) { for (var _c = 0, typeRoots_2 = typeRoots; _c < typeRoots_2.length; _c++) { var root = typeRoots_2[_c]; getCompletionEntriesFromDirectories(host, root, span, result); } } } if (host.getDirectories) { // Also get all @types typings installed in visible node_modules directories for (var _d = 0, _e = findPackageJsons(scriptPath, host); _d < _e.length; _d++) { var packageJson = _e[_d]; var typesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules/@types"); getCompletionEntriesFromDirectories(host, typesDir, span, result); } } return result; } function getCompletionEntriesFromDirectories(host, directory, span, result) { if (host.getDirectories && tryDirectoryExists(host, directory)) { var directories = tryGetDirectories(host, directory); if (directories) { for (var _i = 0, directories_2 = directories; _i < directories_2.length; _i++) { var typeDirectory = directories_2[_i]; typeDirectory = ts.normalizePath(typeDirectory); result.push(createCompletionEntryForModule(ts.getBaseFileName(typeDirectory), "external module name" /* externalModuleName */, span)); } } } } function findPackageJsons(directory, host) { var paths = []; ts.forEachAncestorDirectory(directory, function (ancestor) { var currentConfigPath = ts.findConfigFile(ancestor, function (f) { return tryFileExists(host, f); }, "package.json"); if (!currentConfigPath) { return true; // break out } paths.push(currentConfigPath); }); return paths; } function enumerateNodeModulesVisibleToScript(host, scriptPath) { var result = []; if (host.readFile && host.fileExists) { for (var _i = 0, _a = findPackageJsons(scriptPath, host); _i < _a.length; _i++) { var packageJson = _a[_i]; var contents = tryReadingPackageJson(packageJson); if (!contents) { return; } var nodeModulesDir = ts.combinePaths(ts.getDirectoryPath(packageJson), "node_modules"); var foundModuleNames = []; // Provide completions for all non @types dependencies for (var _b = 0, nodeModulesDependencyKeys_1 = nodeModulesDependencyKeys; _b < nodeModulesDependencyKeys_1.length; _b++) { var key = nodeModulesDependencyKeys_1[_b]; addPotentialPackageNames(contents[key], foundModuleNames); } for (var _c = 0, foundModuleNames_1 = foundModuleNames; _c < foundModuleNames_1.length; _c++) { var moduleName = foundModuleNames_1[_c]; var moduleDir = ts.combinePaths(nodeModulesDir, moduleName); result.push({ moduleName: moduleName, moduleDir: moduleDir }); } } } return result; function tryReadingPackageJson(filePath) { try { var fileText = tryReadFile(host, filePath); return fileText ? JSON.parse(fileText) : undefined; } catch (e) { return undefined; } } function addPotentialPackageNames(dependencies, result) { if (dependencies) { for (var dep in dependencies) { if (dependencies.hasOwnProperty(dep) && !ts.startsWith(dep, "@types/")) { result.push(dep); } } } } } function createCompletionEntryForModule(name, kind, replacementSpan) { return { name: name, kind: kind, kindModifiers: "" /* none */, sortText: name, replacementSpan: replacementSpan }; } // Replace everything after the last directory seperator that appears function getDirectoryFragmentTextSpan(text, textStart) { var index = text.lastIndexOf(ts.directorySeparator); var offset = index !== -1 ? index + 1 : 0; return { start: textStart + offset, length: text.length - offset }; } // Returns true if the path is explicitly relative to the script (i.e. relative to . or ..) function isPathRelativeToScript(path) { if (path && path.length >= 2 && path.charCodeAt(0) === 46 /* dot */) { var slashIndex = path.length >= 3 && path.charCodeAt(1) === 46 /* dot */ ? 2 : 1; var slashCharCode = path.charCodeAt(slashIndex); return slashCharCode === 47 /* slash */ || slashCharCode === 92 /* backslash */; } return false; } function normalizeAndPreserveTrailingSlash(path) { return ts.hasTrailingDirectorySeparator(path) ? ts.ensureTrailingDirectorySeparator(ts.normalizePath(path)) : ts.normalizePath(path); } /** * Matches a triple slash reference directive with an incomplete string literal for its path. Used * to determine if the caret is currently within the string literal and capture the literal fragment * for completions. * For example, this matches * * /// /* @internal */ var ts; (function (ts) { var Completions; (function (Completions) { var KeywordCompletionFilters; (function (KeywordCompletionFilters) { KeywordCompletionFilters[KeywordCompletionFilters["None"] = 0] = "None"; KeywordCompletionFilters[KeywordCompletionFilters["ClassElementKeywords"] = 1] = "ClassElementKeywords"; KeywordCompletionFilters[KeywordCompletionFilters["ConstructorParameterKeywords"] = 2] = "ConstructorParameterKeywords"; })(KeywordCompletionFilters || (KeywordCompletionFilters = {})); function getCompletionsAtPosition(host, typeChecker, log, compilerOptions, sourceFile, position, allSourceFiles, options) { if (ts.isInReferenceComment(sourceFile, position)) { var entries_2 = Completions.PathCompletions.getTripleSlashReferenceCompletion(sourceFile, position, compilerOptions, host); return entries_2 && pathCompletionsInfo(entries_2); } if (ts.isInString(sourceFile, position)) { return getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log); } var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, compilerOptions.target); if (!completionData) { return undefined; } var symbols = completionData.symbols, isGlobalCompletion = completionData.isGlobalCompletion, isMemberCompletion = completionData.isMemberCompletion, allowStringLiteral = completionData.allowStringLiteral, isNewIdentifierLocation = completionData.isNewIdentifierLocation, location = completionData.location, request = completionData.request, keywordFilters = completionData.keywordFilters, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, recommendedCompletion = completionData.recommendedCompletion; if (sourceFile.languageVariant === 1 /* JSX */ && location && location.parent && location.parent.kind === 253 /* 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 =
completion list at "1" will contain "div" with type any var tagName = location.parent.parent.openingElement.tagName; return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: false, entries: [{ name: tagName.getFullText(), kind: "class" /* classElement */, kindModifiers: undefined, sortText: "0", }] }; } if (request) { var entries_3 = request.kind === "JsDocTagName" // If the current position is a jsDoc tag name, only tag names should be provided for completion ? ts.JsDoc.getJSDocTagNameCompletions() : request.kind === "JsDocTag" // If the current position is a jsDoc tag, only tags should be provided for completion ? ts.JsDoc.getJSDocTagCompletions() : ts.JsDoc.getJSDocParameterNameCompletions(request.tag); return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries_3 }; } var entries = []; if (ts.isSourceFileJavaScript(sourceFile)) { var uniqueNames = getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); getJavaScriptCompletionEntries(sourceFile, location.pos, uniqueNames, compilerOptions.target, entries); } else { if ((!symbols || symbols.length === 0) && keywordFilters === 0 /* None */) { return undefined; } getCompletionEntriesFromSymbols(symbols, entries, location, /*performCharacterChecks*/ true, typeChecker, compilerOptions.target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap); } // TODO add filter for keyword based on type/value/namespace and also location // Add all keywords if // - this is not a member completion list (all the keywords) // - other filters are enabled in required scenario so add those keywords if (keywordFilters !== 0 /* None */ || !isMemberCompletion) { ts.addRange(entries, getKeywordCompletions(keywordFilters)); } return { isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, isNewIdentifierLocation: isNewIdentifierLocation, entries: entries }; } Completions.getCompletionsAtPosition = getCompletionsAtPosition; function getJavaScriptCompletionEntries(sourceFile, position, uniqueNames, target, entries) { ts.getNameTable(sourceFile).forEach(function (pos, name) { // Skip identifiers produced only from the current location if (pos === position) { return; } var realName = ts.unescapeLeadingUnderscores(name); if (uniqueNames.has(realName) || ts.isStringANonContextualKeyword(realName)) { return; } uniqueNames.set(realName, true); var displayName = getCompletionEntryDisplayName(realName, target, /*performCharacterChecks*/ true, /*allowStringLiteral*/ false); if (displayName) { entries.push({ name: displayName, kind: "warning" /* warning */, kindModifiers: "", sortText: "1" }); } }); } function createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion) { // Try to get a valid display name for this symbol, if we could not find one, then ignore it. // We would like to only show things that can be added after a dot, so for instance numeric properties can // not be accessed with a dot (a.1 <- invalid) var displayName = getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin); if (!displayName) { return undefined; } // TODO(drosen): Right now we just permit *all* semantic meanings when calling // 'getSymbolKind' which is permissible given that it is backwards compatible; but // really we should consider passing the meaning for the node so that we don't report // that a suggestion for a value is an interface. We COULD also just do what // 'getSymbolModifiers' does, which is to use the first declaration. // Use a 'sortText' of 0' so that all symbol completion entries come before any other // entries (like JavaScript identifier entries). return { name: displayName, kind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, location), kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol), sortText: "0", source: getSourceFromOrigin(origin), hasAction: trueOrUndefined(origin !== undefined), isRecommended: trueOrUndefined(isRecommendedCompletionMatch(symbol, recommendedCompletion, typeChecker)), }; } function isRecommendedCompletionMatch(localSymbol, recommendedCompletion, checker) { return localSymbol === recommendedCompletion || !!(localSymbol.flags & 1048576 /* ExportValue */) && checker.getExportSymbolOfSymbol(localSymbol) === recommendedCompletion; } function trueOrUndefined(b) { return b ? true : undefined; } function getSourceFromOrigin(origin) { return origin && ts.stripQuotes(origin.moduleSymbol.name); } function getCompletionEntriesFromSymbols(symbols, entries, location, performCharacterChecks, typeChecker, target, log, allowStringLiteral, recommendedCompletion, symbolToOriginInfoMap) { var start = ts.timestamp(); // Tracks unique names. // We don't set this for global variables or completions from external module exports, because we can have multiple of those. // Based on the order we add things we will always see locals first, then globals, then module exports. // So adding a completion for a local will prevent us from adding completions for external module exports sharing the same name. var uniques = ts.createMap(); if (symbols) { for (var _i = 0, symbols_5 = symbols; _i < symbols_5.length; _i++) { var symbol = symbols_5[_i]; var origin = symbolToOriginInfoMap ? symbolToOriginInfoMap[ts.getSymbolId(symbol)] : undefined; var entry = createCompletionEntry(symbol, location, performCharacterChecks, typeChecker, target, allowStringLiteral, origin, recommendedCompletion); if (!entry) { continue; } var name = entry.name; if (uniques.has(name)) { continue; } // Latter case tests whether this is a global variable. if (!origin && !(symbol.parent === undefined && !ts.some(symbol.declarations, function (d) { return d.getSourceFile() === location.getSourceFile(); }))) { uniques.set(name, true); } entries.push(entry); } } log("getCompletionsAtPosition: getCompletionEntriesFromSymbols: " + (ts.timestamp() - start)); return uniques; } function getStringLiteralCompletionEntries(sourceFile, position, typeChecker, compilerOptions, host, log) { var node = ts.findPrecedingToken(position, sourceFile); if (!node || node.kind !== 9 /* StringLiteral */) { return undefined; } if (node.parent.kind === 265 /* PropertyAssignment */ && node.parent.parent.kind === 179 /* ObjectLiteralExpression */ && node.parent.name === node) { // Get quoted name of properties of the object literal expression // i.e. interface ConfigFiles { // 'jspm:dev': string // } // let files: ConfigFiles = { // '/*completion position*/' // } // // function foo(c: ConfigFiles) {} // foo({ // '/*completion position*/' // }); return getStringLiteralCompletionEntriesFromPropertyAssignment(node.parent, typeChecker, compilerOptions.target, log); } else if (ts.isElementAccessExpression(node.parent) && node.parent.argumentExpression === node) { // Get all names of properties on the expression // i.e. interface A { // 'prop1': string // } // let a: A; // a['/*completion position*/'] return getStringLiteralCompletionEntriesFromElementAccess(node.parent, typeChecker, compilerOptions.target, log); } else if (node.parent.kind === 239 /* ImportDeclaration */ || node.parent.kind === 245 /* ExportDeclaration */ || ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || ts.isImportCall(node.parent) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node)) { // Get all known external module names or complete a path to a module // i.e. import * as ns from "/*completion position*/"; // var y = import("/*completion position*/"); // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); // export * from "/*completion position*/"; var entries = Completions.PathCompletions.getStringLiteralCompletionsFromModuleNames(node, compilerOptions, host, typeChecker); return pathCompletionsInfo(entries); } else if (isEqualityExpression(node.parent)) { // Get completions from the type of the other operand // i.e. switch (a) { // case '/*completion position*/' // } return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.left === node ? node.parent.right : node.parent.left), typeChecker); } else if (ts.isCaseOrDefaultClause(node.parent)) { // Get completions from the type of the switch expression // i.e. x === '/*completion position' return getStringLiteralCompletionEntriesFromType(typeChecker.getTypeAtLocation(node.parent.parent.parent.expression), typeChecker); } else { var argumentInfo = ts.SignatureHelp.getImmediatelyContainingArgumentInfo(node, position, sourceFile); if (argumentInfo) { // Get string literal completions from specialized signatures of the target // i.e. declare function f(a: 'A'); // f("/*completion position*/") return getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker); } // Get completion for string literal from string literal type // i.e. var x: "hi" | "hello" = "/*completion position*/" return getStringLiteralCompletionEntriesFromType(typeChecker.getContextualType(node), typeChecker); } } function pathCompletionsInfo(entries) { return { // We don't want the editor to offer any other completions, such as snippets, inside a comment. isGlobalCompletion: false, isMemberCompletion: false, // The user may type in a path that doesn't yet exist, creating a "new identifier" // with respect to the collection of identifiers the server is aware of. isNewIdentifierLocation: true, entries: entries, }; } function getStringLiteralCompletionEntriesFromPropertyAssignment(element, typeChecker, target, log) { var type = typeChecker.getContextualType(element.parent); var entries = []; if (type) { getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, element, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries }; } } } function getStringLiteralCompletionEntriesFromCallExpression(argumentInfo, typeChecker) { var candidates = []; var entries = []; var uniques = ts.createMap(); typeChecker.getResolvedSignature(argumentInfo.invocation, candidates, argumentInfo.argumentCount); for (var _i = 0, candidates_1 = candidates; _i < candidates_1.length; _i++) { var candidate = candidates_1[_i]; addStringLiteralCompletionsFromType(typeChecker.getParameterType(candidate, argumentInfo.argumentIndex), entries, typeChecker, uniques); } if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: true, entries: entries }; } return undefined; } function getStringLiteralCompletionEntriesFromElementAccess(node, typeChecker, target, log) { var type = typeChecker.getTypeAtLocation(node.expression); var entries = []; if (type) { getCompletionEntriesFromSymbols(type.getApparentProperties(), entries, node, /*performCharacterChecks*/ false, typeChecker, target, log, /*allowStringLiteral*/ true); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: true, entries: entries }; } } return undefined; } function getStringLiteralCompletionEntriesFromType(type, typeChecker) { if (type) { var entries = []; addStringLiteralCompletionsFromType(type, entries, typeChecker); if (entries.length) { return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: false, entries: entries }; } } return undefined; } function addStringLiteralCompletionsFromType(type, result, typeChecker, uniques) { if (uniques === void 0) { uniques = ts.createMap(); } if (type && type.flags & 32768 /* TypeParameter */) { type = typeChecker.getBaseConstraintOfType(type); } if (!type) { return; } if (type.flags & 131072 /* Union */) { for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var t = _a[_i]; addStringLiteralCompletionsFromType(t, result, typeChecker, uniques); } } else if (type.flags & 32 /* StringLiteral */ && !(type.flags & 256 /* EnumLiteral */)) { var name = type.value; if (!uniques.has(name)) { uniques.set(name, true); result.push({ name: name, kindModifiers: "" /* none */, kind: "var" /* variableElement */, sortText: "0" }); } } } function getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, _a, allSourceFiles) { var name = _a.name, source = _a.source; var completionData = getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, { includeExternalModuleExports: true }, compilerOptions.target); if (!completionData) { return { type: "none" }; } var symbols = completionData.symbols, location = completionData.location, allowStringLiteral = completionData.allowStringLiteral, symbolToOriginInfoMap = completionData.symbolToOriginInfoMap, request = completionData.request; if (request) { return { type: "request", request: request }; } // Find the symbol with the matching entry name. // We don't need to perform character checks here because we're only comparing the // name against 'entryName' (which is known to be good), not building a new // completion entry. var symbol = ts.find(symbols, function (s) { var origin = symbolToOriginInfoMap[ts.getSymbolId(s)]; return getCompletionEntryDisplayNameForSymbol(s, compilerOptions.target, /*performCharacterChecks*/ false, allowStringLiteral, origin) === name && getSourceFromOrigin(origin) === source; }); return symbol ? { type: "symbol", symbol: symbol, location: location, symbolToOriginInfoMap: symbolToOriginInfoMap } : { type: "none" }; } function getSymbolName(symbol, origin, target) { return origin && origin.isDefaultExport && symbol.name === "default" ? ts.codefix.moduleSymbolToValidIdentifier(origin.moduleSymbol, target) : symbol.name; } function getCompletionEntryDetails(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles, host, formatContext, getCanonicalFileName) { var name = entryId.name; // Compute all the completion symbols again. var symbolCompletion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles); switch (symbolCompletion.type) { case "request": { var request = symbolCompletion.request; switch (request.kind) { case "JsDocTagName": return ts.JsDoc.getJSDocTagNameCompletionDetails(name); case "JsDocTag": return ts.JsDoc.getJSDocTagCompletionDetails(name); case "JsDocParameterName": return ts.JsDoc.getJSDocParameterNameCompletionDetails(name); default: return ts.Debug.assertNever(request); } } case "symbol": { var symbol = symbolCompletion.symbol, location = symbolCompletion.location, symbolToOriginInfoMap = symbolCompletion.symbolToOriginInfoMap; var _a = getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, typeChecker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName, allSourceFiles), codeActions = _a.codeActions, sourceDisplay = _a.sourceDisplay; var kindModifiers = ts.SymbolDisplay.getSymbolModifiers(symbol); var _b = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, location, location, 7 /* All */), displayParts = _b.displayParts, documentation = _b.documentation, symbolKind = _b.symbolKind, tags = _b.tags; return { name: name, kindModifiers: kindModifiers, kind: symbolKind, displayParts: displayParts, documentation: documentation, tags: tags, codeActions: codeActions, source: sourceDisplay }; } case "none": { // Didn't find a symbol with this name. See if we can find a keyword instead. if (ts.some(getKeywordCompletions(0 /* None */), function (c) { return c.name === name; })) { return { name: name, kind: "keyword" /* keyword */, kindModifiers: "" /* none */, displayParts: [ts.displayPart(name, ts.SymbolDisplayPartKind.keyword)], documentation: undefined, tags: undefined, codeActions: undefined, source: undefined, }; } return undefined; } } } Completions.getCompletionEntryDetails = getCompletionEntryDetails; function getCompletionEntryCodeActionsAndSourceDisplay(symbolToOriginInfoMap, symbol, checker, host, compilerOptions, sourceFile, formatContext, getCanonicalFileName, allSourceFiles) { var symbolOriginInfo = symbolToOriginInfoMap[ts.getSymbolId(symbol)]; if (!symbolOriginInfo) { return { codeActions: undefined, sourceDisplay: undefined }; } var moduleSymbol = symbolOriginInfo.moduleSymbol, isDefaultExport = symbolOriginInfo.isDefaultExport; var exportedSymbol = ts.skipAlias(symbol.exportSymbol || symbol, checker); var moduleSymbols = getAllReExportingModules(exportedSymbol, checker, allSourceFiles); ts.Debug.assert(ts.contains(moduleSymbols, moduleSymbol)); var sourceDisplay = [ts.textPart(ts.first(ts.codefix.getModuleSpecifiersForNewImport(sourceFile, moduleSymbols, compilerOptions, getCanonicalFileName, host)))]; var codeActions = ts.codefix.getCodeActionForImport(moduleSymbols, { host: host, checker: checker, newLineCharacter: host.getNewLine(), compilerOptions: compilerOptions, sourceFile: sourceFile, formatContext: formatContext, symbolName: getSymbolName(symbol, symbolOriginInfo, compilerOptions.target), getCanonicalFileName: getCanonicalFileName, symbolToken: undefined, kind: isDefaultExport ? 1 /* Default */ : 0 /* Named */, }); return { sourceDisplay: sourceDisplay, codeActions: codeActions }; } function getAllReExportingModules(exportedSymbol, checker, allSourceFiles) { var result = []; ts.codefix.forEachExternalModule(checker, allSourceFiles, function (module) { for (var _i = 0, _a = checker.getExportsOfModule(module); _i < _a.length; _i++) { var exported = _a[_i]; if (ts.skipAlias(exported, checker) === exportedSymbol) { result.push(module); } } }); return result; } function getCompletionEntrySymbol(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles) { var completion = getSymbolCompletionFromEntryId(typeChecker, log, compilerOptions, sourceFile, position, entryId, allSourceFiles); return completion.type === "symbol" ? completion.symbol : undefined; } Completions.getCompletionEntrySymbol = getCompletionEntrySymbol; function getRecommendedCompletion(currentToken, checker /*, symbolToOriginInfoMap: SymbolOriginInfoMap*/) { var ty = checker.getContextualType(currentToken); var symbol = ty && ty.symbol; // Don't include make a recommended completion for an abstract class return symbol && (symbol.flags & 384 /* Enum */ || symbol.flags & 32 /* Class */ && !ts.isAbstractConstructorSymbol(symbol)) ? getFirstSymbolInChain(symbol, currentToken, checker) : undefined; } function getFirstSymbolInChain(symbol, enclosingDeclaration, checker) { var chain = checker.getAccessibleSymbolChain(symbol, enclosingDeclaration, /*meaning*/ 67108863 /* All */, /*useOnlyExternalAliasing*/ false); if (chain) return ts.first(chain); return isModuleSymbol(symbol.parent) ? symbol : symbol.parent && getFirstSymbolInChain(symbol.parent, enclosingDeclaration, checker); } function isModuleSymbol(symbol) { return symbol.declarations.some(function (d) { return d.kind === 269 /* SourceFile */; }); } function getCompletionData(typeChecker, log, sourceFile, position, allSourceFiles, options, target) { var request; var start = ts.timestamp(); var currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853 // We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.) log("getCompletionData: Get current token: " + (ts.timestamp() - start)); start = ts.timestamp(); // Completion not allowed inside comments, bail out if this is the case var insideComment = ts.isInComment(sourceFile, position, currentToken); log("getCompletionData: Is inside comment: " + (ts.timestamp() - start)); var insideJsDocTagTypeExpression = false; if (insideComment) { if (ts.hasDocComment(sourceFile, position)) { if (sourceFile.text.charCodeAt(position - 1) === 64 /* at */) { // The current position is next to the '@' sign, when no tag name being provided yet. // Provide a full list of tag names request = { kind: "JsDocTagName" }; } else { // When completion is requested without "@", we will have check to make sure that // there are no comments prefix the request position. We will only allow "*" and space. // e.g // /** |c| /* // // /** // |c| // */ // // /** // * |c| // */ // // /** // * |c| // */ var lineStart = ts.getLineStartPositionForPosition(position, sourceFile); if (!(sourceFile.text.substring(lineStart, position).match(/[^\*|\s|(/\*\*)]/))) { request = { kind: "JsDocTag" }; } } } // Completion should work inside certain JsDoc tags. For example: // /** @type {number | string} */ // Completion should work in the brackets var tag = getJsDocTagAtPosition(currentToken, position); if (tag) { if (tag.tagName.pos <= position && position <= tag.tagName.end) { request = { kind: "JsDocTagName" }; } if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === 271 /* JSDocTypeExpression */) { currentToken = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true); if (!currentToken || (!ts.isDeclarationName(currentToken) && (currentToken.parent.kind !== 289 /* JSDocPropertyTag */ || currentToken.parent.name !== currentToken))) { // Use as type location if inside tag's type expression insideJsDocTagTypeExpression = isCurrentlyEditingNode(tag.typeExpression); } } if (ts.isJSDocParameterTag(tag) && (ts.nodeIsMissing(tag.name) || tag.name.pos <= position && position <= tag.name.end)) { request = { kind: "JsDocParameterName", tag: tag }; } } if (request) { return { symbols: ts.emptyArray, isGlobalCompletion: false, isMemberCompletion: false, allowStringLiteral: false, isNewIdentifierLocation: false, location: undefined, isRightOfDot: false, request: request, keywordFilters: 0 /* None */, symbolToOriginInfoMap: undefined, recommendedCompletion: undefined, }; } if (!insideJsDocTagTypeExpression) { // Proceed if the current position is in jsDoc tag expression; otherwise it is a normal // comment or the plain text part of a jsDoc comment, so no completion should be available log("Returning an empty list because completion was inside a regular comment or plain text part of a JsDoc comment."); return undefined; } } start = ts.timestamp(); var previousToken = ts.findPrecedingToken(position, sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression); log("getCompletionData: Get previous token 1: " + (ts.timestamp() - start)); // The decision to provide completion depends on the contextToken, which is determined through the previousToken. // Note: 'previousToken' (and thus 'contextToken') can be undefined if we are the beginning of the file var contextToken = previousToken; // Check if the caret is at the end of an identifier; this is a partial identifier that we want to complete: e.g. a.toS| // Skip this partial identifier and adjust the contextToken to the token that precedes it. if (contextToken && position <= contextToken.end && ts.isWord(contextToken.kind)) { var start_4 = ts.timestamp(); contextToken = ts.findPrecedingToken(contextToken.getFullStart(), sourceFile, /*startNode*/ undefined, insideJsDocTagTypeExpression); log("getCompletionData: Get previous token 2: " + (ts.timestamp() - start_4)); } // Find the node where completion is requested on. // Also determine whether we are trying to complete with members of that node // or attributes of a JSX tag. var node = currentToken; var isRightOfDot = false; var isRightOfOpenTag = false; var isStartingCloseTag = false; var location = ts.getTouchingPropertyName(sourceFile, position, insideJsDocTagTypeExpression); // TODO: GH#15853 if (contextToken) { // Bail out if this is a known invalid completion location if (isCompletionListBlocker(contextToken)) { log("Returning an empty list because completion was requested in an invalid position."); return undefined; } var parent = contextToken.parent; if (contextToken.kind === 23 /* DotToken */) { if (parent.kind === 180 /* PropertyAccessExpression */) { node = contextToken.parent.expression; isRightOfDot = true; } else if (parent.kind === 144 /* 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 the tagname is a property access expression, we will then walk up to the top most of property access expression. // Then, try to get a JSX container and its associated attributes type. if (parent && parent.kind === 180 /* PropertyAccessExpression */) { contextToken = parent; parent = parent.parent; } switch (parent.kind) { case 253 /* JsxClosingElement */: if (contextToken.kind === 41 /* SlashToken */) { isStartingCloseTag = true; location = contextToken; } break; case 195 /* BinaryExpression */: if (!(parent.left.flags & 32768 /* ThisNodeHasError */)) { // It has a left-hand side, so we're not in an opening JSX tag. break; } // falls through case 251 /* JsxSelfClosingElement */: case 250 /* JsxElement */: case 252 /* JsxOpeningElement */: if (contextToken.kind === 27 /* LessThanToken */) { isRightOfOpenTag = true; location = contextToken; } break; } } } var semanticStart = ts.timestamp(); var isGlobalCompletion = false; var isMemberCompletion; var allowStringLiteral = false; var isNewIdentifierLocation; var keywordFilters = 0 /* None */; var symbols = []; var symbolToOriginInfoMap = []; if (isRightOfDot) { getTypeScriptMemberSymbols(); } else if (isRightOfOpenTag) { var tagSymbols = typeChecker.getJsxIntrinsicTagNames(); if (tryGetGlobalSymbols()) { symbols = tagSymbols.concat(symbols.filter(function (s) { return !!(s.flags & (107455 /* Value */ | 2097152 /* Alias */)); })); } else { symbols = tagSymbols; } isMemberCompletion = true; isNewIdentifierLocation = false; } else if (isStartingCloseTag) { var tagName = contextToken.parent.parent.openingElement.tagName; var tagSymbol = typeChecker.getSymbolAtLocation(tagName); if (!typeChecker.isUnknownSymbol(tagSymbol)) { symbols = [tagSymbol]; } isMemberCompletion = true; isNewIdentifierLocation = false; } else { // For JavaScript or TypeScript, if we're not after a dot, then just try to get the // global symbols in scope. These results should be valid for either language as // the set of symbols that can be referenced from this location. if (!tryGetGlobalSymbols()) { return undefined; } } log("getCompletionData: Semantic work: " + (ts.timestamp() - semanticStart)); var recommendedCompletion = getRecommendedCompletion(previousToken, typeChecker); return { symbols: symbols, isGlobalCompletion: isGlobalCompletion, isMemberCompletion: isMemberCompletion, allowStringLiteral: allowStringLiteral, isNewIdentifierLocation: isNewIdentifierLocation, location: location, isRightOfDot: (isRightOfDot || isRightOfOpenTag), request: request, keywordFilters: keywordFilters, symbolToOriginInfoMap: symbolToOriginInfoMap, recommendedCompletion: recommendedCompletion }; function isTagWithTypeExpression(tag) { switch (tag.kind) { case 284 /* JSDocParameterTag */: case 289 /* JSDocPropertyTag */: case 285 /* JSDocReturnTag */: case 286 /* JSDocTypeTag */: case 288 /* JSDocTypedefTag */: return true; } } function getTypeScriptMemberSymbols() { // Right of dot member completion list isGlobalCompletion = false; isMemberCompletion = true; isNewIdentifierLocation = false; // Since this is qualified name check its a type node location var isTypeLocation = insideJsDocTagTypeExpression || ts.isPartOfTypeNode(node.parent); var isRhsOfImportDeclaration = ts.isInRightSideOfInternalImportEqualsDeclaration(node); if (ts.isEntityName(node)) { var symbol = typeChecker.getSymbolAtLocation(node); if (symbol) { symbol = ts.skipAlias(symbol, typeChecker); if (symbol.flags & (1536 /* Module */ | 384 /* Enum */)) { // Extract module or enum members var exportedSymbols = typeChecker.getExportsOfModule(symbol); var isValidValueAccess_1 = function (symbol) { return typeChecker.isValidPropertyAccess((node.parent), symbol.name); }; var isValidTypeAccess_1 = function (symbol) { return symbolCanBeReferencedAtTypeLocation(symbol); }; var isValidAccess = isRhsOfImportDeclaration ? // Any kind is allowed when dotting off namespace in internal import equals declaration function (symbol) { return isValidTypeAccess_1(symbol) || isValidValueAccess_1(symbol); } : isTypeLocation ? isValidTypeAccess_1 : isValidValueAccess_1; for (var _i = 0, exportedSymbols_1 = exportedSymbols; _i < exportedSymbols_1.length; _i++) { var symbol_2 = exportedSymbols_1[_i]; if (isValidAccess(symbol_2)) { symbols.push(symbol_2); } } // If the module is merged with a value, we must get the type of the class and add its propertes (for inherited static methods). if (!isTypeLocation && symbol.declarations.some(function (d) { return d.kind !== 269 /* SourceFile */ && d.kind !== 234 /* ModuleDeclaration */ && d.kind !== 233 /* EnumDeclaration */; })) { addTypeProperties(typeChecker.getTypeOfSymbolAtLocation(symbol, node)); } return; } } } if (!isTypeLocation) { addTypeProperties(typeChecker.getTypeAtLocation(node)); } } function addTypeProperties(type) { if (ts.isSourceFileJavaScript(sourceFile)) { // 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. symbols.push.apply(symbols, getPropertiesForCompletion(type, typeChecker, /*isForAccess*/ true)); } else { // 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); } } } } function tryGetGlobalSymbols() { var objectLikeContainer; var namedImportsOrExports; var classLikeContainer; var jsxContainer; if (objectLikeContainer = tryGetObjectLikeCompletionContainer(contextToken)) { return tryGetObjectLikeCompletionSymbols(objectLikeContainer); } if (namedImportsOrExports = tryGetNamedImportsOrExportsForCompletion(contextToken)) { // cursor is in an import clause // try to show exported member for imported module return tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports); } if (tryGetConstructorLikeCompletionContainer(contextToken)) { // no members, only keywords isMemberCompletion = false; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for constructor parameter keywordFilters = 2 /* ConstructorParameterKeywords */; return true; } if (classLikeContainer = tryGetClassLikeCompletionContainer(contextToken)) { // cursor inside class declaration getGetClassLikeCompletionSymbols(classLikeContainer); return true; } if (jsxContainer = tryGetContainingJsxElement(contextToken)) { var attrsType = void 0; if ((jsxContainer.kind === 251 /* JsxSelfClosingElement */) || (jsxContainer.kind === 252 /* JsxOpeningElement */)) { // Cursor is inside a JSX self-closing element or opening element attrsType = typeChecker.getAllAttributesTypeFromJsxOpeningLikeElement(jsxContainer); if (attrsType) { symbols = filterJsxAttributes(typeChecker.getPropertiesOfType(attrsType), jsxContainer.attributes.properties); isMemberCompletion = true; isNewIdentifierLocation = false; return true; } } } // Get all entities in the current scope. isMemberCompletion = false; isNewIdentifierLocation = isNewIdentifierDefinitionLocation(contextToken); if (previousToken !== contextToken) { ts.Debug.assert(!!previousToken, "Expected 'contextToken' to be defined when different from 'previousToken'."); } // We need to find the node that will give us an appropriate scope to begin // aggregating completion candidates. This is achieved in 'getScopeNode' // by finding the first node that encompasses a position, accounting for whether a node // is "complete" to decide whether a position belongs to the node. // // However, at the end of an identifier, we are interested in the scope of the identifier // itself, but fall outside of the identifier. For instance: // // xyz => x$ // // the cursor is outside of both the 'x' and the arrow function 'xyz => x', // so 'xyz' is not returned in our results. // // We define 'adjustedPosition' so that we may appropriately account for // being at the end of an identifier. The intention is that if requesting completion // at the end of an identifier, it should be effectively equivalent to requesting completion // anywhere inside/at the beginning of the identifier. So in the previous case, the // 'adjustedPosition' will work as if requesting completion in the following: // // xyz => $x // // If previousToken !== contextToken, then // - 'contextToken' was adjusted to the token prior to 'previousToken' // because we were at the end of an identifier. // - 'previousToken' is defined. var adjustedPosition = previousToken !== contextToken ? previousToken.getStart() : position; var scopeNode = getScopeNode(contextToken, adjustedPosition, sourceFile) || sourceFile; if (scopeNode) { isGlobalCompletion = scopeNode.kind === 269 /* SourceFile */ || scopeNode.kind === 197 /* TemplateExpression */ || scopeNode.kind === 260 /* JsxExpression */ || scopeNode.kind === 208 /* Block */ || // Some blocks aren't statements, but all get global completions ts.isStatement(scopeNode); } var symbolMeanings = 793064 /* Type */ | 107455 /* Value */ | 1920 /* Namespace */ | 2097152 /* Alias */; symbols = typeChecker.getSymbolsInScope(scopeNode, symbolMeanings); if (options.includeExternalModuleExports) { getSymbolsFromOtherSourceFileExports(symbols, previousToken && ts.isIdentifier(previousToken) ? previousToken.text : "", target); } filterGlobalCompletion(symbols); return true; } function filterGlobalCompletion(symbols) { ts.filterMutate(symbols, function (symbol) { if (!ts.isSourceFile(location)) { // export = /**/ here we want to get all meanings, so any symbol is ok if (ts.isExportAssignment(location.parent)) { return true; } // This is an alias, follow what it aliases if (symbol && symbol.flags & 2097152 /* Alias */) { symbol = typeChecker.getAliasedSymbol(symbol); } // import m = /**/ <-- It can only access namespace (if typing import = x. this would get member symbols and not namespace) if (ts.isInRightSideOfInternalImportEqualsDeclaration(location)) { return !!(symbol.flags & 1920 /* Namespace */); } if (insideJsDocTagTypeExpression || (!isContextTokenValueLocation(contextToken) && (ts.isPartOfTypeNode(location) || isContextTokenTypeLocation(contextToken)))) { // Its a type, but you can reach it by namespace.type as well return symbolCanBeReferencedAtTypeLocation(symbol); } } // expressions are value space (which includes the value namespaces) return !!(ts.getCombinedLocalAndExportSymbolFlags(symbol) & 107455 /* Value */); }); } function isContextTokenValueLocation(contextToken) { return contextToken && contextToken.kind === 103 /* TypeOfKeyword */ && contextToken.parent.kind === 163 /* TypeQuery */; } function isContextTokenTypeLocation(contextToken) { if (contextToken) { var parentKind = contextToken.parent.kind; switch (contextToken.kind) { case 56 /* ColonToken */: return parentKind === 150 /* PropertyDeclaration */ || parentKind === 149 /* PropertySignature */ || parentKind === 147 /* Parameter */ || parentKind === 227 /* VariableDeclaration */ || ts.isFunctionLikeKind(parentKind); case 58 /* EqualsToken */: return parentKind === 232 /* TypeAliasDeclaration */; case 118 /* AsKeyword */: return parentKind === 203 /* AsExpression */; } } } function symbolCanBeReferencedAtTypeLocation(symbol) { symbol = symbol.exportSymbol || symbol; // This is an alias, follow what it aliases symbol = ts.skipAlias(symbol, typeChecker); if (symbol.flags & 793064 /* Type */) { return true; } if (symbol.flags & 1536 /* Module */) { var exportedSymbols = typeChecker.getExportsOfModule(symbol); // If the exported symbols contains type, // symbol can be referenced at locations where type is allowed return ts.forEach(exportedSymbols, symbolCanBeReferencedAtTypeLocation); } } function getSymbolsFromOtherSourceFileExports(symbols, tokenText, target) { var tokenTextLowerCase = tokenText.toLowerCase(); ts.codefix.forEachExternalModuleToImportFrom(typeChecker, sourceFile, allSourceFiles, function (moduleSymbol) { for (var _i = 0, _a = typeChecker.getExportsOfModule(moduleSymbol); _i < _a.length; _i++) { var symbol = _a[_i]; var name = symbol.name; // Don't add a completion for a re-export, only for the original. // If `symbol.parent !== moduleSymbol`, this comes from an `export * from "foo"` re-export. Those don't create new symbols. // If `some(...)`, this comes from an `export { foo } from "foo"` re-export, which creates a new symbol (thus isn't caught by the first check). if (symbol.parent !== moduleSymbol || ts.some(symbol.declarations, function (d) { return ts.isExportSpecifier(d) && !!d.parent.parent.moduleSpecifier; })) { continue; } var isDefaultExport = name === "default"; if (isDefaultExport) { var localSymbol = ts.getLocalSymbolForExportDefault(symbol); if (localSymbol) { symbol = localSymbol; name = localSymbol.name; } else { name = ts.codefix.moduleSymbolToValidIdentifier(moduleSymbol, target); } } if (stringContainsCharactersInOrder(name.toLowerCase(), tokenTextLowerCase)) { symbols.push(symbol); symbolToOriginInfoMap[ts.getSymbolId(symbol)] = { moduleSymbol: moduleSymbol, isDefaultExport: isDefaultExport }; } } }); } /** * True if you could remove some characters in `a` to get `b`. * E.g., true for "abcdef" and "bdf". * But not true for "abcdef" and "dbf". */ function stringContainsCharactersInOrder(str, characters) { if (characters.length === 0) { return true; } var characterIndex = 0; for (var strIndex = 0; strIndex < str.length; strIndex++) { if (str.charCodeAt(strIndex) === characters.charCodeAt(characterIndex)) { characterIndex++; if (characterIndex === characters.length) { return true; } } } // Did not find all characters return false; } /** * Finds the first node that "embraces" the position, so that one may * accurately aggregate locals from the closest containing scope. */ function getScopeNode(initialToken, position, sourceFile) { var scope = initialToken; while (scope && !ts.positionBelongsToNode(scope, position, sourceFile)) { scope = scope.parent; } return scope; } function isCompletionListBlocker(contextToken) { var start = ts.timestamp(); var result = isInStringOrRegularExpressionOrTemplateLiteral(contextToken) || isSolelyIdentifierDefinitionLocation(contextToken) || isDotOfNumericLiteral(contextToken) || isInJsxText(contextToken); log("getCompletionsAtPosition: isCompletionListBlocker: " + (ts.timestamp() - start)); return result; } function isInJsxText(contextToken) { if (contextToken.kind === 10 /* JsxText */) { return true; } if (contextToken.kind === 29 /* GreaterThanToken */ && contextToken.parent) { if (contextToken.parent.kind === 252 /* JsxOpeningElement */) { return true; } if (contextToken.parent.kind === 253 /* JsxClosingElement */ || contextToken.parent.kind === 251 /* JsxSelfClosingElement */) { return contextToken.parent.parent && contextToken.parent.parent.kind === 250 /* JsxElement */; } } return false; } function isNewIdentifierDefinitionLocation(previousToken) { if (previousToken) { var containingNodeKind = previousToken.parent.kind; switch (previousToken.kind) { case 26 /* CommaToken */: return containingNodeKind === 182 /* CallExpression */ // func( a, | || containingNodeKind === 153 /* Constructor */ // constructor( a, | /* public, protected, private keywords are allowed here, so show completion */ || containingNodeKind === 183 /* NewExpression */ // new C(a, | || containingNodeKind === 178 /* ArrayLiteralExpression */ // [a, | || containingNodeKind === 195 /* BinaryExpression */ // const x = (a, | || containingNodeKind === 161 /* FunctionType */; // var x: (s: string, list| case 19 /* OpenParenToken */: return containingNodeKind === 182 /* CallExpression */ // func( | || containingNodeKind === 153 /* Constructor */ // constructor( | || containingNodeKind === 183 /* NewExpression */ // new C(a| || containingNodeKind === 186 /* ParenthesizedExpression */ // const x = (a| || containingNodeKind === 169 /* ParenthesizedType */; // function F(pred: (a| /* this can become an arrow function, where 'a' is the argument */ case 21 /* OpenBracketToken */: return containingNodeKind === 178 /* ArrayLiteralExpression */ // [ | || containingNodeKind === 158 /* IndexSignature */ // [ | : string ] || containingNodeKind === 145 /* ComputedPropertyName */; // [ | /* this can become an index signature */ case 128 /* ModuleKeyword */: // module | case 129 /* NamespaceKeyword */:// namespace | return true; case 23 /* DotToken */: return containingNodeKind === 234 /* ModuleDeclaration */; // module A.| case 17 /* OpenBraceToken */: return containingNodeKind === 230 /* ClassDeclaration */; // class A{ | case 58 /* EqualsToken */: return containingNodeKind === 227 /* VariableDeclaration */ // const x = a| || containingNodeKind === 195 /* BinaryExpression */; // x = a| case 14 /* TemplateHead */: return containingNodeKind === 197 /* TemplateExpression */; // `aa ${| case 15 /* TemplateMiddle */: return containingNodeKind === 206 /* TemplateSpan */; // `aa ${10} dd ${| case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: return containingNodeKind === 150 /* PropertyDeclaration */; // class A{ public | } // Previous token may have been a keyword that was converted to an identifier. switch (previousToken.getText()) { case "public": case "protected": case "private": return true; } } return false; } function isInStringOrRegularExpressionOrTemplateLiteral(contextToken) { if (contextToken.kind === 9 /* StringLiteral */ || contextToken.kind === 12 /* RegularExpressionLiteral */ || ts.isTemplateLiteralKind(contextToken.kind)) { var start_5 = contextToken.getStart(); var end = contextToken.getEnd(); // To be "in" one of these literals, the position has to be: // 1. entirely within the token text. // 2. at the end position of an unterminated token. // 3. at the end of a regular expression (due to trailing flags like '/foo/g'). if (start_5 < position && position < end) { return true; } if (position === end) { return !!contextToken.isUnterminated || contextToken.kind === 12 /* RegularExpressionLiteral */; } } return false; } /** * Aggregates relevant symbols for completion in object literals and object binding patterns. * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetObjectLikeCompletionSymbols(objectLikeContainer) { // We're looking up possible property names from contextual/inferred/declared type. isMemberCompletion = true; allowStringLiteral = true; var typeMembers; var existingMembers; if (objectLikeContainer.kind === 179 /* ObjectLiteralExpression */) { // We are completing on contextual types, but may also include properties // other than those within the declared type. isNewIdentifierLocation = true; var typeForObject = typeChecker.getContextualType(objectLikeContainer); if (!typeForObject) return false; typeMembers = getPropertiesForCompletion(typeForObject, typeChecker, /*isForAccess*/ false); existingMembers = objectLikeContainer.properties; } else { ts.Debug.assert(objectLikeContainer.kind === 175 /* ObjectBindingPattern */); // We are *only* completing on properties from the type being destructured. isNewIdentifierLocation = false; var rootDeclaration = ts.getRootDeclaration(objectLikeContainer.parent); if (!ts.isVariableLike(rootDeclaration)) throw ts.Debug.fail("Root declaration is not variable-like."); // We don't want to complete using the type acquired by the shape // of the binding pattern; we are only interested in types acquired // through type declaration or inference. // Also proceed if rootDeclaration is a parameter and if its containing function expression/arrow function is contextually typed - // type of parameter will flow in from the contextual type of the function var canGetType = rootDeclaration.initializer || rootDeclaration.type || rootDeclaration.parent.parent.kind === 217 /* ForOfStatement */; if (!canGetType && rootDeclaration.kind === 147 /* Parameter */) { if (ts.isExpression(rootDeclaration.parent)) { canGetType = !!typeChecker.getContextualType(rootDeclaration.parent); } else if (rootDeclaration.parent.kind === 152 /* MethodDeclaration */ || rootDeclaration.parent.kind === 155 /* SetAccessor */) { canGetType = ts.isExpression(rootDeclaration.parent.parent) && !!typeChecker.getContextualType(rootDeclaration.parent.parent); } } if (canGetType) { var typeForObject = typeChecker.getTypeAtLocation(objectLikeContainer); if (!typeForObject) return false; // In a binding pattern, get only known properties. Everywhere else we will get all possible properties. typeMembers = typeChecker.getPropertiesOfType(typeForObject).filter(function (symbol) { return !(ts.getDeclarationModifierFlagsFromSymbol(symbol) & 24 /* NonPublicAccessibilityModifier */); }); existingMembers = objectLikeContainer.elements; } } if (typeMembers && typeMembers.length > 0) { // Add filtered items to the completion list symbols = filterObjectMembersList(typeMembers, existingMembers); } return true; } /** * Aggregates relevant symbols for completion in import clauses and export clauses * whose declarations have a module specifier; for instance, symbols will be aggregated for * * import { | } from "moduleName"; * export { a as foo, | } from "moduleName"; * * but not for * * export { | }; * * Relevant symbols are stored in the captured 'symbols' variable. * * @returns true if 'symbols' was successfully populated; false otherwise. */ function tryGetImportOrExportClauseCompletionSymbols(namedImportsOrExports) { var declarationKind = namedImportsOrExports.kind === 242 /* NamedImports */ ? 239 /* ImportDeclaration */ : 245 /* ExportDeclaration */; var importOrExportDeclaration = ts.getAncestor(namedImportsOrExports, declarationKind); var moduleSpecifier = importOrExportDeclaration.moduleSpecifier; if (!moduleSpecifier) { return false; } isMemberCompletion = true; isNewIdentifierLocation = false; var moduleSpecifierSymbol = typeChecker.getSymbolAtLocation(moduleSpecifier); if (!moduleSpecifierSymbol) { symbols = ts.emptyArray; return true; } var exports = typeChecker.getExportsAndPropertiesOfModule(moduleSpecifierSymbol); symbols = filterNamedImportOrExportCompletionItems(exports, namedImportsOrExports.elements); return true; } /** * Aggregates relevant symbols for completion in class declaration * Relevant symbols are stored in the captured 'symbols' variable. */ function getGetClassLikeCompletionSymbols(classLikeDeclaration) { // We're looking up possible property names from parent type. isMemberCompletion = true; // Declaring new property/method/accessor isNewIdentifierLocation = true; // Has keywords for class elements keywordFilters = 1 /* ClassElementKeywords */; var baseTypeNode = ts.getClassExtendsHeritageClauseElement(classLikeDeclaration); var implementsTypeNodes = ts.getClassImplementsHeritageClauseElements(classLikeDeclaration); if (baseTypeNode || implementsTypeNodes) { var classElement = contextToken.parent; var classElementModifierFlags = ts.isClassElement(classElement) && ts.getModifierFlags(classElement); // If this is context token is not something we are editing now, consider if this would lead to be modifier if (contextToken.kind === 71 /* Identifier */ && !isCurrentlyEditingNode(contextToken)) { switch (contextToken.getText()) { case "private": classElementModifierFlags = classElementModifierFlags | 8 /* Private */; break; case "static": classElementModifierFlags = classElementModifierFlags | 32 /* Static */; break; } } // No member list for private methods if (!(classElementModifierFlags & 8 /* Private */)) { var baseClassTypeToGetPropertiesFrom = void 0; if (baseTypeNode) { baseClassTypeToGetPropertiesFrom = typeChecker.getTypeAtLocation(baseTypeNode); if (classElementModifierFlags & 32 /* Static */) { // Use static class to get property symbols from baseClassTypeToGetPropertiesFrom = typeChecker.getTypeOfSymbolAtLocation(baseClassTypeToGetPropertiesFrom.symbol, classLikeDeclaration); } } var implementedInterfaceTypePropertySymbols = (classElementModifierFlags & 32 /* Static */) ? ts.emptyArray : ts.flatMap(implementsTypeNodes || ts.emptyArray, function (typeNode) { return typeChecker.getPropertiesOfType(typeChecker.getTypeAtLocation(typeNode)); }); // List of property symbols of base type that are not private and already implemented symbols = filterClassMembersList(baseClassTypeToGetPropertiesFrom ? typeChecker.getPropertiesOfType(baseClassTypeToGetPropertiesFrom) : ts.emptyArray, implementedInterfaceTypePropertySymbols, classLikeDeclaration.members, classElementModifierFlags); } } } /** * Returns the immediate owning object literal or binding pattern of a context token, * on the condition that one exists and that the context implies completion should be given. */ function tryGetObjectLikeCompletionContainer(contextToken) { if (contextToken) { switch (contextToken.kind) { case 17 /* OpenBraceToken */: // const x = { | case 26 /* CommaToken */:// const x = { a: 0, | var parent = contextToken.parent; if (ts.isObjectLiteralExpression(parent) || ts.isObjectBindingPattern(parent)) { return parent; } break; } } return undefined; } /** * Returns the containing list of named imports or exports of a context token, * on the condition that one exists and that the context implies completion should be given. */ function tryGetNamedImportsOrExportsForCompletion(contextToken) { if (contextToken) { switch (contextToken.kind) { case 17 /* OpenBraceToken */: // import { | case 26 /* CommaToken */:// import { a as 0, | switch (contextToken.parent.kind) { case 242 /* NamedImports */: case 246 /* NamedExports */: return contextToken.parent; } } } return undefined; } function isFromClassElementDeclaration(node) { return ts.isClassElement(node.parent) && ts.isClassLike(node.parent.parent); } function isParameterOfConstructorDeclaration(node) { return ts.isParameter(node) && ts.isConstructorDeclaration(node.parent); } function isConstructorParameterCompletion(node) { return node.parent && isParameterOfConstructorDeclaration(node.parent) && (isConstructorParameterCompletionKeyword(node.kind) || ts.isDeclarationName(node)); } /** * Returns the immediate owning class declaration of a context token, * on the condition that one exists and that the context implies completion should be given. */ function tryGetClassLikeCompletionContainer(contextToken) { if (contextToken) { switch (contextToken.kind) { case 17 /* OpenBraceToken */:// class c { | if (ts.isClassLike(contextToken.parent)) { return contextToken.parent; } break; // class c {getValue(): number, | } case 26 /* CommaToken */: if (ts.isClassLike(contextToken.parent)) { return contextToken.parent; } break; // class c {getValue(): number; | } case 25 /* SemicolonToken */: // class c { method() { } | } case 18 /* CloseBraceToken */: if (ts.isClassLike(location)) { return location; } // class c { method() { } b| } if (isFromClassElementDeclaration(location) && location.parent.name === location) { return location.parent.parent; } break; default: if (isFromClassElementDeclaration(contextToken) && (isClassMemberCompletionKeyword(contextToken.kind) || isClassMemberCompletionKeywordText(contextToken.getText()))) { return contextToken.parent.parent; } } } // class c { method() { } | method2() { } } if (location && location.kind === 290 /* SyntaxList */ && ts.isClassLike(location.parent)) { return location.parent; } return undefined; } /** * Returns the immediate owning class declaration of a context token, * on the condition that one exists and that the context implies completion should be given. */ function tryGetConstructorLikeCompletionContainer(contextToken) { if (contextToken) { switch (contextToken.kind) { case 19 /* OpenParenToken */: case 26 /* CommaToken */: return ts.isConstructorDeclaration(contextToken.parent) && contextToken.parent; default: if (isConstructorParameterCompletion(contextToken)) { return contextToken.parent.parent; } } } return undefined; } function tryGetContainingJsxElement(contextToken) { if (contextToken) { var parent = contextToken.parent; switch (contextToken.kind) { case 28 /* LessThanSlashToken */: case 41 /* SlashToken */: case 71 /* Identifier */: case 180 /* PropertyAccessExpression */: case 258 /* JsxAttributes */: case 257 /* JsxAttribute */: case 259 /* JsxSpreadAttribute */: if (parent && (parent.kind === 251 /* JsxSelfClosingElement */ || parent.kind === 252 /* JsxOpeningElement */)) { return parent; } else if (parent.kind === 257 /* JsxAttribute */) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent; } break; // The context token is the closing } or " of an attribute, which means // its parent is a JsxExpression, whose parent is a JsxAttribute, // whose parent is a JsxOpeningLikeElement case 9 /* StringLiteral */: if (parent && ((parent.kind === 257 /* JsxAttribute */) || (parent.kind === 259 /* JsxSpreadAttribute */))) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent; } break; case 18 /* CloseBraceToken */: if (parent && parent.kind === 260 /* JsxExpression */ && parent.parent && parent.parent.kind === 257 /* JsxAttribute */) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray // each JsxAttribute can have initializer as JsxExpression return parent.parent.parent.parent; } if (parent && parent.kind === 259 /* JsxSpreadAttribute */) { // Currently we parse JsxOpeningLikeElement as: // JsxOpeningLikeElement // attributes: JsxAttributes // properties: NodeArray return parent.parent.parent; } break; } } return undefined; } /** * @returns true if we are certain that the currently edited location must define a new location; false otherwise. */ function isSolelyIdentifierDefinitionLocation(contextToken) { var containingNodeKind = contextToken.parent.kind; switch (contextToken.kind) { case 26 /* CommaToken */: return containingNodeKind === 227 /* VariableDeclaration */ || containingNodeKind === 228 /* VariableDeclarationList */ || containingNodeKind === 209 /* VariableStatement */ || containingNodeKind === 233 /* EnumDeclaration */ || // enum a { foo, | isFunctionLikeButNotConstructor(containingNodeKind) || containingNodeKind === 231 /* InterfaceDeclaration */ || // interface A= contextToken.pos); case 23 /* DotToken */: return containingNodeKind === 176 /* ArrayBindingPattern */; // var [.| case 56 /* ColonToken */: return containingNodeKind === 177 /* BindingElement */; // var {x :html| case 21 /* OpenBracketToken */: return containingNodeKind === 176 /* ArrayBindingPattern */; // var [x| case 19 /* OpenParenToken */: return containingNodeKind === 264 /* CatchClause */ || isFunctionLikeButNotConstructor(containingNodeKind); case 17 /* OpenBraceToken */: return containingNodeKind === 233 /* EnumDeclaration */ || // enum a { | containingNodeKind === 231 /* InterfaceDeclaration */ || // interface a { | containingNodeKind === 164 /* TypeLiteral */; // const x : { | case 25 /* SemicolonToken */: return containingNodeKind === 149 /* PropertySignature */ && contextToken.parent && contextToken.parent.parent && (contextToken.parent.parent.kind === 231 /* InterfaceDeclaration */ || // interface a { f; | contextToken.parent.parent.kind === 164 /* TypeLiteral */); // const x : { a; | case 27 /* LessThanToken */: return containingNodeKind === 230 /* ClassDeclaration */ || // class A< | containingNodeKind === 200 /* ClassExpression */ || // var C = class D< | containingNodeKind === 231 /* InterfaceDeclaration */ || // interface A< | containingNodeKind === 232 /* TypeAliasDeclaration */ || // type List< | ts.isFunctionLikeKind(containingNodeKind); case 115 /* StaticKeyword */: return containingNodeKind === 150 /* PropertyDeclaration */ && !ts.isClassLike(contextToken.parent.parent); case 24 /* DotDotDotToken */: return containingNodeKind === 147 /* Parameter */ || (contextToken.parent && contextToken.parent.parent && contextToken.parent.parent.kind === 176 /* ArrayBindingPattern */); // var [...z| case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: return containingNodeKind === 147 /* Parameter */ && !ts.isConstructorDeclaration(contextToken.parent.parent); case 118 /* AsKeyword */: return containingNodeKind === 243 /* ImportSpecifier */ || containingNodeKind === 247 /* ExportSpecifier */ || containingNodeKind === 241 /* NamespaceImport */; case 125 /* GetKeyword */: case 135 /* SetKeyword */: if (isFromClassElementDeclaration(contextToken)) { return false; } // falls through case 75 /* ClassKeyword */: case 83 /* EnumKeyword */: case 109 /* InterfaceKeyword */: case 89 /* FunctionKeyword */: case 104 /* VarKeyword */: case 91 /* ImportKeyword */: case 110 /* LetKeyword */: case 76 /* ConstKeyword */: case 116 /* YieldKeyword */: case 138 /* TypeKeyword */:// type htm| return true; } // If the previous token is keyword correspoding to class member completion keyword // there will be completion available here if (isClassMemberCompletionKeywordText(contextToken.getText()) && isFromClassElementDeclaration(contextToken)) { return false; } if (isConstructorParameterCompletion(contextToken)) { // constructor parameter completion is available only if // - its modifier of the constructor parameter or // - its name of the parameter and not being edited // eg. constructor(a |<- this shouldnt show completion if (!ts.isIdentifier(contextToken) || isConstructorParameterCompletionKeywordText(contextToken.getText()) || isCurrentlyEditingNode(contextToken)) { return false; } } // Previous token may have been a keyword that was converted to an identifier. switch (contextToken.getText()) { case "abstract": case "async": case "class": case "const": case "declare": case "enum": case "function": case "interface": case "let": case "private": case "protected": case "public": case "static": case "var": case "yield": return true; } return ts.isDeclarationName(contextToken) && !ts.isJsxAttribute(contextToken.parent); } function isFunctionLikeButNotConstructor(kind) { return ts.isFunctionLikeKind(kind) && kind !== 153 /* Constructor */; } function isDotOfNumericLiteral(contextToken) { if (contextToken.kind === 8 /* NumericLiteral */) { var text = contextToken.getFullText(); return text.charAt(text.length - 1) === "."; } return false; } /** * Filters out completion suggestions for named imports or exports. * * @param exportsOfModule The list of symbols which a module exposes. * @param namedImportsOrExports The list of existing import/export specifiers in the import/export clause. * * @returns Symbols to be suggested at an import/export clause, barring those whose named imports/exports * do not occur at the current position and have not otherwise been typed. */ function filterNamedImportOrExportCompletionItems(exportsOfModule, namedImportsOrExports) { var existingImportsOrExports = ts.createUnderscoreEscapedMap(); for (var _i = 0, namedImportsOrExports_1 = namedImportsOrExports; _i < namedImportsOrExports_1.length; _i++) { var element = namedImportsOrExports_1[_i]; // If this is the current item we are editing right now, do not filter it out if (isCurrentlyEditingNode(element)) { continue; } var name = element.propertyName || element.name; existingImportsOrExports.set(name.escapedText, true); } if (existingImportsOrExports.size === 0) { return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default"; }); } return ts.filter(exportsOfModule, function (e) { return e.escapedName !== "default" && !existingImportsOrExports.get(e.escapedName); }); } /** * Filters out completion suggestions for named imports or exports. * * @returns Symbols to be suggested in an object binding pattern or object literal expression, barring those whose declarations * do not occur at the current position and have not otherwise been typed. */ function filterObjectMembersList(contextualMemberSymbols, existingMembers) { if (!existingMembers || existingMembers.length === 0) { return contextualMemberSymbols; } var existingMemberNames = ts.createUnderscoreEscapedMap(); for (var _i = 0, existingMembers_1 = existingMembers; _i < existingMembers_1.length; _i++) { var m = existingMembers_1[_i]; // Ignore omitted expressions for missing members if (m.kind !== 265 /* PropertyAssignment */ && m.kind !== 266 /* ShorthandPropertyAssignment */ && m.kind !== 177 /* BindingElement */ && m.kind !== 152 /* MethodDeclaration */ && m.kind !== 154 /* GetAccessor */ && m.kind !== 155 /* SetAccessor */) { continue; } // If this is the current item we are editing right now, do not filter it out if (isCurrentlyEditingNode(m)) { continue; } var existingName = void 0; if (m.kind === 177 /* BindingElement */ && m.propertyName) { // include only identifiers in completion list if (m.propertyName.kind === 71 /* Identifier */) { existingName = m.propertyName.escapedText; } } else { // TODO: Account for computed property name // NOTE: if one only performs this step when m.name is an identifier, // things like '__proto__' are not filtered out. var name = ts.getNameOfDeclaration(m); existingName = ts.getEscapedTextOfIdentifierOrLiteral(name); } existingMemberNames.set(existingName, true); } return ts.filter(contextualMemberSymbols, function (m) { return !existingMemberNames.get(m.escapedName); }); } /** * Filters out completion suggestions for class elements. * * @returns Symbols to be suggested in an class element depending on existing memebers and symbol flags */ function filterClassMembersList(baseSymbols, implementingTypeSymbols, existingMembers, currentClassElementModifierFlags) { var existingMemberNames = ts.createUnderscoreEscapedMap(); for (var _i = 0, existingMembers_2 = existingMembers; _i < existingMembers_2.length; _i++) { var m = existingMembers_2[_i]; // Ignore omitted expressions for missing members if (m.kind !== 150 /* PropertyDeclaration */ && m.kind !== 152 /* MethodDeclaration */ && m.kind !== 154 /* GetAccessor */ && m.kind !== 155 /* SetAccessor */) { continue; } // If this is the current item we are editing right now, do not filter it out if (isCurrentlyEditingNode(m)) { continue; } // Dont filter member even if the name matches if it is declared private in the list if (ts.hasModifier(m, 8 /* Private */)) { continue; } // do not filter it out if the static presence doesnt match var mIsStatic = ts.hasModifier(m, 32 /* Static */); var currentElementIsStatic = !!(currentClassElementModifierFlags & 32 /* Static */); if ((mIsStatic && !currentElementIsStatic) || (!mIsStatic && currentElementIsStatic)) { continue; } var existingName = ts.getPropertyNameForPropertyNameNode(m.name); if (existingName) { existingMemberNames.set(existingName, true); } } var result = []; addPropertySymbols(baseSymbols, 8 /* Private */); addPropertySymbols(implementingTypeSymbols, 24 /* NonPublicAccessibilityModifier */); return result; function addPropertySymbols(properties, inValidModifierFlags) { for (var _i = 0, properties_12 = properties; _i < properties_12.length; _i++) { var property = properties_12[_i]; if (isValidProperty(property, inValidModifierFlags)) { result.push(property); } } } function isValidProperty(propertySymbol, inValidModifierFlags) { return !existingMemberNames.get(propertySymbol.escapedName) && propertySymbol.getDeclarations() && !(ts.getDeclarationModifierFlagsFromSymbol(propertySymbol) & inValidModifierFlags); } } /** * Filters out completion suggestions from 'symbols' according to existing JSX attributes. * * @returns Symbols to be suggested in a JSX element, barring those whose attributes * do not occur at the current position and have not otherwise been typed. */ function filterJsxAttributes(symbols, attributes) { var seenNames = ts.createUnderscoreEscapedMap(); for (var _i = 0, attributes_1 = attributes; _i < attributes_1.length; _i++) { var attr = attributes_1[_i]; // If this is the current item we are editing right now, do not filter it out if (isCurrentlyEditingNode(attr)) { continue; } if (attr.kind === 257 /* JsxAttribute */) { seenNames.set(attr.name.escapedText, true); } } return ts.filter(symbols, function (a) { return !seenNames.get(a.escapedName); }); } function isCurrentlyEditingNode(node) { return node.getStart() <= position && position <= node.getEnd(); } } /** * Get the name to be display in completion from a given symbol. * * @return undefined if the name is of external module */ function getCompletionEntryDisplayNameForSymbol(symbol, target, performCharacterChecks, allowStringLiteral, origin) { var name = getSymbolName(symbol, origin, target); if (!name) return undefined; // First check of the displayName is not external module; if it is an external module, it is not valid entry if (symbol.flags & 1920 /* Namespace */) { var firstCharCode = name.charCodeAt(0); if (ts.isSingleOrDoubleQuote(firstCharCode)) { // If the symbol is external module, don't show it in the completion list // (i.e declare module "http" { const x; } | // <= request completion here, "http" should not be there) return undefined; } } // If the symbol is for a member of an object type and is the internal name of an ES // symbol, it is not a valid entry. Internal names for ES symbols start with "__@" if (symbol.flags & 106500 /* ClassMember */) { var escapedName = symbol.escapedName; if (escapedName.length >= 3 && escapedName.charCodeAt(0) === 95 /* _ */ && escapedName.charCodeAt(1) === 95 /* _ */ && escapedName.charCodeAt(2) === 64 /* at */) { return undefined; } } return getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral); } /** * Get a displayName from a given for completion list, performing any necessary quotes stripping * and checking whether the name is valid identifier name. */ function getCompletionEntryDisplayName(name, target, performCharacterChecks, allowStringLiteral) { // If the user entered name for the symbol was quoted, removing the quotes is not enough, as the name could be an // invalid identifier name. We need to check if whatever was inside the quotes is actually a valid identifier name. // e.g "b a" is valid quoted name but when we strip off the quotes, it is invalid. // We, thus, need to check if whatever was inside the quotes is actually a valid identifier name. if (performCharacterChecks && !ts.isIdentifierText(name, target)) { // TODO: GH#18169 return allowStringLiteral ? JSON.stringify(name) : undefined; } return name; } // A cache of completion entries for keywords, these do not change between sessions var _keywordCompletions = []; function getKeywordCompletions(keywordFilter) { var completions = _keywordCompletions[keywordFilter]; if (completions) { return completions; } return _keywordCompletions[keywordFilter] = generateKeywordCompletions(keywordFilter); function generateKeywordCompletions(keywordFilter) { switch (keywordFilter) { case 0 /* None */: return getAllKeywordCompletions(); case 1 /* ClassElementKeywords */: return getFilteredKeywordCompletions(isClassMemberCompletionKeywordText); case 2 /* ConstructorParameterKeywords */: return getFilteredKeywordCompletions(isConstructorParameterCompletionKeywordText); } } function getAllKeywordCompletions() { var allKeywordsCompletions = []; for (var i = 72 /* FirstKeyword */; i <= 143 /* LastKeyword */; i++) { // "undefined" is a global variable, so don't need a keyword completion for it. if (i === 139 /* UndefinedKeyword */) continue; allKeywordsCompletions.push({ name: ts.tokenToString(i), kind: "keyword" /* keyword */, kindModifiers: "" /* none */, sortText: "0" }); } return allKeywordsCompletions; } function getFilteredKeywordCompletions(filterFn) { return ts.filter(getKeywordCompletions(0 /* None */), function (entry) { return filterFn(entry.name); }); } } function isClassMemberCompletionKeyword(kind) { switch (kind) { case 114 /* PublicKeyword */: case 113 /* ProtectedKeyword */: case 112 /* PrivateKeyword */: case 117 /* AbstractKeyword */: case 115 /* StaticKeyword */: case 123 /* ConstructorKeyword */: case 131 /* ReadonlyKeyword */: case 125 /* GetKeyword */: case 135 /* SetKeyword */: case 120 /* AsyncKeyword */: return true; } } function isClassMemberCompletionKeywordText(text) { return isClassMemberCompletionKeyword(ts.stringToToken(text)); } function isConstructorParameterCompletionKeyword(kind) { switch (kind) { case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 131 /* ReadonlyKeyword */: return true; } } function isConstructorParameterCompletionKeywordText(text) { return isConstructorParameterCompletionKeyword(ts.stringToToken(text)); } function isEqualityExpression(node) { return ts.isBinaryExpression(node) && isEqualityOperatorKind(node.operatorToken.kind); } function isEqualityOperatorKind(kind) { return kind === 32 /* EqualsEqualsToken */ || kind === 33 /* ExclamationEqualsToken */ || kind === 34 /* EqualsEqualsEqualsToken */ || kind === 35 /* ExclamationEqualsEqualsToken */; } /** Get the corresponding JSDocTag node if the position is in a jsDoc comment */ function getJsDocTagAtPosition(node, position) { var jsDoc = getJsDocHavingNode(node).jsDoc; if (!jsDoc) return undefined; for (var _i = 0, jsDoc_1 = jsDoc; _i < jsDoc_1.length; _i++) { var _a = jsDoc_1[_i], pos = _a.pos, end = _a.end, tags = _a.tags; if (!tags || position < pos || position > end) continue; for (var i = tags.length - 1; i >= 0; i--) { var tag = tags[i]; if (position >= tag.pos) { return tag; } } } } function getJsDocHavingNode(node) { if (!ts.isToken(node)) return node; switch (node.kind) { case 104 /* VarKeyword */: case 110 /* LetKeyword */: case 76 /* ConstKeyword */: // if the current token is var, let or const, skip the VariableDeclarationList return node.parent.parent; default: return node.parent; } } /** * Gets all properties on a type, but if that type is a union of several types, * tries to only include those types which declare properties, not methods. * This ensures that we don't try providing completions for all the methods on e.g. Array. */ function getPropertiesForCompletion(type, checker, isForAccess) { if (!(type.flags & 131072 /* Union */)) { return type.getApparentProperties(); } var types = type.types; // If we're providing completions for an object literal, skip primitive, array-like, or callable types since those shouldn't be implemented by object literals. var filteredTypes = isForAccess ? types : types.filter(function (memberType) { return !(memberType.flags & 16382 /* Primitive */ || checker.isArrayLikeType(memberType) || ts.typeHasCallOrConstructSignatures(memberType, checker)); }); return checker.getAllPossiblePropertiesOfTypes(filteredTypes); } })(Completions = ts.Completions || (ts.Completions = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var DocumentHighlights; (function (DocumentHighlights) { function getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch) { var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); // Note that getTouchingWord indicates failure by returning the sourceFile node. if (node === sourceFile) return undefined; ts.Debug.assert(node.parent !== undefined); if (ts.isJsxOpeningElement(node.parent) && node.parent.tagName === node || ts.isJsxClosingElement(node.parent)) { // For a JSX element, just highlight the matching tag, not all references. var _a = node.parent.parent, openingElement = _a.openingElement, closingElement = _a.closingElement; var highlightSpans = [openingElement, closingElement].map(function (_a) { var tagName = _a.tagName; return getHighlightSpanForNode(tagName, sourceFile); }); return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }]; } return getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) || getSyntacticDocumentHighlights(node, sourceFile); } DocumentHighlights.getDocumentHighlights = getDocumentHighlights; function getHighlightSpanForNode(node, sourceFile) { return { fileName: sourceFile.fileName, textSpan: ts.createTextSpanFromNode(node, sourceFile), kind: "none" /* none */ }; } function getSemanticDocumentHighlights(node, program, cancellationToken, sourceFilesToSearch) { var referenceEntries = ts.FindAllReferences.getReferenceEntriesForNode(node, program, sourceFilesToSearch, cancellationToken); return referenceEntries && convertReferencedSymbols(referenceEntries); } function convertReferencedSymbols(referenceEntries) { var fileNameToDocumentHighlights = ts.createMap(); for (var _i = 0, referenceEntries_1 = referenceEntries; _i < referenceEntries_1.length; _i++) { var entry = referenceEntries_1[_i]; var _a = ts.FindAllReferences.toHighlightSpan(entry), fileName = _a.fileName, span_12 = _a.span; var highlightSpans = fileNameToDocumentHighlights.get(fileName); if (!highlightSpans) { fileNameToDocumentHighlights.set(fileName, highlightSpans = []); } highlightSpans.push(span_12); } return ts.arrayFrom(fileNameToDocumentHighlights.entries(), function (_a) { var fileName = _a[0], highlightSpans = _a[1]; return ({ fileName: fileName, highlightSpans: highlightSpans }); }); } function getSyntacticDocumentHighlights(node, sourceFile) { var highlightSpans = getHighlightSpans(node, sourceFile); if (!highlightSpans || highlightSpans.length === 0) { return undefined; } return [{ fileName: sourceFile.fileName, highlightSpans: highlightSpans }]; } function getHighlightSpans(node, sourceFile) { switch (node.kind) { case 90 /* IfKeyword */: case 82 /* ElseKeyword */: return ts.isIfStatement(node.parent) ? getIfElseOccurrences(node.parent, sourceFile) : undefined; case 96 /* ReturnKeyword */: return useParent(node.parent, ts.isReturnStatement, getReturnOccurrences); case 100 /* ThrowKeyword */: return useParent(node.parent, ts.isThrowStatement, getThrowOccurrences); case 102 /* TryKeyword */: case 74 /* CatchKeyword */: case 87 /* FinallyKeyword */: var tryStatement = node.kind === 74 /* CatchKeyword */ ? node.parent.parent : node.parent; return useParent(tryStatement, ts.isTryStatement, getTryCatchFinallyOccurrences); case 98 /* SwitchKeyword */: return useParent(node.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 73 /* CaseKeyword */: case 79 /* DefaultKeyword */: return useParent(node.parent.parent.parent, ts.isSwitchStatement, getSwitchCaseDefaultOccurrences); case 72 /* BreakKeyword */: case 77 /* ContinueKeyword */: return useParent(node.parent, ts.isBreakOrContinueStatement, getBreakOrContinueStatementOccurrences); case 88 /* ForKeyword */: case 106 /* WhileKeyword */: case 81 /* DoKeyword */: return useParent(node.parent, function (n) { return ts.isIterationStatement(n, /*lookInLabeledStatements*/ true); }, getLoopBreakContinueOccurrences); case 123 /* ConstructorKeyword */: return useParent(node.parent, ts.isConstructorDeclaration, getConstructorOccurrences); case 125 /* GetKeyword */: case 135 /* SetKeyword */: return useParent(node.parent, ts.isAccessor, getGetAndSetOccurrences); default: return ts.isModifierKind(node.kind) && (ts.isDeclaration(node.parent) || ts.isVariableStatement(node.parent)) ? highlightSpans(getModifierOccurrences(node.kind, node.parent)) : undefined; } function useParent(node, nodeTest, getNodes) { return nodeTest(node) ? highlightSpans(getNodes(node, sourceFile)) : undefined; } function highlightSpans(nodes) { return nodes && nodes.map(function (node) { return getHighlightSpanForNode(node, sourceFile); }); } } /** * Aggregates all throw-statements within this node *without* crossing * into function boundaries and try-blocks with catch-clauses. */ function aggregateOwnedThrowStatements(node) { var statementAccumulator = []; aggregate(node); return statementAccumulator; function aggregate(node) { if (ts.isThrowStatement(node)) { statementAccumulator.push(node); } else if (ts.isTryStatement(node)) { if (node.catchClause) { aggregate(node.catchClause); } else { // Exceptions thrown within a try block lacking a catch clause // are "owned" in the current context. aggregate(node.tryBlock); } if (node.finallyBlock) { aggregate(node.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 = child.parent; if (ts.isFunctionBlock(parent) || parent.kind === 269 /* SourceFile */) { return parent; } // 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.kind === 225 /* TryStatement */) { var tryStatement = parent; if (tryStatement.tryBlock === child && tryStatement.catchClause) { return child; } } child = parent; } return undefined; } function aggregateAllBreakAndContinueStatements(node) { var statementAccumulator = []; aggregate(node); return statementAccumulator; function aggregate(node) { if (node.kind === 219 /* BreakStatement */ || node.kind === 218 /* 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) { return ts.findAncestor(statement, function (node) { switch (node.kind) { case 222 /* SwitchStatement */: if (statement.kind === 218 /* ContinueStatement */) { return false; } // falls through case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 214 /* WhileStatement */: case 213 /* DoStatement */: return !statement.label || isLabeledBy(node, statement.label.text); default: // Don't cross function boundaries. // TODO: GH#20090 return (ts.isFunctionLike(node) && "quit"); } }); } function getModifierOccurrences(modifier, declaration) { // Make sure we only highlight the keyword when it makes sense to do so. if (!isLegalModifier(modifier, declaration)) { return undefined; } var modifierFlag = ts.modifierToFlag(modifier); return ts.mapDefined(getNodesToSearchForModifier(declaration, modifierFlag), function (node) { if (ts.getModifierFlags(node) & modifierFlag) { var mod = ts.find(node.modifiers, function (m) { return m.kind === modifier; }); ts.Debug.assert(!!mod); return mod; } }); } function getNodesToSearchForModifier(declaration, modifierFlag) { var container = declaration.parent; switch (container.kind) { case 235 /* ModuleBlock */: case 269 /* SourceFile */: case 208 /* Block */: case 261 /* CaseClause */: case 262 /* DefaultClause */: // Container is either a class declaration or the declaration is a classDeclaration if (modifierFlag & 128 /* Abstract */) { return declaration.members.concat([declaration]); } else { return container.statements; } case 153 /* Constructor */: return container.parameters.concat(container.parent.members); case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: var nodes = container.members; // If we're an accessibility modifier, we're in an instance member and should search // the constructor's parameter list for instance members as well. if (modifierFlag & 28 /* AccessibilityModifier */) { var constructor = ts.find(container.members, ts.isConstructorDeclaration); if (constructor) { return nodes.concat(constructor.parameters); } } else if (modifierFlag & 128 /* Abstract */) { return nodes.concat([container]); } return nodes; default: ts.Debug.fail("Invalid container kind."); } } function isLegalModifier(modifier, declaration) { var container = declaration.parent; switch (modifier) { case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 114 /* PublicKeyword */: switch (container.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: return true; case 153 /* Constructor */: return declaration.kind === 147 /* Parameter */; default: return false; } case 115 /* StaticKeyword */: return container.kind === 230 /* ClassDeclaration */ || container.kind === 200 /* ClassExpression */; case 84 /* ExportKeyword */: case 124 /* DeclareKeyword */: return container.kind === 235 /* ModuleBlock */ || container.kind === 269 /* SourceFile */; case 117 /* AbstractKeyword */: return container.kind === 230 /* ClassDeclaration */ || declaration.kind === 230 /* ClassDeclaration */; default: return false; } } function pushKeywordIf(keywordList, token) { var expected = []; for (var _i = 2; _i < arguments.length; _i++) { expected[_i - 2] = arguments[_i]; } if (token && ts.contains(expected, token.kind)) { keywordList.push(token); return true; } return false; } function getGetAndSetOccurrences(accessorDeclaration) { var keywords = []; tryPushAccessorKeyword(accessorDeclaration.symbol, 154 /* GetAccessor */); tryPushAccessorKeyword(accessorDeclaration.symbol, 155 /* SetAccessor */); return keywords; function tryPushAccessorKeyword(accessorSymbol, accessorKind) { var accessor = ts.getDeclarationOfKind(accessorSymbol, accessorKind); if (accessor) { ts.forEach(accessor.getChildren(), function (child) { return pushKeywordIf(keywords, child, 125 /* GetKeyword */, 135 /* SetKeyword */); }); } } } function getConstructorOccurrences(constructorDeclaration) { var declarations = constructorDeclaration.symbol.getDeclarations(); var keywords = []; ts.forEach(declarations, function (declaration) { ts.forEach(declaration.getChildren(), function (token) { return pushKeywordIf(keywords, token, 123 /* ConstructorKeyword */); }); }); return keywords; } function getLoopBreakContinueOccurrences(loopNode) { var keywords = []; if (pushKeywordIf(keywords, loopNode.getFirstToken(), 88 /* ForKeyword */, 106 /* WhileKeyword */, 81 /* DoKeyword */)) { // If we succeeded and got a do-while loop, then start looking for a 'while' keyword. if (loopNode.kind === 213 /* DoStatement */) { var loopTokens = loopNode.getChildren(); for (var i = loopTokens.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, loopTokens[i], 106 /* WhileKeyword */)) { break; } } } } var breaksAndContinues = aggregateAllBreakAndContinueStatements(loopNode.statement); ts.forEach(breaksAndContinues, function (statement) { if (ownsBreakOrContinueStatement(loopNode, statement)) { pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */, 77 /* ContinueKeyword */); } }); return keywords; } function getBreakOrContinueStatementOccurrences(breakOrContinueStatement) { var owner = getBreakOrContinueOwner(breakOrContinueStatement); if (owner) { switch (owner.kind) { case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 213 /* DoStatement */: case 214 /* WhileStatement */: return getLoopBreakContinueOccurrences(owner); case 222 /* SwitchStatement */: return getSwitchCaseDefaultOccurrences(owner); } } return undefined; } function getSwitchCaseDefaultOccurrences(switchStatement) { var keywords = []; pushKeywordIf(keywords, switchStatement.getFirstToken(), 98 /* SwitchKeyword */); // Go through each clause in the switch statement, collecting the 'case'/'default' keywords. ts.forEach(switchStatement.caseBlock.clauses, function (clause) { pushKeywordIf(keywords, clause.getFirstToken(), 73 /* CaseKeyword */, 79 /* DefaultKeyword */); var breaksAndContinues = aggregateAllBreakAndContinueStatements(clause); ts.forEach(breaksAndContinues, function (statement) { if (ownsBreakOrContinueStatement(switchStatement, statement)) { pushKeywordIf(keywords, statement.getFirstToken(), 72 /* BreakKeyword */); } }); }); return keywords; } function getTryCatchFinallyOccurrences(tryStatement, sourceFile) { var keywords = []; pushKeywordIf(keywords, tryStatement.getFirstToken(), 102 /* TryKeyword */); if (tryStatement.catchClause) { pushKeywordIf(keywords, tryStatement.catchClause.getFirstToken(), 74 /* CatchKeyword */); } if (tryStatement.finallyBlock) { var finallyKeyword = ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile); pushKeywordIf(keywords, finallyKeyword, 87 /* FinallyKeyword */); } return keywords; } function getThrowOccurrences(throwStatement) { var owner = getThrowStatementOwner(throwStatement); if (!owner) { return undefined; } var keywords = []; ts.forEach(aggregateOwnedThrowStatements(owner), function (throwStatement) { pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */); }); // If the "owner" is a function, then we equate 'return' and 'throw' statements in their // ability to "jump out" of the function, and include occurrences for both. if (ts.isFunctionBlock(owner)) { ts.forEachReturnStatement(owner, function (returnStatement) { pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */); }); } return keywords; } function getReturnOccurrences(returnStatement) { var func = ts.getContainingFunction(returnStatement); if (!func) { return undefined; } var keywords = []; ts.forEachReturnStatement(ts.cast(func.body, ts.isBlock), function (returnStatement) { pushKeywordIf(keywords, returnStatement.getFirstToken(), 96 /* ReturnKeyword */); }); // Include 'throw' statements that do not occur within a try block. ts.forEach(aggregateOwnedThrowStatements(func.body), function (throwStatement) { pushKeywordIf(keywords, throwStatement.getFirstToken(), 100 /* ThrowKeyword */); }); return keywords; } function getIfElseOccurrences(ifStatement, sourceFile) { var keywords = getIfElseKeywords(ifStatement, sourceFile); var result = []; // We'd like to highlight else/ifs together if they are only separated by whitespace // (i.e. the keywords are separated by no comments, no newlines). for (var i = 0; i < keywords.length; i++) { if (keywords[i].kind === 82 /* ElseKeyword */ && i < keywords.length - 1) { var elseKeyword = keywords[i]; var ifKeyword = keywords[i + 1]; // this *should* always be an 'if' keyword. var shouldCombineElseAndIf = true; // Avoid recalculating getStart() by iterating backwards. for (var j = ifKeyword.getStart(sourceFile) - 1; j >= elseKeyword.end; j--) { if (!ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(j))) { shouldCombineElseAndIf = false; break; } } if (shouldCombineElseAndIf) { result.push({ fileName: sourceFile.fileName, textSpan: ts.createTextSpanFromBounds(elseKeyword.getStart(), ifKeyword.end), kind: "reference" /* reference */ }); i++; // skip the next keyword continue; } } // Ordinary case: just highlight the keyword. result.push(getHighlightSpanForNode(keywords[i], sourceFile)); } return result; } function getIfElseKeywords(ifStatement, sourceFile) { var keywords = []; // Traverse upwards through all parent if-statements linked by their else-branches. while (ts.isIfStatement(ifStatement.parent) && ifStatement.parent.elseStatement === ifStatement) { ifStatement = ifStatement.parent; } // Now traverse back down through the else branches, aggregating if/else keywords of if-statements. while (true) { var children = ifStatement.getChildren(sourceFile); pushKeywordIf(keywords, children[0], 90 /* IfKeyword */); // Generally the 'else' keyword is second-to-last, so we traverse backwards. for (var i = children.length - 1; i >= 0; i--) { if (pushKeywordIf(keywords, children[i], 82 /* ElseKeyword */)) { break; } } if (!ifStatement.elseStatement || !ts.isIfStatement(ifStatement.elseStatement)) { break; } ifStatement = ifStatement.elseStatement; } return keywords; } /** * 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 === 223 /* LabeledStatement */; owner = owner.parent) { if (owner.label.escapedText === labelName) { return true; } } return false; } })(DocumentHighlights = ts.DocumentHighlights || (ts.DocumentHighlights = {})); })(ts || (ts = {})); var ts; (function (ts) { function createDocumentRegistry(useCaseSensitiveFileNames, currentDirectory) { if (currentDirectory === void 0) { currentDirectory = ""; } // Maps from compiler setting target (ES3, ES5, etc.) to all the cached documents we have // for those settings. var buckets = ts.createMap(); var getCanonicalFileName = ts.createGetCanonicalFileName(!!useCaseSensitiveFileNames); function getKeyForCompilationSettings(settings) { return "_" + settings.target + "|" + settings.module + "|" + settings.noResolve + "|" + settings.jsx + "|" + settings.allowJs + "|" + settings.baseUrl + "|" + JSON.stringify(settings.typeRoots) + "|" + JSON.stringify(settings.rootDirs) + "|" + JSON.stringify(settings.paths); } function getBucketForCompilationSettings(key, createIfMissing) { var bucket = buckets.get(key); if (!bucket && createIfMissing) { buckets.set(key, bucket = ts.createMap()); } return bucket; } function reportStats() { var bucketInfoArray = ts.arrayFrom(buckets.keys()).filter(function (name) { return name && name.charAt(0) === "_"; }).map(function (name) { var entries = buckets.get(name); var sourceFiles = []; entries.forEach(function (entry, name) { sourceFiles.push({ name: name, refCount: entry.languageServiceRefCount, references: entry.owners.slice(0) }); }); sourceFiles.sort(function (x, y) { return y.refCount - x.refCount; }); return { bucket: name, sourceFiles: sourceFiles }; }); return JSON.stringify(bucketInfoArray, undefined, 2); } function acquireDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); var key = getKeyForCompilationSettings(compilationSettings); return acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind); } function acquireDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) { return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ true, scriptKind); } function updateDocument(fileName, compilationSettings, scriptSnapshot, version, scriptKind) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); var key = getKeyForCompilationSettings(compilationSettings); return updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind); } function updateDocumentWithKey(fileName, path, compilationSettings, key, scriptSnapshot, version, scriptKind) { return acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, /*acquiring*/ false, scriptKind); } function acquireOrUpdateDocument(fileName, path, compilationSettings, key, scriptSnapshot, version, acquiring, scriptKind) { var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true); var entry = bucket.get(path); if (!entry) { // Have never seen this file with these settings. Create a new source file for it. var sourceFile = ts.createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind); entry = { sourceFile: sourceFile, languageServiceRefCount: 1, owners: [] }; bucket.set(path, entry); } else { // We have an entry for this file. However, it may be for a different version of // the script snapshot. If so, update it appropriately. Otherwise, we can just // return it as is. if (entry.sourceFile.version !== version) { entry.sourceFile = ts.updateLanguageServiceSourceFile(entry.sourceFile, scriptSnapshot, version, scriptSnapshot.getChangeRange(entry.sourceFile.scriptSnapshot)); } // If we're acquiring, then this is the first time this LS is asking for this document. // Increase our ref count so we know there's another LS using the document. If we're // not acquiring, then that means the LS is 'updating' the file instead, and that means // it has already acquired the document previously. As such, we do not need to increase // the ref count. if (acquiring) { entry.languageServiceRefCount++; } } return entry.sourceFile; } function releaseDocument(fileName, compilationSettings) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); var key = getKeyForCompilationSettings(compilationSettings); return releaseDocumentWithKey(path, key); } function releaseDocumentWithKey(path, key) { var bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ false); ts.Debug.assert(bucket !== undefined); var entry = bucket.get(path); entry.languageServiceRefCount--; ts.Debug.assert(entry.languageServiceRefCount >= 0); if (entry.languageServiceRefCount === 0) { bucket.delete(path); } } return { acquireDocument: acquireDocument, acquireDocumentWithKey: acquireDocumentWithKey, updateDocument: updateDocument, updateDocumentWithKey: updateDocumentWithKey, releaseDocument: releaseDocument, releaseDocumentWithKey: releaseDocumentWithKey, reportStats: reportStats, getKeyForCompilationSettings: getKeyForCompilationSettings }; } ts.createDocumentRegistry = createDocumentRegistry; })(ts || (ts = {})); /* Code for finding imports of an exported symbol. Used only by FindAllReferences. */ /* @internal */ var ts; (function (ts) { var FindAllReferences; (function (FindAllReferences) { /** Creates the imports map and returns an ImportTracker that uses it. Call this lazily to avoid calling `getDirectImportsMap` unnecessarily. */ function createImportTracker(sourceFiles, checker, cancellationToken) { var allDirectImports = getDirectImportsMap(sourceFiles, checker, cancellationToken); return function (exportSymbol, exportInfo, isForRename) { var _a = getImportersForExport(sourceFiles, allDirectImports, exportInfo, checker, cancellationToken), directImports = _a.directImports, indirectUsers = _a.indirectUsers; return __assign({ indirectUsers: indirectUsers }, getSearchesFromDirectImports(directImports, exportSymbol, exportInfo.exportKind, checker, isForRename)); }; } FindAllReferences.createImportTracker = createImportTracker; var ExportKind; (function (ExportKind) { ExportKind[ExportKind["Named"] = 0] = "Named"; ExportKind[ExportKind["Default"] = 1] = "Default"; ExportKind[ExportKind["ExportEquals"] = 2] = "ExportEquals"; })(ExportKind = FindAllReferences.ExportKind || (FindAllReferences.ExportKind = {})); var ImportExport; (function (ImportExport) { ImportExport[ImportExport["Import"] = 0] = "Import"; ImportExport[ImportExport["Export"] = 1] = "Export"; })(ImportExport = FindAllReferences.ImportExport || (FindAllReferences.ImportExport = {})); /** Returns import statements that directly reference the exporting module, and a list of files that may access the module through a namespace. */ function getImportersForExport(sourceFiles, allDirectImports, _a, checker, cancellationToken) { var exportingModuleSymbol = _a.exportingModuleSymbol, exportKind = _a.exportKind; var markSeenDirectImport = ts.nodeSeenTracker(); var markSeenIndirectUser = ts.nodeSeenTracker(); var directImports = []; var isAvailableThroughGlobal = !!exportingModuleSymbol.globalExports; var indirectUserDeclarations = isAvailableThroughGlobal ? undefined : []; handleDirectImports(exportingModuleSymbol); return { directImports: directImports, indirectUsers: getIndirectUsers() }; function getIndirectUsers() { if (isAvailableThroughGlobal) { // It has `export as namespace`, so anything could potentially use it. return sourceFiles; } // Module augmentations may use this module's exports without importing it. for (var _i = 0, _a = exportingModuleSymbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; if (ts.isExternalModuleAugmentation(decl)) { addIndirectUser(decl); } } // This may return duplicates (if there are multiple module declarations in a single source file, all importing the same thing as a namespace), but `State.markSearchedSymbol` will handle that. return indirectUserDeclarations.map(ts.getSourceFileOfNode); } function handleDirectImports(exportingModuleSymbol) { var theseDirectImports = getDirectImports(exportingModuleSymbol); if (theseDirectImports) { for (var _i = 0, theseDirectImports_1 = theseDirectImports; _i < theseDirectImports_1.length; _i++) { var direct = theseDirectImports_1[_i]; if (!markSeenDirectImport(direct)) { continue; } cancellationToken.throwIfCancellationRequested(); switch (direct.kind) { case 182 /* CallExpression */: if (!isAvailableThroughGlobal) { var parent = direct.parent; if (exportKind === 2 /* ExportEquals */ && parent.kind === 227 /* VariableDeclaration */) { var name = parent.name; if (name.kind === 71 /* Identifier */) { directImports.push(name); break; } } // Don't support re-exporting 'require()' calls, so just add a single indirect user. addIndirectUser(direct.getSourceFile()); } break; case 238 /* ImportEqualsDeclaration */: handleNamespaceImport(direct, direct.name, ts.hasModifier(direct, 1 /* Export */)); break; case 239 /* ImportDeclaration */: var namedBindings = direct.importClause && direct.importClause.namedBindings; if (namedBindings && namedBindings.kind === 241 /* NamespaceImport */) { handleNamespaceImport(direct, namedBindings.name); } else { directImports.push(direct); } break; case 245 /* ExportDeclaration */: if (!direct.exportClause) { // This is `export * from "foo"`, so imports of this module may import the export too. handleDirectImports(getContainingModuleSymbol(direct, checker)); } else { // This is `export { foo } from "foo"` and creates an alias symbol, so recursive search will get handle re-exports. directImports.push(direct); } break; } } } } function handleNamespaceImport(importDeclaration, name, isReExport) { if (exportKind === 2 /* ExportEquals */) { // This is a direct import, not import-as-namespace. directImports.push(importDeclaration); } else if (!isAvailableThroughGlobal) { var sourceFileLike = getSourceFileLikeForImportDeclaration(importDeclaration); ts.Debug.assert(sourceFileLike.kind === 269 /* SourceFile */ || sourceFileLike.kind === 234 /* ModuleDeclaration */); if (isReExport || findNamespaceReExports(sourceFileLike, name, checker)) { addIndirectUsers(sourceFileLike); } else { addIndirectUser(sourceFileLike); } } } function addIndirectUser(sourceFileLike) { ts.Debug.assert(!isAvailableThroughGlobal); var isNew = markSeenIndirectUser(sourceFileLike); if (isNew) { indirectUserDeclarations.push(sourceFileLike); } return isNew; } /** Adds a module and all of its transitive dependencies as possible indirect users. */ function addIndirectUsers(sourceFileLike) { if (!addIndirectUser(sourceFileLike)) { return; } var moduleSymbol = checker.getMergedSymbol(sourceFileLike.symbol); ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */)); var directImports = getDirectImports(moduleSymbol); if (directImports) { for (var _i = 0, directImports_1 = directImports; _i < directImports_1.length; _i++) { var directImport = directImports_1[_i]; addIndirectUsers(getSourceFileLikeForImportDeclaration(directImport)); } } } function getDirectImports(moduleSymbol) { return allDirectImports.get(ts.getSymbolId(moduleSymbol).toString()); } } /** * Given the set of direct imports of a module, we need to find which ones import the particular exported symbol. * The returned `importSearches` will result in the entire source file being searched. * But re-exports will be placed in 'singleReferences' since they cannot be locally referenced. */ function getSearchesFromDirectImports(directImports, exportSymbol, exportKind, checker, isForRename) { var importSearches = []; var singleReferences = []; function addSearch(location, symbol) { importSearches.push([location, symbol]); } if (directImports) { for (var _i = 0, directImports_2 = directImports; _i < directImports_2.length; _i++) { var decl = directImports_2[_i]; handleImport(decl); } } return { importSearches: importSearches, singleReferences: singleReferences }; function handleImport(decl) { if (decl.kind === 238 /* ImportEqualsDeclaration */) { if (isExternalModuleImportEquals(decl)) { handleNamespaceImportLike(decl.name); } return; } if (decl.kind === 71 /* Identifier */) { handleNamespaceImportLike(decl); return; } // Ignore if there's a grammar error if (decl.moduleSpecifier.kind !== 9 /* StringLiteral */) { return; } if (decl.kind === 245 /* ExportDeclaration */) { searchForNamedImport(decl.exportClause); return; } var importClause = decl.importClause; if (!importClause) { return; } var namedBindings = importClause.namedBindings; if (namedBindings && namedBindings.kind === 241 /* NamespaceImport */) { handleNamespaceImportLike(namedBindings.name); return; } if (exportKind === 0 /* Named */) { searchForNamedImport(namedBindings); } else { // `export =` might be imported by a default import if `--allowSyntheticDefaultImports` is on, so this handles both ExportKind.Default and ExportKind.ExportEquals var name = importClause.name; // If a default import has the same name as the default export, allow to rename it. // Given `import f` and `export default function f`, we will rename both, but for `import g` we will rename just that. if (name && (!isForRename || name.escapedText === symbolName(exportSymbol))) { var defaultImportAlias = checker.getSymbolAtLocation(name); addSearch(name, defaultImportAlias); } // 'default' might be accessed as a named import `{ default as foo }`. if (!isForRename && exportKind === 1 /* Default */) { searchForNamedImport(namedBindings); } } } /** * `import x = require("./x") or `import * as x from "./x"`. * An `export =` may be imported by this syntax, so it may be a direct import. * If it's not a direct import, it will be in `indirectUsers`, so we don't have to do anything here. */ function handleNamespaceImportLike(importName) { // Don't rename an import that already has a different name than the export. if (exportKind === 2 /* ExportEquals */ && (!isForRename || isNameMatch(importName.escapedText))) { addSearch(importName, checker.getSymbolAtLocation(importName)); } } function searchForNamedImport(namedBindings) { if (!namedBindings) { return; } for (var _i = 0, _a = namedBindings.elements; _i < _a.length; _i++) { var element = _a[_i]; var name = element.name, propertyName = element.propertyName; if (!isNameMatch((propertyName || name).escapedText)) { continue; } if (propertyName) { // This is `import { foo as bar } from "./a"` or `export { foo as bar } from "./a"`. `foo` isn't a local in the file, so just add it as a single reference. singleReferences.push(propertyName); if (!isForRename) { // Search locally for `bar`. addSearch(name, checker.getSymbolAtLocation(name)); } } else { var localSymbol = element.kind === 247 /* ExportSpecifier */ && element.propertyName ? checker.getExportSpecifierLocalTargetSymbol(element) // For re-exporting under a different name, we want to get the re-exported symbol. : checker.getSymbolAtLocation(name); addSearch(name, localSymbol); } } } function isNameMatch(name) { // Use name of "default" even in `export =` case because we may have allowSyntheticDefaultImports return name === exportSymbol.escapedName || exportKind !== 0 /* Named */ && name === "default"; } } /** Returns 'true' is the namespace 'name' is re-exported from this module, and 'false' if it is only used locally. */ function findNamespaceReExports(sourceFileLike, name, checker) { var namespaceImportSymbol = checker.getSymbolAtLocation(name); return forEachPossibleImportOrExportStatement(sourceFileLike, function (statement) { if (statement.kind !== 245 /* ExportDeclaration */) return; var _a = statement, exportClause = _a.exportClause, moduleSpecifier = _a.moduleSpecifier; if (moduleSpecifier || !exportClause) return; for (var _i = 0, _b = exportClause.elements; _i < _b.length; _i++) { var element = _b[_i]; if (checker.getExportSpecifierLocalTargetSymbol(element) === namespaceImportSymbol) { return true; } } }); } function findModuleReferences(program, sourceFiles, searchModuleSymbol) { var refs = []; var checker = program.getTypeChecker(); for (var _i = 0, sourceFiles_4 = sourceFiles; _i < sourceFiles_4.length; _i++) { var referencingFile = sourceFiles_4[_i]; var searchSourceFile = searchModuleSymbol.valueDeclaration; if (searchSourceFile.kind === 269 /* SourceFile */) { for (var _a = 0, _b = referencingFile.referencedFiles; _a < _b.length; _a++) { var ref = _b[_a]; if (program.getSourceFileFromReference(referencingFile, ref) === searchSourceFile) { refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref }); } } for (var _c = 0, _d = referencingFile.typeReferenceDirectives; _c < _d.length; _c++) { var ref = _d[_c]; var referenced = program.getResolvedTypeReferenceDirectives().get(ref.fileName); if (referenced !== undefined && referenced.resolvedFileName === searchSourceFile.fileName) { refs.push({ kind: "reference", referencingFile: referencingFile, ref: ref }); } } } forEachImport(referencingFile, function (_importDecl, moduleSpecifier) { var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier); if (moduleSymbol === searchModuleSymbol) { refs.push({ kind: "import", literal: moduleSpecifier }); } }); } return refs; } FindAllReferences.findModuleReferences = findModuleReferences; /** Returns a map from a module symbol Id to all import statements that directly reference the module. */ function getDirectImportsMap(sourceFiles, checker, cancellationToken) { var map = ts.createMap(); for (var _i = 0, sourceFiles_5 = sourceFiles; _i < sourceFiles_5.length; _i++) { var sourceFile = sourceFiles_5[_i]; cancellationToken.throwIfCancellationRequested(); forEachImport(sourceFile, function (importDecl, moduleSpecifier) { var moduleSymbol = checker.getSymbolAtLocation(moduleSpecifier); if (moduleSymbol) { var id = ts.getSymbolId(moduleSymbol).toString(); var imports = map.get(id); if (!imports) { map.set(id, imports = []); } imports.push(importDecl); } }); } return map; } /** Iterates over all statements at the top level or in module declarations. Returns the first truthy result. */ function forEachPossibleImportOrExportStatement(sourceFileLike, action) { return ts.forEach(sourceFileLike.kind === 269 /* SourceFile */ ? sourceFileLike.statements : sourceFileLike.body.statements, function (statement) { return action(statement) || (isAmbientModuleDeclaration(statement) && ts.forEach(statement.body && statement.body.statements, action)); }); } /** Calls `action` for each import, re-export, or require() in a file. */ function forEachImport(sourceFile, action) { if (sourceFile.externalModuleIndicator || sourceFile.imports !== undefined) { for (var _i = 0, _a = sourceFile.imports; _i < _a.length; _i++) { var moduleSpecifier = _a[_i]; action(importerFromModuleSpecifier(moduleSpecifier), moduleSpecifier); } } else { forEachPossibleImportOrExportStatement(sourceFile, function (statement) { switch (statement.kind) { case 245 /* ExportDeclaration */: case 239 /* ImportDeclaration */: { var decl = statement; if (decl.moduleSpecifier && decl.moduleSpecifier.kind === 9 /* StringLiteral */) { action(decl, decl.moduleSpecifier); } break; } case 238 /* ImportEqualsDeclaration */: { var decl = statement; var moduleReference = decl.moduleReference; if (moduleReference.kind === 249 /* ExternalModuleReference */ && moduleReference.expression.kind === 9 /* StringLiteral */) { action(decl, moduleReference.expression); } break; } } }); } } function importerFromModuleSpecifier(moduleSpecifier) { var decl = moduleSpecifier.parent; switch (decl.kind) { case 182 /* CallExpression */: case 239 /* ImportDeclaration */: case 245 /* ExportDeclaration */: return decl; case 249 /* ExternalModuleReference */: return decl.parent; default: ts.Debug.fail("Unexpected module specifier parent: " + decl.kind); } } /** * Given a local reference, we might notice that it's an import/export and recursively search for references of that. * If at an import, look locally for the symbol it imports. * If an an export, look for all imports of it. * This doesn't handle export specifiers; that is done in `getReferencesAtExportSpecifier`. * @param comingFromExport If we are doing a search for all exports, don't bother looking backwards for the imported symbol, since that's the reason we're here. */ function getImportOrExportSymbol(node, symbol, checker, comingFromExport) { return comingFromExport ? getExport() : getExport() || getImport(); function getExport() { var parent = node.parent; if (symbol.exportSymbol) { if (parent.kind === 180 /* PropertyAccessExpression */) { // When accessing an export of a JS module, there's no alias. The symbol will still be flagged as an export even though we're at the use. // So check that we are at the declaration. return symbol.declarations.some(function (d) { return d === parent; }) && ts.isBinaryExpression(parent.parent) ? getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ false) : undefined; } else { return exportInfo(symbol.exportSymbol, getExportKindForDeclaration(parent)); } } else { var exportNode = getExportNode(parent, node); if (exportNode && ts.hasModifier(exportNode, 1 /* Export */)) { if (ts.isImportEqualsDeclaration(exportNode) && exportNode.moduleReference === node) { // We're at `Y` in `export import X = Y`. This is not the exported symbol, the left-hand-side is. So treat this as an import statement. if (comingFromExport) { return undefined; } var lhsSymbol = checker.getSymbolAtLocation(exportNode.name); return { kind: 0 /* Import */, symbol: lhsSymbol, isNamedImport: false }; } else { return exportInfo(symbol, getExportKindForDeclaration(exportNode)); } } else if (ts.isExportAssignment(parent)) { return getExportAssignmentExport(parent); } else if (ts.isExportAssignment(parent.parent)) { return getExportAssignmentExport(parent.parent); } else if (ts.isBinaryExpression(parent)) { return getSpecialPropertyExport(parent, /*useLhsSymbol*/ true); } else if (ts.isBinaryExpression(parent.parent)) { return getSpecialPropertyExport(parent.parent, /*useLhsSymbol*/ true); } } function getExportAssignmentExport(ex) { // Get the symbol for the `export =` node; its parent is the module it's the export of. var exportingModuleSymbol = ex.symbol.parent; ts.Debug.assert(!!exportingModuleSymbol); var exportKind = ex.isExportEquals ? 2 /* ExportEquals */ : 1 /* Default */; return { kind: 1 /* Export */, symbol: symbol, exportInfo: { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } }; } function getSpecialPropertyExport(node, useLhsSymbol) { var kind; switch (ts.getSpecialPropertyAssignmentKind(node)) { case 1 /* ExportsProperty */: kind = 0 /* Named */; break; case 2 /* ModuleExports */: kind = 2 /* ExportEquals */; break; default: return undefined; } var sym = useLhsSymbol ? checker.getSymbolAtLocation(node.left.name) : symbol; return sym && exportInfo(sym, kind); } } function getImport() { var isImport = isNodeImport(node); if (!isImport) return undefined; // A symbol being imported is always an alias. So get what that aliases to find the local symbol. var importedSymbol = checker.getImmediateAliasedSymbol(symbol); if (!importedSymbol) return undefined; // Search on the local symbol in the exporting module, not the exported symbol. importedSymbol = skipExportSpecifierSymbol(importedSymbol, checker); // Similarly, skip past the symbol for 'export =' if (importedSymbol.escapedName === "export=") { importedSymbol = getExportEqualsLocalSymbol(importedSymbol, checker); } // If the import has a different name than the export, do not continue searching. // If `importedName` is undefined, do continue searching as the export is anonymous. // (All imports returned from this function will be ignored anyway if we are in rename and this is a not a named export.) var importedName = symbolName(importedSymbol); if (importedName === undefined || importedName === "default" || importedName === symbol.escapedName) { return __assign({ kind: 0 /* Import */, symbol: importedSymbol }, isImport); } } function exportInfo(symbol, kind) { var exportInfo = getExportInfo(symbol, kind, checker); return exportInfo && { kind: 1 /* Export */, symbol: symbol, exportInfo: exportInfo }; } // Not meant for use with export specifiers or export assignment. function getExportKindForDeclaration(node) { return ts.hasModifier(node, 512 /* Default */) ? 1 /* Default */ : 0 /* Named */; } } FindAllReferences.getImportOrExportSymbol = getImportOrExportSymbol; function getExportEqualsLocalSymbol(importedSymbol, checker) { if (importedSymbol.flags & 2097152 /* Alias */) { return checker.getImmediateAliasedSymbol(importedSymbol); } var decl = importedSymbol.valueDeclaration; if (ts.isExportAssignment(decl)) { return decl.expression.symbol; } else if (ts.isBinaryExpression(decl)) { return decl.right.symbol; } ts.Debug.fail(); } // If a reference is a class expression, the exported node would be its parent. // If a reference is a variable declaration, the exported node would be the variable statement. function getExportNode(parent, node) { if (parent.kind === 227 /* VariableDeclaration */) { var p = parent; return p.name !== node ? undefined : p.parent.kind === 264 /* CatchClause */ ? undefined : p.parent.parent.kind === 209 /* VariableStatement */ ? p.parent.parent : undefined; } else { return parent; } } function isNodeImport(node) { var parent = node.parent; switch (parent.kind) { case 238 /* ImportEqualsDeclaration */: return parent.name === node && isExternalModuleImportEquals(parent) ? { isNamedImport: false } : undefined; case 243 /* ImportSpecifier */: // For a rename import `{ foo as bar }`, don't search for the imported symbol. Just find local uses of `bar`. return parent.propertyName ? undefined : { isNamedImport: true }; case 240 /* ImportClause */: case 241 /* NamespaceImport */: ts.Debug.assert(parent.name === node); return { isNamedImport: false }; default: return undefined; } } function getExportInfo(exportSymbol, exportKind, checker) { var exportingModuleSymbol = checker.getMergedSymbol(exportSymbol.parent); // Need to get merged symbol in case there's an augmentation. // `export` may appear in a namespace. In that case, just rely on global search. return ts.isExternalModuleSymbol(exportingModuleSymbol) ? { exportingModuleSymbol: exportingModuleSymbol, exportKind: exportKind } : undefined; } FindAllReferences.getExportInfo = getExportInfo; function symbolName(symbol) { if (symbol.escapedName !== "default") { return symbol.escapedName; } return ts.forEach(symbol.declarations, function (decl) { var name = ts.getNameOfDeclaration(decl); return name && name.kind === 71 /* Identifier */ && name.escapedText; }); } /** If at an export specifier, go to the symbol it refers to. */ function skipExportSpecifierSymbol(symbol, checker) { // For `export { foo } from './bar", there's nothing to skip, because it does not create a new alias. But `export { foo } does. if (symbol.declarations) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (ts.isExportSpecifier(declaration) && !declaration.propertyName && !declaration.parent.parent.moduleSpecifier) { return checker.getExportSpecifierLocalTargetSymbol(declaration); } } } return symbol; } function getContainingModuleSymbol(importer, checker) { return checker.getMergedSymbol(getSourceFileLikeForImportDeclaration(importer).symbol); } function getSourceFileLikeForImportDeclaration(node) { if (node.kind === 182 /* CallExpression */) { return node.getSourceFile(); } var parent = node.parent; if (parent.kind === 269 /* SourceFile */) { return parent; } ts.Debug.assert(parent.kind === 235 /* ModuleBlock */ && isAmbientModuleDeclaration(parent.parent)); return parent.parent; } function isAmbientModuleDeclaration(node) { return node.kind === 234 /* ModuleDeclaration */ && node.name.kind === 9 /* StringLiteral */; } function isExternalModuleImportEquals(_a) { var moduleReference = _a.moduleReference; return moduleReference.kind === 249 /* ExternalModuleReference */ && moduleReference.expression.kind === 9 /* StringLiteral */; } })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { var FindAllReferences; (function (FindAllReferences) { function nodeEntry(node, isInString) { return { type: "node", node: node, isInString: isInString }; } FindAllReferences.nodeEntry = nodeEntry; function findReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position) { var referencedSymbols = findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position); if (!referencedSymbols || !referencedSymbols.length) { return undefined; } var out = []; var checker = program.getTypeChecker(); for (var _i = 0, referencedSymbols_1 = referencedSymbols; _i < referencedSymbols_1.length; _i++) { var _a = referencedSymbols_1[_i], definition = _a.definition, references = _a.references; // Only include referenced symbols that have a valid definition. if (definition) { out.push({ definition: definitionToReferencedSymbolDefinitionInfo(definition, checker), references: references.map(toReferenceEntry) }); } } return out; } FindAllReferences.findReferencedSymbols = findReferencedSymbols; function getImplementationsAtPosition(program, cancellationToken, sourceFiles, sourceFile, position) { // A node in a JSDoc comment can't have an implementation anyway. var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ false); var referenceEntries = getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node); var checker = program.getTypeChecker(); return ts.map(referenceEntries, function (entry) { return toImplementationLocation(entry, checker); }); } FindAllReferences.getImplementationsAtPosition = getImplementationsAtPosition; function getImplementationReferenceEntries(program, cancellationToken, sourceFiles, node) { if (node.kind === 269 /* SourceFile */) { return undefined; } var checker = program.getTypeChecker(); // If invoked directly on a shorthand property assignment, then return // the declaration of the symbol being assigned (not the symbol being assigned to). if (node.parent.kind === 266 /* ShorthandPropertyAssignment */) { var result_4 = []; FindAllReferences.Core.getReferenceEntriesForShorthandPropertyAssignment(node, checker, function (node) { return result_4.push(nodeEntry(node)); }); return result_4; } else if (node.kind === 97 /* SuperKeyword */ || ts.isSuperProperty(node.parent)) { // References to and accesses on the super keyword only have one possible implementation, so no // need to "Find all References" var symbol = checker.getSymbolAtLocation(node); return symbol.valueDeclaration && [nodeEntry(symbol.valueDeclaration)]; } else { // Perform "Find all References" and retrieve only those that are implementations return getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, { implementations: true }); } } function findReferencedEntries(program, cancellationToken, sourceFiles, sourceFile, position, options) { var x = flattenEntries(findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options)); return ts.map(x, toReferenceEntry); } FindAllReferences.findReferencedEntries = findReferencedEntries; function getReferenceEntriesForNode(node, program, sourceFiles, cancellationToken, options) { if (options === void 0) { options = {}; } return flattenEntries(FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options)); } FindAllReferences.getReferenceEntriesForNode = getReferenceEntriesForNode; function findAllReferencedSymbols(program, cancellationToken, sourceFiles, sourceFile, position, options) { var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); return FindAllReferences.Core.getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options); } function flattenEntries(referenceSymbols) { return referenceSymbols && ts.flatMap(referenceSymbols, function (r) { return r.references; }); } function definitionToReferencedSymbolDefinitionInfo(def, checker) { var info = (function () { switch (def.type) { case "symbol": { var symbol = def.symbol, node_3 = def.node; var _a = getDefinitionKindAndDisplayParts(symbol, node_3, checker), displayParts_1 = _a.displayParts, kind_1 = _a.kind; var name_5 = displayParts_1.map(function (p) { return p.text; }).join(""); return { node: node_3, name: name_5, kind: kind_1, displayParts: displayParts_1 }; } case "label": { var node_4 = def.node; return { node: node_4, name: node_4.text, kind: "label" /* label */, displayParts: [ts.displayPart(node_4.text, ts.SymbolDisplayPartKind.text)] }; } case "keyword": { var node_5 = def.node; var name_6 = ts.tokenToString(node_5.kind); return { node: node_5, name: name_6, kind: "keyword" /* keyword */, displayParts: [{ text: name_6, kind: "keyword" /* keyword */ }] }; } case "this": { var node_6 = def.node; var symbol = checker.getSymbolAtLocation(node_6); var displayParts_2 = symbol && ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node_6.getSourceFile(), ts.getContainerNode(node_6), node_6).displayParts; return { node: node_6, name: "this", kind: "var" /* variableElement */, displayParts: displayParts_2 }; } case "string": { var node_7 = def.node; return { node: node_7, name: node_7.text, kind: "var" /* variableElement */, displayParts: [ts.displayPart(ts.getTextOfNode(node_7), ts.SymbolDisplayPartKind.stringLiteral)] }; } } })(); if (!info) { return undefined; } var node = info.node, name = info.name, kind = info.kind, displayParts = info.displayParts; var sourceFile = node.getSourceFile(); return { containerKind: "" /* unknown */, containerName: "", fileName: sourceFile.fileName, kind: kind, name: name, textSpan: ts.createTextSpanFromNode(node, sourceFile), displayParts: displayParts }; } function getDefinitionKindAndDisplayParts(symbol, node, checker) { var _a = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(checker, symbol, node.getSourceFile(), ts.getContainerNode(node), node), displayParts = _a.displayParts, symbolKind = _a.symbolKind; return { displayParts: displayParts, kind: symbolKind }; } function toReferenceEntry(entry) { if (entry.type === "span") { return { textSpan: entry.textSpan, fileName: entry.fileName, isWriteAccess: false, isDefinition: false }; } var node = entry.node, isInString = entry.isInString; return { fileName: node.getSourceFile().fileName, textSpan: getTextSpan(node), isWriteAccess: isWriteAccessForReference(node), isDefinition: node.kind === 79 /* DefaultKeyword */ || ts.isAnyDeclarationName(node) || ts.isLiteralComputedPropertyDeclarationName(node), isInString: isInString }; } function toImplementationLocation(entry, checker) { if (entry.type === "node") { var node = entry.node; return __assign({ textSpan: getTextSpan(node), fileName: node.getSourceFile().fileName }, implementationKindDisplayParts(node, checker)); } else { var textSpan = entry.textSpan, fileName = entry.fileName; return { textSpan: textSpan, fileName: fileName, kind: "" /* unknown */, displayParts: [] }; } } function implementationKindDisplayParts(node, checker) { var symbol = checker.getSymbolAtLocation(ts.isDeclaration(node) && node.name ? node.name : node); if (symbol) { return getDefinitionKindAndDisplayParts(symbol, node, checker); } else if (node.kind === 179 /* ObjectLiteralExpression */) { return { kind: "interface" /* interfaceElement */, displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("object literal"), ts.punctuationPart(20 /* CloseParenToken */)] }; } else if (node.kind === 200 /* ClassExpression */) { return { kind: "local class" /* localClassElement */, displayParts: [ts.punctuationPart(19 /* OpenParenToken */), ts.textPart("anonymous local class"), ts.punctuationPart(20 /* CloseParenToken */)] }; } else { return { kind: ts.getNodeKind(node), displayParts: [] }; } } function toHighlightSpan(entry) { if (entry.type === "span") { var fileName_1 = entry.fileName, textSpan = entry.textSpan; return { fileName: fileName_1, span: { textSpan: textSpan, kind: "reference" /* reference */ } }; } var node = entry.node, isInString = entry.isInString; var fileName = entry.node.getSourceFile().fileName; var writeAccess = isWriteAccessForReference(node); var span = { textSpan: getTextSpan(node), kind: writeAccess ? "writtenReference" /* writtenReference */ : "reference" /* reference */, isInString: isInString }; return { fileName: fileName, span: span }; } FindAllReferences.toHighlightSpan = toHighlightSpan; function getTextSpan(node) { var start = node.getStart(); var end = node.getEnd(); if (node.kind === 9 /* StringLiteral */) { start += 1; end -= 1; } return ts.createTextSpanFromBounds(start, end); } /** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */ function isWriteAccessForReference(node) { return node.kind === 79 /* DefaultKeyword */ || ts.isAnyDeclarationName(node) || ts.isWriteAccess(node); } })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {})); })(ts || (ts = {})); /** Encapsulates the core find-all-references algorithm. */ /* @internal */ (function (ts) { var FindAllReferences; (function (FindAllReferences) { var Core; (function (Core) { /** Core find-all-references algorithm. Handles special cases before delegating to `getReferencedSymbolsForSymbol`. */ function getReferencedSymbolsForNode(node, program, sourceFiles, cancellationToken, options) { if (options === void 0) { options = {}; } if (node.kind === 269 /* SourceFile */) { return undefined; } if (!options.implementations) { var special = getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken); if (special) { return special; } } var checker = program.getTypeChecker(); var symbol = checker.getSymbolAtLocation(node); // Could not find a symbol e.g. unknown identifier if (!symbol) { // String literal might be a property (and thus have a symbol), so do this here rather than in getReferencedSymbolsSpecial. if (!options.implementations && node.kind === 9 /* StringLiteral */) { return getReferencesForStringLiteral(node, sourceFiles, cancellationToken); } // Can't have references to something that we have no symbol for. return undefined; } if (symbol.flags & 1536 /* Module */ && isModuleReferenceLocation(node)) { return getReferencedSymbolsForModule(program, symbol, sourceFiles); } return getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options); } Core.getReferencedSymbolsForNode = getReferencedSymbolsForNode; function isModuleReferenceLocation(node) { if (node.kind !== 9 /* StringLiteral */) { return false; } switch (node.parent.kind) { case 234 /* ModuleDeclaration */: case 249 /* ExternalModuleReference */: case 239 /* ImportDeclaration */: case 245 /* ExportDeclaration */: return true; case 182 /* CallExpression */: return ts.isRequireCall(node.parent, /*checkArgumentIsStringLiteral*/ false) || ts.isImportCall(node.parent); default: return false; } } function getReferencedSymbolsForModule(program, symbol, sourceFiles) { ts.Debug.assert(!!symbol.valueDeclaration); var references = FindAllReferences.findModuleReferences(program, sourceFiles, symbol).map(function (reference) { if (reference.kind === "import") { return { type: "node", node: reference.literal }; } else { return { type: "span", fileName: reference.referencingFile.fileName, textSpan: ts.createTextSpanFromRange(reference.ref), }; } }); for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var decl = _a[_i]; switch (decl.kind) { case 269 /* SourceFile */: // Don't include the source file itself. (This may not be ideal behavior, but awkward to include an entire file as a reference.) break; case 234 /* ModuleDeclaration */: references.push({ type: "node", node: decl.name }); break; default: ts.Debug.fail("Expected a module symbol to be declared by a SourceFile or ModuleDeclaration."); } } return [{ definition: { type: "symbol", symbol: symbol, node: symbol.valueDeclaration }, references: references }]; } /** getReferencedSymbols for special node kinds. */ function getReferencedSymbolsSpecial(node, sourceFiles, cancellationToken) { if (ts.isTypeKeyword(node.kind)) { return getAllReferencesForKeyword(sourceFiles, node.kind, cancellationToken); } // Labels if (ts.isLabelName(node)) { if (ts.isJumpStatementTarget(node)) { var labelDefinition = ts.getTargetLabel(node.parent, node.text); // if we have a label definition, look within its statement for references, if not, then // the label is undefined and we have no results.. return labelDefinition && getLabelReferencesInNode(labelDefinition.parent, labelDefinition); } else { // it is a label definition and not a target, search within the parent labeledStatement return getLabelReferencesInNode(node.parent, node); } } if (ts.isThis(node)) { return getReferencesForThisKeyword(node, sourceFiles, cancellationToken); } if (node.kind === 97 /* SuperKeyword */) { return getReferencesForSuperKeyword(node); } return undefined; } /** Core find-all-references algorithm for a normal symbol. */ function getReferencedSymbolsForSymbol(symbol, node, sourceFiles, checker, cancellationToken, options) { symbol = skipPastExportOrImportSpecifier(symbol, node, checker); // Compute the meaning from the location and the symbol it references var searchMeaning = getIntersectingMeaningFromDeclarations(ts.getMeaningFromLocation(node), symbol.declarations); var result = []; var state = new State(sourceFiles, /*isForConstructor*/ node.kind === 123 /* ConstructorKeyword */, checker, cancellationToken, searchMeaning, options, result); if (node.kind === 79 /* DefaultKeyword */) { addReference(node, symbol, node, state); searchForImportsOfExport(node, symbol, { exportingModuleSymbol: symbol.parent, exportKind: 1 /* Default */ }, state); } else { var search = state.createSearch(node, symbol, /*comingFrom*/ undefined, { allSearchSymbols: populateSearchSymbolSet(symbol, node, checker, options.implementations) }); // Try to get the smallest valid scope that we can limit our search to; // otherwise we'll need to search globally (i.e. include each file). var scope = getSymbolScope(symbol); if (scope) { getReferencesInContainer(scope, scope.getSourceFile(), search, state); } else { // Global search for (var _i = 0, _a = state.sourceFiles; _i < _a.length; _i++) { var sourceFile = _a[_i]; state.cancellationToken.throwIfCancellationRequested(); searchForName(sourceFile, search, state); } } } return result; } /** Handle a few special cases relating to export/import specifiers. */ function skipPastExportOrImportSpecifier(symbol, node, checker) { var parent = node.parent; if (ts.isExportSpecifier(parent)) { return getLocalSymbolForExportSpecifier(node, symbol, parent, checker); } if (ts.isImportSpecifier(parent) && parent.propertyName === node) { // We're at `foo` in `import { foo as bar }`. Probably intended to find all refs on the original, not just on the import. return checker.getImmediateAliasedSymbol(symbol); } return symbol; } /** * Holds all state needed for the finding references. * Unlike `Search`, there is only one `State`. */ var State = /** @class */ (function () { function State(sourceFiles, /** True if we're searching for constructor references. */ isForConstructor, checker, cancellationToken, searchMeaning, options, result) { this.sourceFiles = sourceFiles; this.isForConstructor = isForConstructor; this.checker = checker; this.cancellationToken = cancellationToken; this.searchMeaning = searchMeaning; this.options = options; this.result = result; /** Cache for `explicitlyinheritsFrom`. */ this.inheritsFromCache = ts.createMap(); /** * Type nodes can contain multiple references to the same type. For example: * let x: Foo & (Foo & Bar) = ... * Because we are returning the implementation locations and not the identifier locations, * duplicate entries would be returned here as each of the type references is part of * the same implementation. For that reason, check before we add a new entry. */ this.markSeenContainingTypeReference = ts.nodeSeenTracker(); /** * It's possible that we will encounter the right side of `export { foo as bar } from "x";` more than once. * For example: * // b.ts * export { foo as bar } from "./a"; * import { bar } from "./b"; * * Normally at `foo as bar` we directly add `foo` and do not locally search for it (since it doesn't declare a local). * But another reference to it may appear in the same source file. * See `tests/cases/fourslash/transitiveExportImports3.ts`. */ this.markSeenReExportRHS = ts.nodeSeenTracker(); this.symbolIdToReferences = []; // Source file ID → symbol ID → Whether the symbol has been searched for in the source file. this.sourceFileToSeenSymbols = []; } /** Gets every place to look for references of an exported symbols. See `ImportsResult` in `importTracker.ts` for more documentation. */ State.prototype.getImportSearches = function (exportSymbol, exportInfo) { if (!this.importTracker) this.importTracker = FindAllReferences.createImportTracker(this.sourceFiles, this.checker, this.cancellationToken); return this.importTracker(exportSymbol, exportInfo, this.options.isForRename); }; /** @param allSearchSymbols set of additinal symbols for use by `includes`. */ State.prototype.createSearch = function (location, symbol, comingFrom, searchOptions) { if (searchOptions === void 0) { searchOptions = {}; } // Note: if this is an external module symbol, the name doesn't include quotes. var _a = searchOptions.text, text = _a === void 0 ? ts.stripQuotes(ts.unescapeLeadingUnderscores((ts.getLocalSymbolForExportDefault(symbol) || symbol).escapedName)) : _a, _b = searchOptions.allSearchSymbols, allSearchSymbols = _b === void 0 ? undefined : _b; var escapedText = ts.escapeLeadingUnderscores(text); var parents = this.options.implementations && getParentSymbolsOfPropertyAccess(location, symbol, this.checker); return { location: location, symbol: symbol, comingFrom: comingFrom, text: text, escapedText: escapedText, parents: parents, includes: function (referenceSymbol) { return allSearchSymbols ? ts.contains(allSearchSymbols, referenceSymbol) : referenceSymbol === symbol; }, }; }; /** * Callback to add references for a particular searched symbol. * This initializes a reference group, so only call this if you will add at least one reference. */ State.prototype.referenceAdder = function (searchSymbol, searchLocation) { var symbolId = ts.getSymbolId(searchSymbol); var references = this.symbolIdToReferences[symbolId]; if (!references) { references = this.symbolIdToReferences[symbolId] = []; this.result.push({ definition: { type: "symbol", symbol: searchSymbol, node: searchLocation }, references: references }); } return function (node) { return references.push(FindAllReferences.nodeEntry(node)); }; }; /** Add a reference with no associated definition. */ State.prototype.addStringOrCommentReference = function (fileName, textSpan) { this.result.push({ definition: undefined, references: [{ type: "span", fileName: fileName, textSpan: textSpan }] }); }; /** Returns `true` the first time we search for a symbol in a file and `false` afterwards. */ State.prototype.markSearchedSymbol = function (sourceFile, symbol) { var sourceId = ts.getNodeId(sourceFile); var symbolId = ts.getSymbolId(symbol); var seenSymbols = this.sourceFileToSeenSymbols[sourceId] || (this.sourceFileToSeenSymbols[sourceId] = []); return !seenSymbols[symbolId] && (seenSymbols[symbolId] = true); }; return State; }()); /** Search for all imports of a given exported symbol using `State.getImportSearches`. */ function searchForImportsOfExport(exportLocation, exportSymbol, exportInfo, state) { var _a = state.getImportSearches(exportSymbol, exportInfo), importSearches = _a.importSearches, singleReferences = _a.singleReferences, indirectUsers = _a.indirectUsers; // For `import { foo as bar }` just add the reference to `foo`, and don't otherwise search in the file. if (singleReferences.length) { var addRef = state.referenceAdder(exportSymbol, exportLocation); for (var _i = 0, singleReferences_1 = singleReferences; _i < singleReferences_1.length; _i++) { var singleRef = singleReferences_1[_i]; addRef(singleRef); } } // For each import, find all references to that import in its source file. for (var _b = 0, importSearches_1 = importSearches; _b < importSearches_1.length; _b++) { var _c = importSearches_1[_b], importLocation = _c[0], importSymbol = _c[1]; getReferencesInSourceFile(importLocation.getSourceFile(), state.createSearch(importLocation, importSymbol, 1 /* Export */), state); } if (indirectUsers.length) { var indirectSearch = void 0; switch (exportInfo.exportKind) { case 0 /* Named */: indirectSearch = state.createSearch(exportLocation, exportSymbol, 1 /* Export */); break; case 1 /* Default */: // Search for a property access to '.default'. This can't be renamed. indirectSearch = state.options.isForRename ? undefined : state.createSearch(exportLocation, exportSymbol, 1 /* Export */, { text: "default" }); break; case 2 /* ExportEquals */: break; } if (indirectSearch) { for (var _d = 0, indirectUsers_1 = indirectUsers; _d < indirectUsers_1.length; _d++) { var indirectUser = indirectUsers_1[_d]; searchForName(indirectUser, indirectSearch, state); } } } } // Go to the symbol we imported from and find references for it. function searchForImportedSymbol(symbol, state) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; getReferencesInSourceFile(declaration.getSourceFile(), state.createSearch(declaration, symbol, 0 /* Import */), state); } } /** Search for all occurences of an identifier in a source file (and filter out the ones that match). */ function searchForName(sourceFile, search, state) { if (ts.getNameTable(sourceFile).get(search.escapedText) !== undefined) { getReferencesInSourceFile(sourceFile, search, state); } } function getPropertySymbolOfDestructuringAssignment(location, checker) { return ts.isArrayLiteralOrObjectLiteralDestructuringPattern(location.parent.parent) && checker.getPropertySymbolOfDestructuringAssignment(location); } function getObjectBindingElementWithoutPropertyName(symbol) { var bindingElement = ts.getDeclarationOfKind(symbol, 177 /* BindingElement */); if (bindingElement && bindingElement.parent.kind === 175 /* ObjectBindingPattern */ && !bindingElement.propertyName) { return bindingElement; } } function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker) { var bindingElement = getObjectBindingElementWithoutPropertyName(symbol); if (!bindingElement) return undefined; var typeOfPattern = checker.getTypeAtLocation(bindingElement.parent); var propSymbol = typeOfPattern && checker.getPropertyOfType(typeOfPattern, bindingElement.name.text); if (propSymbol && propSymbol.flags & 98304 /* Accessor */) { // See GH#16922 ts.Debug.assert(!!(propSymbol.flags & 33554432 /* Transient */)); return propSymbol.target; } return propSymbol; } /** * Determines the smallest scope in which a symbol may have named references. * Note that not every construct has been accounted for. This function can * probably be improved. * * @returns undefined if the scope cannot be determined, implying that * a reference to a symbol can occur anywhere. */ function getSymbolScope(symbol) { // If this is the symbol of a named function expression or named class expression, // then named references are limited to its own scope. var declarations = symbol.declarations, flags = symbol.flags, parent = symbol.parent, valueDeclaration = symbol.valueDeclaration; if (valueDeclaration && (valueDeclaration.kind === 187 /* FunctionExpression */ || valueDeclaration.kind === 200 /* ClassExpression */)) { return valueDeclaration; } if (!declarations) { return undefined; } // If this is private property or method, the scope is the containing class if (flags & (4 /* Property */ | 8192 /* Method */)) { var privateDeclaration = ts.find(declarations, function (d) { return ts.hasModifier(d, 8 /* Private */); }); if (privateDeclaration) { return ts.getAncestor(privateDeclaration, 230 /* ClassDeclaration */); } // Else this is a public property and could be accessed from anywhere. return undefined; } // If symbol is of object binding pattern element without property name we would want to // look for property too and that could be anywhere if (getObjectBindingElementWithoutPropertyName(symbol)) { return undefined; } /* If the symbol has a parent, it's globally visible unless: - It's a private property (handled above). - It's a type parameter. - The parent is an external module: then we should only search in the module (and recurse on the export later). - But if the parent has `export as namespace`, the symbol is globally visible through that namespace. */ var exposedByParent = parent && !(symbol.flags & 262144 /* TypeParameter */); if (exposedByParent && !((parent.flags & 1536 /* Module */) && ts.isExternalModuleSymbol(parent) && !parent.globalExports)) { return undefined; } var scope; for (var _i = 0, declarations_9 = declarations; _i < declarations_9.length; _i++) { var declaration = declarations_9[_i]; var container = ts.getContainerNode(declaration); if (scope && scope !== container) { // Different declarations have different containers, bail out return undefined; } if (!container || container.kind === 269 /* SourceFile */ && !ts.isExternalOrCommonJsModule(container)) { // This is a global variable and not an external module, any declaration defined // within this scope is visible outside the file return undefined; } // The search scope is the container node scope = container; } // If symbol.parent, this means we are in an export of an external module. (Otherwise we would have returned `undefined` above.) // For an export of a module, we may be in a declaration file, and it may be accessed elsewhere. E.g.: // declare module "a" { export type T = number; } // declare module "b" { import { T } from "a"; export const x: T; } // So we must search the whole source file. (Because we will mark the source file as seen, we we won't return to it when searching for imports.) return exposedByParent ? scope.getSourceFile() : scope; } function getPossibleSymbolReferencePositions(sourceFile, symbolName, container) { if (container === void 0) { container = sourceFile; } var positions = []; /// TODO: Cache symbol existence for files to save text search // Also, need to make this work for unicode escapes. // Be resilient in the face of a symbol with no name or zero length name if (!symbolName || !symbolName.length) { return positions; } var text = sourceFile.text; var sourceLength = text.length; var symbolNameLength = symbolName.length; var position = text.indexOf(symbolName, container.pos); while (position >= 0) { // If we are past the end, stop looking if (position > container.end) break; // We found a match. Make sure it's not part of a larger word (i.e. the char // before and after it have to be a non-identifier char). var endPosition = position + symbolNameLength; if ((position === 0 || !ts.isIdentifierPart(text.charCodeAt(position - 1), 6 /* Latest */)) && (endPosition === sourceLength || !ts.isIdentifierPart(text.charCodeAt(endPosition), 6 /* Latest */))) { // Found a real match. Keep searching. positions.push(position); } position = text.indexOf(symbolName, position + symbolNameLength + 1); } return positions; } function getLabelReferencesInNode(container, targetLabel) { var references = []; var sourceFile = container.getSourceFile(); var labelName = targetLabel.text; var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, labelName, container); for (var _i = 0, possiblePositions_1 = possiblePositions; _i < possiblePositions_1.length; _i++) { var position = possiblePositions_1[_i]; var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false); // Only pick labels that are either the target label, or have a target that is the target label if (node && (node === targetLabel || (ts.isJumpStatementTarget(node) && ts.getTargetLabel(node, labelName) === targetLabel))) { references.push(FindAllReferences.nodeEntry(node)); } } return [{ definition: { type: "label", node: targetLabel }, references: references }]; } function isValidReferencePosition(node, searchSymbolName) { // Compare the length so we filter out strict superstrings of the symbol we are looking for switch (node.kind) { case 71 /* Identifier */: return node.text.length === searchSymbolName.length; case 9 /* StringLiteral */: return (ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) && node.text.length === searchSymbolName.length; case 8 /* NumericLiteral */: return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node) && node.text.length === searchSymbolName.length; case 79 /* DefaultKeyword */: return "default".length === searchSymbolName.length; default: return false; } } function getAllReferencesForKeyword(sourceFiles, keywordKind, cancellationToken) { var references = []; for (var _i = 0, sourceFiles_6 = sourceFiles; _i < sourceFiles_6.length; _i++) { var sourceFile = sourceFiles_6[_i]; cancellationToken.throwIfCancellationRequested(); addReferencesForKeywordInFile(sourceFile, keywordKind, ts.tokenToString(keywordKind), references); } return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references: references }] : undefined; } function addReferencesForKeywordInFile(sourceFile, kind, searchText, references) { var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, searchText, sourceFile); for (var _i = 0, possiblePositions_2 = possiblePositions; _i < possiblePositions_2.length; _i++) { var position = possiblePositions_2[_i]; var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (referenceLocation.kind === kind) { references.push(FindAllReferences.nodeEntry(referenceLocation)); } } } function getReferencesInSourceFile(sourceFile, search, state) { state.cancellationToken.throwIfCancellationRequested(); return getReferencesInContainer(sourceFile, sourceFile, search, state); } /** * Search within node "container" for references for a search value, where the search value is defined as a * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). * searchLocation: a node where the search value */ function getReferencesInContainer(container, sourceFile, search, state) { if (!state.markSearchedSymbol(sourceFile, search.symbol)) { return; } for (var _i = 0, _a = getPossibleSymbolReferencePositions(sourceFile, search.text, container); _i < _a.length; _i++) { var position = _a[_i]; getReferencesAtLocation(sourceFile, position, search, state); } } function getReferencesAtLocation(sourceFile, position, search, state) { var referenceLocation = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (!isValidReferencePosition(referenceLocation, search.text)) { // This wasn't the start of a token. Check to see if it might be a // match in a comment or string if that's what the caller is asking // for. if (!state.options.implementations && (state.options.findInStrings && ts.isInString(sourceFile, position) || state.options.findInComments && ts.isInNonReferenceComment(sourceFile, position))) { // In the case where we're looking inside comments/strings, we don't have // an actual definition. So just use 'undefined' here. Features like // 'Rename' won't care (as they ignore the definitions), and features like // 'FindReferences' will just filter out these results. state.addStringOrCommentReference(sourceFile.fileName, ts.createTextSpan(position, search.text.length)); } return; } if (!(ts.getMeaningFromLocation(referenceLocation) & state.searchMeaning)) { return; } var referenceSymbol = state.checker.getSymbolAtLocation(referenceLocation); if (!referenceSymbol) { return; } var parent = referenceLocation.parent; if (ts.isImportSpecifier(parent) && parent.propertyName === referenceLocation) { // This is added through `singleReferences` in ImportsResult. If we happen to see it again, don't add it again. return; } if (ts.isExportSpecifier(parent)) { ts.Debug.assert(referenceLocation.kind === 71 /* Identifier */); getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, parent, search, state); return; } var relatedSymbol = getRelatedSymbol(search, referenceSymbol, referenceLocation, state); if (!relatedSymbol) { getReferenceForShorthandProperty(referenceSymbol, search, state); return; } if (state.isForConstructor) { findConstructorReferences(referenceLocation, sourceFile, search, state); } else { addReference(referenceLocation, relatedSymbol, search.location, state); } getImportOrExportReferences(referenceLocation, referenceSymbol, search, state); } function getReferencesAtExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, search, state) { var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name; var exportDeclaration = parent.parent; var localSymbol = getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, state.checker); if (!search.includes(localSymbol)) { return; } if (!propertyName) { addRef(); } else if (referenceLocation === propertyName) { // For `export { foo as bar } from "baz"`, "`foo`" will be added from the singleReferences for import searches of the original export. // For `export { foo as bar };`, where `foo` is a local, so add it now. if (!exportDeclaration.moduleSpecifier) { addRef(); } if (!state.options.isForRename && state.markSeenReExportRHS(name)) { addReference(name, referenceSymbol, name, state); } } else { if (state.markSeenReExportRHS(referenceLocation)) { addRef(); } } // For `export { foo as bar }`, rename `foo`, but not `bar`. if (!(referenceLocation === propertyName && state.options.isForRename)) { var exportKind = referenceLocation.originalKeywordKind === 79 /* DefaultKeyword */ ? 1 /* Default */ : 0 /* Named */; var exportInfo = FindAllReferences.getExportInfo(referenceSymbol, exportKind, state.checker); ts.Debug.assert(!!exportInfo); searchForImportsOfExport(referenceLocation, referenceSymbol, exportInfo, state); } // At `export { x } from "foo"`, also search for the imported symbol `"foo".x`. if (search.comingFrom !== 1 /* Export */ && exportDeclaration.moduleSpecifier && !propertyName) { searchForImportedSymbol(state.checker.getExportSpecifierLocalTargetSymbol(exportSpecifier), state); } function addRef() { addReference(referenceLocation, localSymbol, search.location, state); } } function getLocalSymbolForExportSpecifier(referenceLocation, referenceSymbol, exportSpecifier, checker) { return isExportSpecifierAlias(referenceLocation, exportSpecifier) ? checker.getExportSpecifierLocalTargetSymbol(exportSpecifier) : referenceSymbol; } function isExportSpecifierAlias(referenceLocation, exportSpecifier) { var parent = exportSpecifier.parent, propertyName = exportSpecifier.propertyName, name = exportSpecifier.name; ts.Debug.assert(propertyName === referenceLocation || name === referenceLocation); if (propertyName) { // Given `export { foo as bar } [from "someModule"]`: It's an alias at `foo`, but at `bar` it's a new symbol. return propertyName === referenceLocation; } else { // `export { foo } from "foo"` is a re-export. // `export { foo };` is not a re-export, it creates an alias for the local variable `foo`. return !parent.parent.moduleSpecifier; } } function getImportOrExportReferences(referenceLocation, referenceSymbol, search, state) { var importOrExport = FindAllReferences.getImportOrExportSymbol(referenceLocation, referenceSymbol, state.checker, search.comingFrom === 1 /* Export */); if (!importOrExport) return; var symbol = importOrExport.symbol; if (importOrExport.kind === 0 /* Import */) { if (!state.options.isForRename || importOrExport.isNamedImport) { searchForImportedSymbol(symbol, state); } } else { // We don't check for `state.isForRename`, even for default exports, because importers that previously matched the export name should be updated to continue matching. searchForImportsOfExport(referenceLocation, symbol, importOrExport.exportInfo, state); } } function getReferenceForShorthandProperty(_a, search, state) { var flags = _a.flags, valueDeclaration = _a.valueDeclaration; var shorthandValueSymbol = state.checker.getShorthandAssignmentValueSymbol(valueDeclaration); /* * Because in short-hand property assignment, an identifier which stored as name of the short-hand property assignment * has two meanings: property name and property value. Therefore when we do findAllReference at the position where * an identifier is declared, the language service should return the position of the variable declaration as well as * the position in short-hand property assignment excluding property accessing. However, if we do findAllReference at the * position of property accessing, the referenceEntry of such position will be handled in the first case. */ if (!(flags & 33554432 /* Transient */) && search.includes(shorthandValueSymbol)) { addReference(ts.getNameOfDeclaration(valueDeclaration), shorthandValueSymbol, search.location, state); } } function addReference(referenceLocation, relatedSymbol, searchLocation, state) { var addRef = state.referenceAdder(relatedSymbol, searchLocation); if (state.options.implementations) { addImplementationReferences(referenceLocation, addRef, state); } else { addRef(referenceLocation); } } /** Adds references when a constructor is used with `new this()` in its own class and `super()` calls in subclasses. */ function findConstructorReferences(referenceLocation, sourceFile, search, state) { if (ts.isNewExpressionTarget(referenceLocation)) { addReference(referenceLocation, search.symbol, search.location, state); } var pusher = state.referenceAdder(search.symbol, search.location); if (ts.isClassLike(referenceLocation.parent)) { ts.Debug.assert(referenceLocation.parent.name === referenceLocation); // This is the class declaration containing the constructor. findOwnConstructorReferences(search.symbol, sourceFile, pusher); } else { // If this class appears in `extends C`, then the extending class' "super" calls are references. var classExtending = tryGetClassByExtendingIdentifier(referenceLocation); if (classExtending && ts.isClassLike(classExtending)) { findSuperConstructorAccesses(classExtending, pusher); } } } function getPropertyAccessExpressionFromRightHandSide(node) { return ts.isRightSideOfPropertyAccess(node) && node.parent; } /** * `classSymbol` is the class where the constructor was defined. * Reference the constructor and all calls to `new this()`. */ function findOwnConstructorReferences(classSymbol, sourceFile, addNode) { for (var _i = 0, _a = classSymbol.members.get("__constructor" /* Constructor */).declarations; _i < _a.length; _i++) { var decl = _a[_i]; var ctrKeyword = ts.findChildOfKind(decl, 123 /* ConstructorKeyword */, sourceFile); ts.Debug.assert(decl.kind === 153 /* Constructor */ && !!ctrKeyword); addNode(ctrKeyword); } classSymbol.exports.forEach(function (member) { var decl = member.valueDeclaration; if (decl && decl.kind === 152 /* MethodDeclaration */) { var body = decl.body; if (body) { forEachDescendantOfKind(body, 99 /* ThisKeyword */, function (thisKeyword) { if (ts.isNewExpressionTarget(thisKeyword)) { addNode(thisKeyword); } }); } } }); } /** Find references to `super` in the constructor of an extending class. */ function findSuperConstructorAccesses(cls, addNode) { var symbol = cls.symbol; var ctr = symbol.members.get("__constructor" /* Constructor */); if (!ctr) { return; } for (var _i = 0, _a = ctr.declarations; _i < _a.length; _i++) { var decl = _a[_i]; ts.Debug.assert(decl.kind === 153 /* Constructor */); var body = decl.body; if (body) { forEachDescendantOfKind(body, 97 /* SuperKeyword */, function (node) { if (ts.isCallExpressionTarget(node)) { addNode(node); } }); } } } function addImplementationReferences(refNode, addReference, state) { // Check if we found a function/propertyAssignment/method with an implementation or initializer if (ts.isDeclarationName(refNode) && isImplementation(refNode.parent)) { addReference(refNode.parent); return; } if (refNode.kind !== 71 /* Identifier */) { return; } if (refNode.parent.kind === 266 /* ShorthandPropertyAssignment */) { // Go ahead and dereference the shorthand assignment by going to its definition getReferenceEntriesForShorthandPropertyAssignment(refNode, state.checker, addReference); } // Check if the node is within an extends or implements clause var containingClass = getContainingClassIfInHeritageClause(refNode); if (containingClass) { addReference(containingClass); return; } // If we got a type reference, try and see if the reference applies to any expressions that can implement an interface var containingTypeReference = getContainingTypeReference(refNode); if (containingTypeReference && state.markSeenContainingTypeReference(containingTypeReference)) { var parent = containingTypeReference.parent; if (ts.isVariableLike(parent) && parent.type === containingTypeReference && parent.initializer && isImplementationExpression(parent.initializer)) { addReference(parent.initializer); } else if (ts.isFunctionLike(parent) && parent.type === containingTypeReference && parent.body) { var body = parent.body; if (body.kind === 208 /* Block */) { ts.forEachReturnStatement(body, function (returnStatement) { if (returnStatement.expression && isImplementationExpression(returnStatement.expression)) { addReference(returnStatement.expression); } }); } else if (isImplementationExpression(body)) { addReference(body); } } else if (ts.isAssertionExpression(parent) && isImplementationExpression(parent.expression)) { addReference(parent.expression); } } } function getSymbolsForClassAndInterfaceComponents(type, result) { if (result === void 0) { result = []; } for (var _i = 0, _a = type.types; _i < _a.length; _i++) { var componentType = _a[_i]; if (componentType.symbol && componentType.symbol.getFlags() & (32 /* Class */ | 64 /* Interface */)) { result.push(componentType.symbol); } if (componentType.getFlags() & 393216 /* UnionOrIntersection */) { getSymbolsForClassAndInterfaceComponents(componentType, result); } } return result; } function getContainingTypeReference(node) { var topLevelTypeReference = undefined; while (node) { if (ts.isTypeNode(node)) { topLevelTypeReference = node; } node = node.parent; } return topLevelTypeReference; } function getContainingClassIfInHeritageClause(node) { if (node && node.parent) { if (node.kind === 202 /* ExpressionWithTypeArguments */ && node.parent.kind === 263 /* HeritageClause */ && ts.isClassLike(node.parent.parent)) { return node.parent.parent; } else if (node.kind === 71 /* Identifier */ || node.kind === 180 /* PropertyAccessExpression */) { return getContainingClassIfInHeritageClause(node.parent); } } return undefined; } /** * Returns true if this is an expression that can be considered an implementation */ function isImplementationExpression(node) { switch (node.kind) { case 186 /* ParenthesizedExpression */: return isImplementationExpression(node.expression); case 188 /* ArrowFunction */: case 187 /* FunctionExpression */: case 179 /* ObjectLiteralExpression */: case 200 /* ClassExpression */: case 178 /* ArrayLiteralExpression */: return true; default: return false; } } /** * Determines if the parent symbol occurs somewhere in the child's ancestry. If the parent symbol * is an interface, determines if some ancestor of the child symbol extends or inherits from it. * Also takes in a cache of previous results which makes this slightly more efficient and is * necessary to avoid potential loops like so: * class A extends B { } * class B extends A { } * * We traverse the AST rather than using the type checker because users are typically only interested * in explicit implementations of an interface/class when calling "Go to Implementation". Sibling * implementations of types that share a common ancestor with the type whose implementation we are * searching for need to be filtered out of the results. The type checker doesn't let us make the * distinction between structurally compatible implementations and explicit implementations, so we * must use the AST. * * @param child A class or interface Symbol * @param parent Another class or interface Symbol * @param cachedResults A map of symbol id pairs (i.e. "child,parent") to booleans indicating previous results */ function explicitlyInheritsFrom(child, parent, cachedResults, checker) { var parentIsInterface = parent.getFlags() & 64 /* Interface */; return searchHierarchy(child); function searchHierarchy(symbol) { if (symbol === parent) { return true; } var key = ts.getSymbolId(symbol) + "," + ts.getSymbolId(parent); var cached = cachedResults.get(key); if (cached !== undefined) { return cached; } // Set the key so that we don't infinitely recurse cachedResults.set(key, false); var inherits = ts.forEach(symbol.getDeclarations(), function (declaration) { if (ts.isClassLike(declaration)) { if (parentIsInterface) { var interfaceReferences = ts.getClassImplementsHeritageClauseElements(declaration); if (interfaceReferences) { for (var _i = 0, interfaceReferences_1 = interfaceReferences; _i < interfaceReferences_1.length; _i++) { var typeReference = interfaceReferences_1[_i]; if (searchTypeReference(typeReference)) { return true; } } } } return searchTypeReference(ts.getClassExtendsHeritageClauseElement(declaration)); } else if (declaration.kind === 231 /* InterfaceDeclaration */) { if (parentIsInterface) { return ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), searchTypeReference); } } return false; }); cachedResults.set(key, inherits); return inherits; } function searchTypeReference(typeReference) { if (typeReference) { var type = checker.getTypeAtLocation(typeReference); if (type && type.symbol) { return searchHierarchy(type.symbol); } } return false; } } function getReferencesForSuperKeyword(superKeyword) { var searchSpaceNode = ts.getSuperContainer(superKeyword, /*stopOnFunctions*/ false); if (!searchSpaceNode) { return undefined; } // Whether 'super' occurs in a static context within a class. var staticFlag = 32 /* Static */; switch (searchSpaceNode.kind) { case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: staticFlag &= ts.getModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; default: return undefined; } var references = []; var sourceFile = searchSpaceNode.getSourceFile(); var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "super", searchSpaceNode); for (var _i = 0, possiblePositions_3 = possiblePositions; _i < possiblePositions_3.length; _i++) { var position = possiblePositions_3[_i]; var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false); if (!node || node.kind !== 97 /* SuperKeyword */) { continue; } var container = ts.getSuperContainer(node, /*stopOnFunctions*/ false); // If we have a 'super' container, we must have an enclosing class. // Now make sure the owning class is the same as the search-space // and has the same static qualifier as the original 'super's owner. if (container && (32 /* Static */ & ts.getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol) { references.push(FindAllReferences.nodeEntry(node)); } } return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol, node: superKeyword }, references: references }]; } function getReferencesForThisKeyword(thisOrSuperKeyword, sourceFiles, cancellationToken) { var searchSpaceNode = ts.getThisContainer(thisOrSuperKeyword, /* includeArrowFunctions */ false); // Whether 'this' occurs in a static context within a class. var staticFlag = 32 /* Static */; switch (searchSpaceNode.kind) { case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.isObjectLiteralMethod(searchSpaceNode)) { break; } // falls through case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: staticFlag &= ts.getModifierFlags(searchSpaceNode); searchSpaceNode = searchSpaceNode.parent; // re-assign to be the owning class break; case 269 /* SourceFile */: if (ts.isExternalModule(searchSpaceNode)) { return undefined; } // falls through case 229 /* FunctionDeclaration */: case 187 /* 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 === 269 /* SourceFile */) { ts.forEach(sourceFiles, function (sourceFile) { cancellationToken.throwIfCancellationRequested(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this"); getThisReferencesInFile(sourceFile, sourceFile, possiblePositions, references); }); } else { var sourceFile = searchSpaceNode.getSourceFile(); possiblePositions = getPossibleSymbolReferencePositions(sourceFile, "this", searchSpaceNode); getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, references); } return [{ definition: { type: "this", node: thisOrSuperKeyword }, references: references }]; function getThisReferencesInFile(sourceFile, searchSpaceNode, possiblePositions, result) { ts.forEach(possiblePositions, function (position) { var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false); if (!node || !ts.isThis(node)) { return; } var container = ts.getThisContainer(node, /* includeArrowFunctions */ false); switch (searchSpaceNode.kind) { case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: if (searchSpaceNode.symbol === container.symbol) { result.push(FindAllReferences.nodeEntry(node)); } break; case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: if (ts.isObjectLiteralMethod(searchSpaceNode) && searchSpaceNode.symbol === container.symbol) { result.push(FindAllReferences.nodeEntry(node)); } break; case 200 /* ClassExpression */: case 230 /* ClassDeclaration */: // Make sure the container belongs to the same class // and has the appropriate static modifier from the original container. if (container.parent && searchSpaceNode.symbol === container.parent.symbol && (ts.getModifierFlags(container) & 32 /* Static */) === staticFlag) { result.push(FindAllReferences.nodeEntry(node)); } break; case 269 /* SourceFile */: if (container.kind === 269 /* SourceFile */ && !ts.isExternalModule(container)) { result.push(FindAllReferences.nodeEntry(node)); } break; } }); } } function getReferencesForStringLiteral(node, sourceFiles, cancellationToken) { var references = []; for (var _i = 0, sourceFiles_7 = sourceFiles; _i < sourceFiles_7.length; _i++) { var sourceFile = sourceFiles_7[_i]; cancellationToken.throwIfCancellationRequested(); var possiblePositions = getPossibleSymbolReferencePositions(sourceFile, node.text); getReferencesForStringLiteralInFile(sourceFile, node.text, possiblePositions, references); } return [{ definition: { type: "string", node: node }, references: references }]; function getReferencesForStringLiteralInFile(sourceFile, searchText, possiblePositions, references) { for (var _i = 0, possiblePositions_4 = possiblePositions; _i < possiblePositions_4.length; _i++) { var position = possiblePositions_4[_i]; var node_8 = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ false); if (node_8 && node_8.kind === 9 /* StringLiteral */ && node_8.text === searchText) { references.push(FindAllReferences.nodeEntry(node_8, /*isInString*/ true)); } } } } // For certain symbol kinds, we need to include other symbols in the search set. // This is not needed when searching for re-exports. function populateSearchSymbolSet(symbol, location, checker, implementations) { // The search set contains at least the current symbol var result = [symbol]; var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(location); if (containingObjectLiteralElement) { // If the location is name of property symbol from object literal destructuring pattern // Search the property symbol // for ( { property: p2 } of elems) { } if (containingObjectLiteralElement.kind !== 266 /* ShorthandPropertyAssignment */) { var propertySymbol = getPropertySymbolOfDestructuringAssignment(location, checker); if (propertySymbol) { result.push(propertySymbol); } } // If the location is in a context sensitive location (i.e. in an object literal) try // to get a contextual type for it, and add the property symbol from the contextual // type to the search set ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), function (contextualSymbol) { ts.addRange(result, checker.getRootSymbols(contextualSymbol)); }); /* Because in short-hand property assignment, location has two meaning : property name and as value of the property * When we do findAllReference at the position of the short-hand property assignment, we would want to have references to position of * property name and variable declaration of the identifier. * Like in below example, when querying for all references for an identifier 'name', of the property assignment, the language service * should show both 'name' in 'obj' and 'name' in variable declaration * const name = "Foo"; * const obj = { name }; * In order to do that, we will populate the search set with the value symbol of the identifier as a value of the property assignment * so that when matching with potential reference symbol, both symbols from property declaration and variable declaration * will be included correctly. */ var shorthandValueSymbol = checker.getShorthandAssignmentValueSymbol(location.parent); if (shorthandValueSymbol) { result.push(shorthandValueSymbol); } } // If the symbol.valueDeclaration is a property parameter declaration, // we should include both parameter declaration symbol and property declaration symbol // Parameter Declaration symbol is only visible within function scope, so the symbol is stored in constructor.locals. // Property Declaration symbol is a member of the class, so the symbol is stored in its class Declaration.symbol.members ts.addRange(result, getParameterPropertySymbols(symbol, checker)); // If this is symbol of binding element without propertyName declaration in Object binding pattern // Include the property in the search var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol, checker); if (bindingElementPropertySymbol) { result.push(bindingElementPropertySymbol); addRootSymbols(bindingElementPropertySymbol); } addRootSymbols(symbol); return result; function addRootSymbols(sym) { // If this is a union property, add all the symbols from all its source symbols in all unioned types. // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list for (var _i = 0, _a = checker.getRootSymbols(sym); _i < _a.length; _i++) { var rootSymbol = _a[_i]; if (rootSymbol !== sym) { result.push(rootSymbol); } // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions if (!implementations && rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) { getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), checker); } } } } function getParameterPropertySymbols(symbol, checker) { return symbol.valueDeclaration && ts.isParameter(symbol.valueDeclaration) && ts.isParameterPropertyDeclaration(symbol.valueDeclaration) ? checker.getSymbolsOfParameterPropertyDeclaration(symbol.valueDeclaration, symbol.name) : undefined; } /** * Find symbol of the given property-name and add the symbol to the given result array * @param symbol a symbol to start searching for the given propertyName * @param propertyName a name of property to search for * @param result an array of symbol of found property symbols * @param previousIterationSymbolsCache a cache of symbol from previous iterations of calling this function to prevent infinite revisiting of the same symbol. * The value of previousIterationSymbol is undefined when the function is first called. */ function getPropertySymbolsFromBaseTypes(symbol, propertyName, result, previousIterationSymbolsCache, checker) { if (!symbol) { return; } // If the current symbol is the same as the previous-iteration symbol, we can just return the symbol that has already been visited // This is particularly important for the following cases, so that we do not infinitely visit the same symbol. // For example: // interface C extends C { // /*findRef*/propName: string; // } // The first time getPropertySymbolsFromBaseTypes is called when finding-all-references at propName, // the symbol argument will be the symbol of an interface "C" and previousIterationSymbol is undefined, // the function will add any found symbol of the property-name, then its sub-routine will call // getPropertySymbolsFromBaseTypes again to walk up any base types to prevent revisiting already // visited symbol, interface "C", the sub-routine will pass the current symbol as previousIterationSymbol. if (previousIterationSymbolsCache.has(symbol.escapedName)) { return; } if (symbol.flags & (32 /* Class */ | 64 /* Interface */)) { ts.forEach(symbol.getDeclarations(), function (declaration) { if (ts.isClassLike(declaration)) { getPropertySymbolFromTypeReference(ts.getClassExtendsHeritageClauseElement(declaration)); ts.forEach(ts.getClassImplementsHeritageClauseElements(declaration), getPropertySymbolFromTypeReference); } else if (declaration.kind === 231 /* InterfaceDeclaration */) { ts.forEach(ts.getInterfaceBaseTypeNodes(declaration), getPropertySymbolFromTypeReference); } }); } return; function getPropertySymbolFromTypeReference(typeReference) { if (typeReference) { var type = checker.getTypeAtLocation(typeReference); if (type) { var propertySymbol = checker.getPropertyOfType(type, propertyName); if (propertySymbol) { result.push.apply(result, checker.getRootSymbols(propertySymbol)); } // Visit the typeReference as well to see if it directly or indirectly use that property previousIterationSymbolsCache.set(symbol.escapedName, symbol); getPropertySymbolsFromBaseTypes(type.symbol, propertyName, result, previousIterationSymbolsCache, checker); } } } } function getRelatedSymbol(search, referenceSymbol, referenceLocation, state) { var checker = state.checker; if (search.includes(referenceSymbol)) { return referenceSymbol; } if (referenceSymbol.flags & 1 /* FunctionScopedVariable */) { ts.Debug.assert(!(referenceSymbol.flags & 4 /* Property */)); var paramProps = getParameterPropertySymbols(referenceSymbol, checker); if (paramProps) { return getRelatedSymbol(search, ts.find(paramProps, function (x) { return !!(x.flags & 4 /* Property */); }), referenceLocation, state); } } // If the reference location is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this symbol to // compare to our searchSymbol var containingObjectLiteralElement = ts.getContainingObjectLiteralElement(referenceLocation); if (containingObjectLiteralElement) { var contextualSymbol = ts.forEach(getPropertySymbolsFromContextualType(containingObjectLiteralElement, checker), function (contextualSymbol) { return ts.find(checker.getRootSymbols(contextualSymbol), search.includes); }); if (contextualSymbol) { return contextualSymbol; } // If the reference location is the name of property from object literal destructuring pattern // Get the property symbol from the object literal's type and look if thats the search symbol // In below eg. get 'property' from type of elems iterating type // for ( { property: p2 } of elems) { } var propertySymbol = getPropertySymbolOfDestructuringAssignment(referenceLocation, checker); if (propertySymbol && search.includes(propertySymbol)) { return propertySymbol; } } // If the reference location is the binding element and doesn't have property name // then include the binding element in the related symbols // let { a } : { a }; var bindingElementPropertySymbol = getPropertySymbolOfObjectBindingPatternWithoutPropertyName(referenceSymbol, checker); if (bindingElementPropertySymbol) { var fromBindingElement = findRootSymbol(bindingElementPropertySymbol); if (fromBindingElement) return fromBindingElement; } return findRootSymbol(referenceSymbol); function findRootSymbol(sym) { // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening) // Or a union property, use its underlying unioned symbols return ts.forEach(state.checker.getRootSymbols(sym), function (rootSymbol) { // if it is in the list, then we are done if (search.includes(rootSymbol)) { return rootSymbol; } // Finally, try all properties with the same name in any type the containing type extended or implemented, and // see if any is in the list. If we were passed a parent symbol, only include types that are subtypes of the // parent symbol if (rootSymbol.parent && rootSymbol.parent.flags & (32 /* Class */ | 64 /* Interface */)) { // Parents will only be defined if implementations is true if (search.parents && !ts.some(search.parents, function (parent) { return explicitlyInheritsFrom(rootSymbol.parent, parent, state.inheritsFromCache, state.checker); })) { return undefined; } var result = []; getPropertySymbolsFromBaseTypes(rootSymbol.parent, rootSymbol.name, result, /*previousIterationSymbolsCache*/ ts.createSymbolTable(), state.checker); return ts.find(result, search.includes); } return undefined; }); } } function getNameFromObjectLiteralElement(node) { if (node.name.kind === 145 /* ComputedPropertyName */) { var nameExpression = node.name.expression; // treat computed property names where expression is string/numeric literal as just string/numeric literal if (ts.isStringOrNumericLiteral(nameExpression)) { return nameExpression.text; } return undefined; } return ts.getTextOfIdentifierOrLiteral(node.name); } /** Gets all symbols for one property. Does not get symbols for every property. */ function getPropertySymbolsFromContextualType(node, checker) { var objectLiteral = node.parent; var contextualType = checker.getContextualType(objectLiteral); var name = getNameFromObjectLiteralElement(node); if (name && contextualType) { var result_5 = []; var symbol = contextualType.getProperty(name); if (symbol) { result_5.push(symbol); } if (contextualType.flags & 131072 /* 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 = ts.getMeaningFromDeclaration(declaration); if (declarationMeaning & meaning) { meaning |= declarationMeaning; } } } while (meaning !== lastIterationMeaning); } return meaning; } function isImplementation(node) { if (!node) { return false; } else if (ts.isVariableLike(node)) { if (node.initializer) { return true; } else if (node.kind === 227 /* VariableDeclaration */) { var parentStatement = getParentStatementOfVariableDeclaration(node); return parentStatement && ts.hasModifier(parentStatement, 2 /* Ambient */); } } else if (ts.isFunctionLike(node)) { return !!node.body || ts.hasModifier(node, 2 /* Ambient */); } else { switch (node.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 233 /* EnumDeclaration */: case 234 /* ModuleDeclaration */: return true; } } return false; } function getParentStatementOfVariableDeclaration(node) { if (node.parent && node.parent.parent && node.parent.parent.kind === 209 /* VariableStatement */) { ts.Debug.assert(node.parent.kind === 228 /* VariableDeclarationList */); return node.parent.parent; } } function getReferenceEntriesForShorthandPropertyAssignment(node, checker, addReference) { var refSymbol = checker.getSymbolAtLocation(node); var shorthandSymbol = checker.getShorthandAssignmentValueSymbol(refSymbol.valueDeclaration); if (shorthandSymbol) { for (var _i = 0, _a = shorthandSymbol.getDeclarations(); _i < _a.length; _i++) { var declaration = _a[_i]; if (ts.getMeaningFromDeclaration(declaration) & 1 /* Value */) { addReference(declaration); } } } } Core.getReferenceEntriesForShorthandPropertyAssignment = getReferenceEntriesForShorthandPropertyAssignment; function forEachDescendantOfKind(node, kind, action) { ts.forEachChild(node, function (child) { if (child.kind === kind) { action(child); } forEachDescendantOfKind(child, kind, action); }); } /** Get `C` given `N` if `N` is in the position `class C extends N` or `class C extends foo.N` where `N` is an identifier. */ function tryGetClassByExtendingIdentifier(node) { return ts.tryGetClassExtendingExpressionWithTypeArguments(ts.climbPastPropertyAccess(node).parent); } function isNameOfExternalModuleImportOrDeclaration(node) { if (node.kind === 9 /* StringLiteral */) { return ts.isNameOfModuleDeclaration(node) || ts.isExpressionOfExternalModuleImportEqualsDeclaration(node); } return false; } /** * If we are just looking for implementations and this is a property access expression, we need to get the * symbol of the local type of the symbol the property is being accessed on. This is because our search * symbol may have a different parent symbol if the local type's symbol does not declare the property * being accessed (i.e. it is declared in some parent class or interface) */ function getParentSymbolsOfPropertyAccess(location, symbol, checker) { var propertyAccessExpression = getPropertyAccessExpressionFromRightHandSide(location); if (!propertyAccessExpression) { return undefined; } var localParentType = checker.getTypeAtLocation(propertyAccessExpression.expression); if (!localParentType) { return undefined; } if (localParentType.symbol && localParentType.symbol.flags & (32 /* Class */ | 64 /* Interface */) && localParentType.symbol !== symbol.parent) { return [localParentType.symbol]; } else if (localParentType.flags & 393216 /* UnionOrIntersection */) { return getSymbolsForClassAndInterfaceComponents(localParentType); } } })(Core = FindAllReferences.Core || (FindAllReferences.Core = {})); })(FindAllReferences = ts.FindAllReferences || (ts.FindAllReferences = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var GoToDefinition; (function (GoToDefinition) { function getDefinitionAtPosition(program, sourceFile, position) { /// Triple slash reference comments var comment = findReferenceInPosition(sourceFile.referencedFiles, position); if (comment) { var referenceFile = ts.tryResolveScriptReference(program, sourceFile, comment); if (referenceFile) { return [getDefinitionInfoForFileReference(comment.fileName, referenceFile.fileName)]; } // Might still be on jsdoc, so keep looking. } // Type reference directives var typeReferenceDirective = findReferenceInPosition(sourceFile.typeReferenceDirectives, position); if (typeReferenceDirective) { var referenceFile = program.getResolvedTypeReferenceDirectives().get(typeReferenceDirective.fileName); return referenceFile && referenceFile.resolvedFileName && [getDefinitionInfoForFileReference(typeReferenceDirective.fileName, referenceFile.resolvedFileName)]; } var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (node === sourceFile) { return undefined; } // Labels if (ts.isJumpStatementTarget(node)) { var labelName = node.text; var label = ts.getTargetLabel(node.parent, labelName); return label ? [createDefinitionInfoFromName(label, "label" /* label */, labelName, /*containerName*/ undefined)] : undefined; } var typeChecker = program.getTypeChecker(); var calledDeclaration = tryGetSignatureDeclaration(typeChecker, node); if (calledDeclaration) { return [createDefinitionFromSignatureDeclaration(typeChecker, calledDeclaration)]; } var symbol = typeChecker.getSymbolAtLocation(node); // Could not find a symbol e.g. node is string or number keyword, // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol if (!symbol) { return undefined; } // If this is an alias, and the request came at the declaration location // get the aliased symbol instead. This allows for goto def on an import e.g. // import {A, B} from "mod"; // to jump to the implementation directly. if (symbol.flags & 2097152 /* Alias */ && shouldSkipAlias(node, symbol.declarations[0])) { var aliased = typeChecker.getAliasedSymbol(symbol); if (aliased.declarations) { symbol = aliased; } } // Because name in short-hand property assignment has two different meanings: property name and property value, // using go-to-definition at such position should go to the variable declaration of the property value rather than // go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition // is performed at the location of property access, we would like to go to definition of the property in the short-hand // assignment. This case and others are handled by the following code. if (node.parent.kind === 266 /* ShorthandPropertyAssignment */) { var shorthandSymbol = typeChecker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration); if (!shorthandSymbol) { return []; } var shorthandDeclarations = shorthandSymbol.getDeclarations(); var shorthandSymbolKind_1 = ts.SymbolDisplay.getSymbolKind(typeChecker, shorthandSymbol, node); var shorthandSymbolName_1 = typeChecker.symbolToString(shorthandSymbol); var shorthandContainerName_1 = typeChecker.symbolToString(symbol.parent, node); return ts.map(shorthandDeclarations, function (declaration) { return createDefinitionInfo(declaration, shorthandSymbolKind_1, shorthandSymbolName_1, shorthandContainerName_1); }); } // If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the // declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern // and return the property declaration for the referenced property. // For example: // import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo" // // function bar(onfulfilled: (value: T) => void) { //....} // interface Test { // pr/*destination*/op1: number // } // bar(({pr/*goto*/op1})=>{}); if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) && (node === (node.parent.propertyName || node.parent.name))) { var type = typeChecker.getTypeAtLocation(node.parent.parent); if (type) { var propSymbols = ts.getPropertySymbolsFromType(type, node); if (propSymbols) { return ts.flatMap(propSymbols, function (propSymbol) { return getDefinitionFromSymbol(typeChecker, propSymbol, node); }); } } } // If the current location we want to find its definition is in an object literal, try to get the contextual type for the // object literal, lookup the property symbol in the contextual type, and use this for goto-definition. // For example // interface Props{ // /*first*/prop1: number // prop2: boolean // } // function Foo(arg: Props) {} // Foo( { pr/*1*/op1: 10, prop2: true }) var element = ts.getContainingObjectLiteralElement(node); if (element && typeChecker.getContextualType(element.parent)) { return ts.flatMap(ts.getPropertySymbolsFromContextualType(typeChecker, element), function (propertySymbol) { return getDefinitionFromSymbol(typeChecker, propertySymbol, node); }); } return getDefinitionFromSymbol(typeChecker, symbol, node); } GoToDefinition.getDefinitionAtPosition = getDefinitionAtPosition; /// Goto type function getTypeDefinitionAtPosition(typeChecker, sourceFile, position) { var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (node === sourceFile) { return undefined; } var symbol = typeChecker.getSymbolAtLocation(node); if (!symbol) { return undefined; } var type = typeChecker.getTypeOfSymbolAtLocation(symbol, node); if (!type) { return undefined; } if (type.flags & 131072 /* Union */ && !(type.flags & 16 /* Enum */)) { var result_6 = []; ts.forEach(type.types, function (t) { if (t.symbol) { ts.addRange(/*to*/ result_6, /*from*/ getDefinitionFromSymbol(typeChecker, t.symbol, node)); } }); return result_6; } if (!type.symbol) { return undefined; } return getDefinitionFromSymbol(typeChecker, type.symbol, node); } GoToDefinition.getTypeDefinitionAtPosition = getTypeDefinitionAtPosition; function getDefinitionAndBoundSpan(program, sourceFile, position) { var definitions = getDefinitionAtPosition(program, sourceFile, position); if (!definitions || definitions.length === 0) { return undefined; } // Check if position is on triple slash reference. var comment = findReferenceInPosition(sourceFile.referencedFiles, position) || findReferenceInPosition(sourceFile.typeReferenceDirectives, position); if (comment) { return { definitions: definitions, textSpan: ts.createTextSpanFromBounds(comment.pos, comment.end) }; } var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); var textSpan = ts.createTextSpan(node.getStart(), node.getWidth()); return { definitions: definitions, textSpan: textSpan }; } GoToDefinition.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan; // Go to the original declaration for cases: // // (1) when the aliased symbol was declared in the location(parent). // (2) when the aliased symbol is originating from an import. // function shouldSkipAlias(node, declaration) { if (node.kind !== 71 /* Identifier */) { return false; } if (node.parent === declaration) { return true; } switch (declaration.kind) { case 240 /* ImportClause */: case 238 /* ImportEqualsDeclaration */: return true; case 243 /* ImportSpecifier */: return declaration.parent.kind === 242 /* NamedImports */; default: return false; } } function getDefinitionFromSymbol(typeChecker, symbol, node) { var result = []; var declarations = symbol.getDeclarations(); var _a = getSymbolInfo(typeChecker, symbol, node), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName; if (!tryAddConstructSignature(symbol, node, symbolKind, symbolName, containerName, result) && !tryAddCallSignature(symbol, node, symbolKind, symbolName, containerName, result)) { // Just add all the declarations. ts.forEach(declarations, function (declaration) { result.push(createDefinitionInfo(declaration, symbolKind, symbolName, containerName)); }); } return result; function tryAddConstructSignature(symbol, location, symbolKind, symbolName, containerName, result) { // Applicable only if we are in a new expression, or we are on a constructor declaration // and in either case the symbol has a construct signature definition, i.e. class if (ts.isNewExpressionTarget(location) || location.kind === 123 /* ConstructorKeyword */) { if (symbol.flags & 32 /* Class */) { // Find the first class-like declaration and try to get the construct signature. for (var _i = 0, _a = symbol.getDeclarations(); _i < _a.length; _i++) { var declaration = _a[_i]; if (ts.isClassLike(declaration)) { return tryAddSignature(declaration.members, /*selectConstructors*/ true, symbolKind, symbolName, containerName, result); } } ts.Debug.fail("Expected declaration to have at least one class-like declaration"); } } return false; } function tryAddCallSignature(symbol, location, symbolKind, symbolName, containerName, result) { if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location) || ts.isNameOfFunctionDeclaration(location)) { return tryAddSignature(symbol.declarations, /*selectConstructors*/ false, symbolKind, symbolName, containerName, result); } return false; } function tryAddSignature(signatureDeclarations, selectConstructors, symbolKind, symbolName, containerName, result) { if (!signatureDeclarations) { return false; } var declarations = []; var definition; for (var _i = 0, signatureDeclarations_1 = signatureDeclarations; _i < signatureDeclarations_1.length; _i++) { var d = signatureDeclarations_1[_i]; if (selectConstructors ? d.kind === 153 /* Constructor */ : isSignatureDeclaration(d)) { declarations.push(d); if (d.body) definition = d; } } if (declarations.length) { result.push(createDefinitionInfo(definition || ts.lastOrUndefined(declarations), symbolKind, symbolName, containerName)); return true; } return false; } } function isSignatureDeclaration(node) { switch (node.kind) { case 153 /* Constructor */: case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: return true; default: return false; } } /** Creates a DefinitionInfo from a Declaration, using the declaration's name if possible. */ function createDefinitionInfo(node, symbolKind, symbolName, containerName) { return createDefinitionInfoFromName(ts.getNameOfDeclaration(node) || node, symbolKind, symbolName, containerName); } /** Creates a DefinitionInfo directly from the name of a declaration. */ function createDefinitionInfoFromName(name, symbolKind, symbolName, containerName) { var sourceFile = name.getSourceFile(); return { fileName: sourceFile.fileName, textSpan: ts.createTextSpanFromNode(name, sourceFile), kind: symbolKind, name: symbolName, containerKind: undefined, containerName: containerName }; } function getSymbolInfo(typeChecker, symbol, node) { return { symbolName: typeChecker.symbolToString(symbol), symbolKind: ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node), containerName: symbol.parent ? typeChecker.symbolToString(symbol.parent, node) : "" }; } function createDefinitionFromSignatureDeclaration(typeChecker, decl) { var _a = getSymbolInfo(typeChecker, decl.symbol, decl), symbolName = _a.symbolName, symbolKind = _a.symbolKind, containerName = _a.containerName; return createDefinitionInfo(decl, symbolKind, symbolName, containerName); } function findReferenceInPosition(refs, pos) { for (var _i = 0, refs_1 = refs; _i < refs_1.length; _i++) { var ref = refs_1[_i]; if (ref.pos <= pos && pos <= ref.end) { return ref; } } return undefined; } function getDefinitionInfoForFileReference(name, targetFileName) { return { fileName: targetFileName, textSpan: ts.createTextSpanFromBounds(0, 0), kind: "script" /* scriptElement */, name: name, containerName: undefined, containerKind: undefined }; } /** Returns a CallLikeExpression where `node` is the target being invoked. */ function getAncestorCallLikeExpression(node) { var target = climbPastManyPropertyAccesses(node); var callLike = target.parent; return callLike && ts.isCallLikeExpression(callLike) && ts.getInvokedExpression(callLike) === target && callLike; } function climbPastManyPropertyAccesses(node) { return ts.isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node; } function tryGetSignatureDeclaration(typeChecker, node) { var callLike = getAncestorCallLikeExpression(node); var signature = callLike && typeChecker.getResolvedSignature(callLike); if (signature) { var decl = signature.declaration; if (decl && isSignatureDeclaration(decl)) { return decl; } } // Don't go to a function type, go to the value having that type. return undefined; } })(GoToDefinition = ts.GoToDefinition || (ts.GoToDefinition = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var JsDoc; (function (JsDoc) { var singleLineTemplate = { newText: "/** */", caretOffset: 3 }; var jsDocTagNames = [ "augments", "author", "argument", "borrows", "class", "constant", "constructor", "constructs", "default", "deprecated", "description", "event", "example", "extends", "field", "fileOverview", "function", "ignore", "inheritDoc", "inner", "lends", "link", "memberOf", "method", "name", "namespace", "param", "private", "prop", "property", "public", "requires", "returns", "see", "since", "static", "throws", "type", "typedef", "version" ]; var jsDocTagNameCompletionEntries; var jsDocTagCompletionEntries; function getJsDocCommentsFromDeclarations(declarations) { // Only collect doc comments from duplicate declarations once: // In case of a union property there might be same declaration multiple times // which only varies in type parameter // Eg. const a: Array | Array; a.length // The property length will have two declarations of property length coming // from Array - Array and Array var documentationComment = []; forEachUnique(declarations, function (declaration) { ts.forEach(ts.getAllJSDocs(declaration), function (doc) { if (doc.comment) { if (documentationComment.length) { documentationComment.push(ts.lineBreakPart()); } documentationComment.push(ts.textPart(doc.comment)); } }); }); return documentationComment; } JsDoc.getJsDocCommentsFromDeclarations = getJsDocCommentsFromDeclarations; function getJsDocTagsFromDeclarations(declarations) { // Only collect doc comments from duplicate declarations once. var tags = []; forEachUnique(declarations, function (declaration) { for (var _i = 0, _a = ts.getJSDocTags(declaration); _i < _a.length; _i++) { var tag = _a[_i]; tags.push({ name: tag.tagName.text, text: getCommentText(tag) }); } }); return tags; } JsDoc.getJsDocTagsFromDeclarations = getJsDocTagsFromDeclarations; function getCommentText(tag) { var comment = tag.comment; switch (tag.kind) { case 282 /* JSDocAugmentsTag */: return withNode(tag.class); case 287 /* JSDocTemplateTag */: return withList(tag.typeParameters); case 286 /* JSDocTypeTag */: return withNode(tag.typeExpression); case 288 /* JSDocTypedefTag */: case 289 /* JSDocPropertyTag */: case 284 /* JSDocParameterTag */: var name = tag.name; return name ? withNode(name) : comment; default: return comment; } function withNode(node) { return node.getText() + " " + comment; } function withList(list) { return list.map(function (x) { return x.getText(); }) + " " + comment; } } /** * Iterates through 'array' by index and performs the callback on each element of array until the callback * returns a truthy value, then returns that value. * If no such value is found, the callback is applied to each element of array and undefined is returned. */ function forEachUnique(array, callback) { if (array) { for (var i = 0; i < array.length; i++) { if (ts.indexOf(array, array[i]) === i) { var result = callback(array[i], i); if (result) { return result; } } } } return undefined; } function getJSDocTagNameCompletions() { return jsDocTagNameCompletionEntries || (jsDocTagNameCompletionEntries = ts.map(jsDocTagNames, function (tagName) { return { name: tagName, kind: "keyword" /* keyword */, kindModifiers: "", sortText: "0", }; })); } JsDoc.getJSDocTagNameCompletions = getJSDocTagNameCompletions; JsDoc.getJSDocTagNameCompletionDetails = getJSDocTagCompletionDetails; function getJSDocTagCompletions() { return jsDocTagCompletionEntries || (jsDocTagCompletionEntries = ts.map(jsDocTagNames, function (tagName) { return { name: "@" + tagName, kind: "keyword" /* keyword */, kindModifiers: "", sortText: "0" }; })); } JsDoc.getJSDocTagCompletions = getJSDocTagCompletions; function getJSDocTagCompletionDetails(name) { return { name: name, kind: "" /* unknown */, kindModifiers: "", displayParts: [ts.textPart(name)], documentation: ts.emptyArray, tags: ts.emptyArray, codeActions: undefined, }; } JsDoc.getJSDocTagCompletionDetails = getJSDocTagCompletionDetails; function getJSDocParameterNameCompletions(tag) { if (!ts.isIdentifier(tag.name)) { return ts.emptyArray; } var nameThusFar = tag.name.text; var jsdoc = tag.parent; var fn = jsdoc.parent; if (!ts.isFunctionLike(fn)) return []; return ts.mapDefined(fn.parameters, function (param) { if (!ts.isIdentifier(param.name)) return undefined; var name = param.name.text; if (jsdoc.tags.some(function (t) { return t !== tag && ts.isJSDocParameterTag(t) && ts.isIdentifier(t.name) && t.name.escapedText === name; }) || nameThusFar !== undefined && !ts.startsWith(name, nameThusFar)) { return undefined; } return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", sortText: "0" }; }); } JsDoc.getJSDocParameterNameCompletions = getJSDocParameterNameCompletions; function getJSDocParameterNameCompletionDetails(name) { return { name: name, kind: "parameter" /* parameterElement */, kindModifiers: "", displayParts: [ts.textPart(name)], documentation: ts.emptyArray, tags: ts.emptyArray, codeActions: undefined, }; } JsDoc.getJSDocParameterNameCompletionDetails = getJSDocParameterNameCompletionDetails; /** * Checks if position points to a valid position to add JSDoc comments, and if so, * returns the appropriate template. Otherwise returns an empty string. * Invalid positions are * - within comments, strings (including template literals and regex), and JSXText * - within a token * * Hosts should ideally check that: * - The line is all whitespace up to 'position' before performing the insertion. * - If the keystroke sequence "/\*\*" induced the call, we also check that the next * non-whitespace character is '*', which (approximately) indicates whether we added * the second '*' to complete an existing (JSDoc) comment. * @param fileName The file in which to perform the check. * @param position The (character-indexed) position in the file where the check should * be performed. */ function getDocCommentTemplateAtPosition(newLine, sourceFile, position) { // Check if in a context where we don't want to perform any insertion if (ts.isInString(sourceFile, position) || ts.isInComment(sourceFile, position) || ts.hasDocComment(sourceFile, position)) { return undefined; } var tokenAtPos = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); var tokenStart = tokenAtPos.getStart(); if (!tokenAtPos || tokenStart < position) { return undefined; } var commentOwnerInfo = getCommentOwnerInfo(tokenAtPos); if (!commentOwnerInfo) { // if climbing the tree did not find a declaration with parameters, complete to a single line comment return singleLineTemplate; } var commentOwner = commentOwnerInfo.commentOwner, parameters = commentOwnerInfo.parameters; if (commentOwner.kind === 10 /* JsxText */) { return undefined; } if (commentOwner.getStart() < position || parameters.length === 0) { // if climbing the tree found a declaration with parameters but the request was made inside it // or if there are no parameters, complete to a single line comment return singleLineTemplate; } var posLineAndChar = sourceFile.getLineAndCharacterOfPosition(position); var lineStart = sourceFile.getLineStarts()[posLineAndChar.line]; // replace non-whitespace characters in prefix with spaces. var indentationStr = sourceFile.text.substr(lineStart, posLineAndChar.character).replace(/\S/i, function () { return " "; }); var isJavaScriptFile = ts.hasJavaScriptFileExtension(sourceFile.fileName); var docParams = parameters.map(function (_a, i) { var name = _a.name; var nameText = ts.isIdentifier(name) ? name.text : "param" + i; var type = isJavaScriptFile ? "{any} " : ""; return indentationStr + " * @param " + type + nameText + newLine; }).join(""); // A doc comment consists of the following // * The opening comment line // * the first line (without a param) for the object's untagged info (this is also where the caret ends up) // * the '@param'-tagged lines // * TODO: other tags. // * the closing comment line // * if the caret was directly in front of the object, then we add an extra line and indentation. var preamble = "/**" + newLine + indentationStr + " * "; var result = preamble + newLine + docParams + indentationStr + " */" + (tokenStart === position ? newLine + indentationStr : ""); return { newText: result, caretOffset: preamble.length }; } JsDoc.getDocCommentTemplateAtPosition = getDocCommentTemplateAtPosition; function getCommentOwnerInfo(tokenAtPos) { for (var commentOwner = tokenAtPos; commentOwner; commentOwner = commentOwner.parent) { switch (commentOwner.kind) { case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 153 /* Constructor */: case 151 /* MethodSignature */: var parameters = commentOwner.parameters; return { commentOwner: commentOwner, parameters: parameters }; case 209 /* VariableStatement */: { var varStatement = commentOwner; var varDeclarations = varStatement.declarationList.declarations; var parameters_1 = varDeclarations.length === 1 && varDeclarations[0].initializer ? getParametersFromRightHandSideOfAssignment(varDeclarations[0].initializer) : undefined; return parameters_1 ? { commentOwner: commentOwner, parameters: parameters_1 } : undefined; } case 269 /* SourceFile */: return undefined; case 195 /* BinaryExpression */: { var be = commentOwner; if (ts.getSpecialPropertyAssignmentKind(be) === 0 /* None */) { return undefined; } var parameters_2 = ts.isFunctionLike(be.right) ? be.right.parameters : ts.emptyArray; return { commentOwner: commentOwner, parameters: parameters_2 }; } case 10 /* JsxText */: { var parameters_3 = ts.emptyArray; return { commentOwner: commentOwner, parameters: parameters_3 }; } } } } /** * 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 === 186 /* ParenthesizedExpression */) { rightHandSide = rightHandSide.expression; } switch (rightHandSide.kind) { case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: return rightHandSide.parameters; case 200 /* ClassExpression */: for (var _i = 0, _a = rightHandSide.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.kind === 153 /* Constructor */) { return member.parameters; } } break; } return ts.emptyArray; } })(JsDoc = ts.JsDoc || (ts.JsDoc = {})); })(ts || (ts = {})); // Copyright (c) Microsoft. All rights reserved. Licensed under the Apache License, Version 2.0. // See LICENSE.txt in the project root for complete license information. /// /// /// /* @internal */ var ts; (function (ts) { var JsTyping; (function (JsTyping) { /* @internal */ JsTyping.nodeCoreModuleList = [ "buffer", "querystring", "events", "http", "cluster", "zlib", "os", "https", "punycode", "repl", "readline", "vm", "child_process", "url", "dns", "net", "dgram", "fs", "path", "string_decoder", "tls", "crypto", "stream", "util", "assert", "tty", "domain", "constants", "process", "v8", "timers", "console" ]; var nodeCoreModules = ts.arrayToSet(JsTyping.nodeCoreModuleList); function loadSafeList(host, safeListPath) { var result = ts.readConfigFile(safeListPath, function (path) { return host.readFile(path); }); return ts.createMapFromTemplate(result.config); } JsTyping.loadSafeList = loadSafeList; function loadTypesMap(host, typesMapPath) { var result = ts.readConfigFile(typesMapPath, function (path) { return host.readFile(path); }); if (result.config) { return ts.createMapFromTemplate(result.config.simpleMap); } return undefined; } JsTyping.loadTypesMap = loadTypesMap; /** * @param host is the object providing I/O related operations. * @param fileNames are the file names that belong to the same project * @param projectRootPath is the path to the project root directory * @param safeListPath is the path used to retrieve the safe list * @param packageNameToTypingLocation is the map of package names to their cached typing locations * @param typeAcquisition is used to customize the typing acquisition process * @param compilerOptions are used as a source for typing inference */ function discoverTypings(host, log, fileNames, projectRootPath, safeList, packageNameToTypingLocation, typeAcquisition, unresolvedImports) { if (!typeAcquisition || !typeAcquisition.enable) { return { cachedTypingPaths: [], newTypingNames: [], filesToWatch: [] }; } // A typing name to typing file path mapping var inferredTypings = ts.createMap(); // Only infer typings for .js and .jsx files fileNames = ts.mapDefined(fileNames, function (fileName) { var path = ts.normalizePath(fileName); if (ts.hasJavaScriptFileExtension(path)) { return path; } }); var filesToWatch = []; if (typeAcquisition.include) addInferredTypings(typeAcquisition.include, "Explicitly included types"); var exclude = typeAcquisition.exclude || []; // Directories to search for package.json, bower.json and other typing information var possibleSearchDirs = ts.arrayToSet(fileNames, ts.getDirectoryPath); possibleSearchDirs.set(projectRootPath, true); possibleSearchDirs.forEach(function (_true, searchDir) { var packageJsonPath = ts.combinePaths(searchDir, "package.json"); getTypingNamesFromJson(packageJsonPath, filesToWatch); var bowerJsonPath = ts.combinePaths(searchDir, "bower.json"); getTypingNamesFromJson(bowerJsonPath, filesToWatch); var bowerComponentsPath = ts.combinePaths(searchDir, "bower_components"); getTypingNamesFromPackagesFolder(bowerComponentsPath, filesToWatch); var nodeModulesPath = ts.combinePaths(searchDir, "node_modules"); getTypingNamesFromPackagesFolder(nodeModulesPath, filesToWatch); }); getTypingNamesFromSourceFileNames(fileNames); // add typings for unresolved imports if (unresolvedImports) { var module = ts.deduplicate(unresolvedImports.map(function (moduleId) { return nodeCoreModules.has(moduleId) ? "node" : moduleId; }), ts.equateStringsCaseSensitive, ts.compareStringsCaseSensitive); addInferredTypings(module, "Inferred typings from unresolved imports"); } // Add the cached typing locations for inferred typings that are already installed packageNameToTypingLocation.forEach(function (typingLocation, name) { if (inferredTypings.has(name) && inferredTypings.get(name) === undefined) { inferredTypings.set(name, typingLocation); } }); // Remove typings that the user has added to the exclude list for (var _i = 0, exclude_1 = exclude; _i < exclude_1.length; _i++) { var excludeTypingName = exclude_1[_i]; var didDelete = inferredTypings.delete(excludeTypingName); if (didDelete && log) log("Typing for " + excludeTypingName + " is in exclude list, will be ignored."); } var newTypingNames = []; var cachedTypingPaths = []; inferredTypings.forEach(function (inferred, typing) { if (inferred !== undefined) { cachedTypingPaths.push(inferred); } else { newTypingNames.push(typing); } }); var result = { cachedTypingPaths: cachedTypingPaths, newTypingNames: newTypingNames, filesToWatch: filesToWatch }; if (log) log("Result: " + JSON.stringify(result)); return result; function addInferredTyping(typingName) { if (!inferredTypings.has(typingName)) { inferredTypings.set(typingName, undefined); } } function addInferredTypings(typingNames, message) { if (log) log(message + ": " + JSON.stringify(typingNames)); ts.forEach(typingNames, addInferredTyping); } /** * Get the typing info from common package manager json files like package.json or bower.json */ function getTypingNamesFromJson(jsonPath, filesToWatch) { if (!host.fileExists(jsonPath)) { return; } filesToWatch.push(jsonPath); var jsonConfig = ts.readConfigFile(jsonPath, function (path) { return host.readFile(path); }).config; var jsonTypingNames = ts.flatMap([jsonConfig.dependencies, jsonConfig.devDependencies, jsonConfig.optionalDependencies, jsonConfig.peerDependencies], ts.getOwnKeys); addInferredTypings(jsonTypingNames, "Typing names in '" + jsonPath + "' dependencies"); } /** * Infer typing names from given file names. For example, the file name "jquery-min.2.3.4.js" * should be inferred to the 'jquery' typing name; and "angular-route.1.2.3.js" should be inferred * to the 'angular-route' typing name. * @param fileNames are the names for source files in the project */ function getTypingNamesFromSourceFileNames(fileNames) { var fromFileNames = ts.mapDefined(fileNames, function (j) { if (!ts.hasJavaScriptFileExtension(j)) return undefined; var inferredTypingName = ts.removeFileExtension(ts.getBaseFileName(j.toLowerCase())); var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName); return safeList.get(cleanedTypingName); }); if (fromFileNames.length) { addInferredTypings(fromFileNames, "Inferred typings from file names"); } var hasJsxFile = ts.some(fileNames, function (f) { return ts.fileExtensionIs(f, ".jsx" /* Jsx */); }); if (hasJsxFile) { if (log) log("Inferred 'react' typings due to presence of '.jsx' extension"); addInferredTyping("react"); } } /** * Infer typing names from packages folder (ex: node_module, bower_components) * @param packagesFolderPath is the path to the packages folder */ function getTypingNamesFromPackagesFolder(packagesFolderPath, filesToWatch) { filesToWatch.push(packagesFolderPath); // Todo: add support for ModuleResolutionHost too if (!host.directoryExists(packagesFolderPath)) { return; } // depth of 2, so we access `node_modules/foo` but not `node_modules/foo/bar` var fileNames = host.readDirectory(packagesFolderPath, [".json" /* Json */], /*excludes*/ undefined, /*includes*/ undefined, /*depth*/ 2); if (log) log("Searching for typing names in " + packagesFolderPath + "; all files: " + JSON.stringify(fileNames)); var packageNames = []; for (var _i = 0, fileNames_1 = fileNames; _i < fileNames_1.length; _i++) { var fileName = fileNames_1[_i]; var normalizedFileName = ts.normalizePath(fileName); var baseFileName = ts.getBaseFileName(normalizedFileName); if (baseFileName !== "package.json" && baseFileName !== "bower.json") { continue; } var result_7 = ts.readConfigFile(normalizedFileName, function (path) { return host.readFile(path); }); var packageJson = result_7.config; // npm 3's package.json contains a "_requiredBy" field // we should include all the top level module names for npm 2, and only module names whose // "_requiredBy" field starts with "#" or equals "/" for npm 3. if (baseFileName === "package.json" && packageJson._requiredBy && ts.filter(packageJson._requiredBy, function (r) { return r[0] === "#" || r === "/"; }).length === 0) { continue; } // If the package has its own d.ts typings, those will take precedence. Otherwise the package name will be used // to download d.ts files from DefinitelyTyped if (!packageJson.name) { continue; } var ownTypes = packageJson.types || packageJson.typings; if (ownTypes) { var absolutePath = ts.getNormalizedAbsolutePath(ownTypes, ts.getDirectoryPath(normalizedFileName)); if (log) log(" Package '" + packageJson.name + "' provides its own types."); inferredTypings.set(packageJson.name, absolutePath); } else { packageNames.push(packageJson.name); } } addInferredTypings(packageNames, " Found package names"); } } JsTyping.discoverTypings = discoverTypings; var PackageNameValidationResult; (function (PackageNameValidationResult) { PackageNameValidationResult[PackageNameValidationResult["Ok"] = 0] = "Ok"; PackageNameValidationResult[PackageNameValidationResult["ScopedPackagesNotSupported"] = 1] = "ScopedPackagesNotSupported"; PackageNameValidationResult[PackageNameValidationResult["EmptyName"] = 2] = "EmptyName"; PackageNameValidationResult[PackageNameValidationResult["NameTooLong"] = 3] = "NameTooLong"; PackageNameValidationResult[PackageNameValidationResult["NameStartsWithDot"] = 4] = "NameStartsWithDot"; PackageNameValidationResult[PackageNameValidationResult["NameStartsWithUnderscore"] = 5] = "NameStartsWithUnderscore"; PackageNameValidationResult[PackageNameValidationResult["NameContainsNonURISafeCharacters"] = 6] = "NameContainsNonURISafeCharacters"; })(PackageNameValidationResult = JsTyping.PackageNameValidationResult || (JsTyping.PackageNameValidationResult = {})); var maxPackageNameLength = 214; /** * Validates package name using rules defined at https://docs.npmjs.com/files/package.json */ function validatePackageName(packageName) { if (!packageName) { return 2 /* EmptyName */; } if (packageName.length > maxPackageNameLength) { return 3 /* NameTooLong */; } if (packageName.charCodeAt(0) === 46 /* dot */) { return 4 /* NameStartsWithDot */; } if (packageName.charCodeAt(0) === 95 /* _ */) { return 5 /* NameStartsWithUnderscore */; } // check if name is scope package like: starts with @ and has one '/' in the middle // scoped packages are not currently supported // TODO: when support will be added we'll need to split and check both scope and package name if (/^@[^/]+\/[^/]+$/.test(packageName)) { return 1 /* ScopedPackagesNotSupported */; } if (encodeURIComponent(packageName) !== packageName) { return 6 /* NameContainsNonURISafeCharacters */; } return 0 /* Ok */; } JsTyping.validatePackageName = validatePackageName; function renderPackageNameValidationFailure(result, typing) { switch (result) { case 2 /* EmptyName */: return "Package name '" + typing + "' cannot be empty"; case 3 /* NameTooLong */: return "Package name '" + typing + "' should be less than " + maxPackageNameLength + " characters"; case 4 /* NameStartsWithDot */: return "Package name '" + typing + "' cannot start with '.'"; case 5 /* NameStartsWithUnderscore */: return "Package name '" + typing + "' cannot start with '_'"; case 1 /* ScopedPackagesNotSupported */: return "Package '" + typing + "' is scoped and currently is not supported"; case 6 /* NameContainsNonURISafeCharacters */: return "Package name '" + typing + "' contains non URI safe characters"; case 0 /* Ok */: throw ts.Debug.fail(); // Shouldn't have called this. default: ts.Debug.assertNever(result); } } JsTyping.renderPackageNameValidationFailure = renderPackageNameValidationFailure; })(JsTyping = ts.JsTyping || (ts.JsTyping = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var NavigateTo; (function (NavigateTo) { function getNavigateToItems(sourceFiles, checker, cancellationToken, searchValue, maxResultCount, excludeDtsFiles) { var patternMatcher = ts.createPatternMatcher(searchValue); var rawItems = []; var _loop_8 = function (sourceFile) { cancellationToken.throwIfCancellationRequested(); if (excludeDtsFiles && ts.fileExtensionIs(sourceFile.fileName, ".d.ts" /* Dts */)) { return "continue"; } ts.forEachEntry(sourceFile.getNamedDeclarations(), function (declarations, name) { getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, sourceFile.fileName, rawItems); }); }; // Search the declarations in all files and output matched NavigateToItem into array of NavigateToItem[] for (var _i = 0, sourceFiles_8 = sourceFiles; _i < sourceFiles_8.length; _i++) { var sourceFile = sourceFiles_8[_i]; _loop_8(sourceFile); } rawItems.sort(compareNavigateToItems); if (maxResultCount !== undefined) { rawItems = rawItems.slice(0, maxResultCount); } return rawItems.map(createNavigateToItem); } NavigateTo.getNavigateToItems = getNavigateToItems; function getItemsFromNamedDeclaration(patternMatcher, name, declarations, checker, fileName, rawItems) { // First do a quick check to see if the name of the declaration matches the // last portion of the (possibly) dotted name they're searching for. var matches = patternMatcher.getMatchesForLastSegmentOfPattern(name); if (!matches) { return; // continue to next named declarations } for (var _i = 0, declarations_11 = declarations; _i < declarations_11.length; _i++) { var declaration = declarations_11[_i]; if (!shouldKeepItem(declaration, checker)) { continue; } // It was a match! If the pattern has dots in it, then also see if the // declaration container matches as well. var containerMatches = matches; if (patternMatcher.patternContainsDots) { containerMatches = patternMatcher.getMatches(getContainers(declaration), name); if (!containerMatches) { continue; } } var matchKind = bestMatchKind(containerMatches); var isCaseSensitive = allMatchesAreCaseSensitive(containerMatches); rawItems.push({ name: name, fileName: fileName, matchKind: matchKind, isCaseSensitive: isCaseSensitive, declaration: declaration }); } } function shouldKeepItem(declaration, checker) { switch (declaration.kind) { case 240 /* ImportClause */: case 243 /* ImportSpecifier */: case 238 /* ImportEqualsDeclaration */: var importer = checker.getSymbolAtLocation(declaration.name); var imported = checker.getAliasedSymbol(importer); return importer.escapedName !== imported.escapedName; default: return true; } } function allMatchesAreCaseSensitive(matches) { ts.Debug.assert(matches.length > 0); // This is a case sensitive match, only if all the submatches were case sensitive. for (var _i = 0, matches_2 = matches; _i < matches_2.length; _i++) { var match = matches_2[_i]; if (!match.isCaseSensitive) { return false; } } return true; } function tryAddSingleDeclarationName(declaration, containers) { if (declaration) { var name = ts.getNameOfDeclaration(declaration); if (name) { var text = ts.getTextOfIdentifierOrLiteral(name); if (text !== undefined) { containers.unshift(text); } else if (name.kind === 145 /* ComputedPropertyName */) { return tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ true); } else { // Don't know how to add this. return false; } } } return true; } // Only added the names of computed properties if they're simple dotted expressions, like: // // [X.Y.Z]() { } function tryAddComputedPropertyName(expression, containers, includeLastPortion) { var text = ts.getTextOfIdentifierOrLiteral(expression); if (text !== undefined) { if (includeLastPortion) { containers.unshift(text); } return true; } if (expression.kind === 180 /* PropertyAccessExpression */) { var propertyAccess = expression; if (includeLastPortion) { containers.unshift(propertyAccess.name.text); } return tryAddComputedPropertyName(propertyAccess.expression, containers, /*includeLastPortion*/ true); } return false; } function getContainers(declaration) { var containers = []; // First, if we started with a computed property name, then add all but the last // portion into the container array. var name = ts.getNameOfDeclaration(declaration); if (name.kind === 145 /* ComputedPropertyName */) { if (!tryAddComputedPropertyName(name.expression, containers, /*includeLastPortion*/ false)) { return undefined; } } // Now, walk up our containers, adding all their names to the container array. declaration = ts.getContainerNode(declaration); while (declaration) { if (!tryAddSingleDeclarationName(declaration, containers)) { return undefined; } declaration = ts.getContainerNode(declaration); } return containers; } function bestMatchKind(matches) { ts.Debug.assert(matches.length > 0); var bestMatchKind = ts.PatternMatchKind.camelCase; for (var _i = 0, matches_3 = matches; _i < matches_3.length; _i++) { var match = matches_3[_i]; var kind = match.kind; if (kind < bestMatchKind) { bestMatchKind = kind; } } return bestMatchKind; } function compareNavigateToItems(i1, i2) { // TODO(cyrusn): get the gamut of comparisons that VS already uses here. return ts.compareValues(i1.matchKind, i2.matchKind) || ts.compareStringsCaseSensitiveUI(i1.name, i2.name); } function createNavigateToItem(rawItem) { var declaration = rawItem.declaration; var container = ts.getContainerNode(declaration); var containerName = container && ts.getNameOfDeclaration(container); return { name: rawItem.name, kind: ts.getNodeKind(declaration), kindModifiers: ts.getNodeModifiers(declaration), matchKind: ts.PatternMatchKind[rawItem.matchKind], isCaseSensitive: rawItem.isCaseSensitive, fileName: rawItem.fileName, textSpan: ts.createTextSpanFromNode(declaration), // TODO(jfreeman): What should be the containerName when the container has a computed name? containerName: containerName ? containerName.text : "", containerKind: containerName ? ts.getNodeKind(container) : "" /* unknown */ }; } })(NavigateTo = ts.NavigateTo || (ts.NavigateTo = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { var NavigationBar; (function (NavigationBar) { /** * Matches all whitespace characters in a string. Eg: * * "app. * * onactivated" * * matches because of the newline, whereas * * "app.onactivated" * * does not match. */ var whiteSpaceRegex = /\s+/g; // Keep sourceFile handy so we don't have to search for it every time we need to call `getText`. var curCancellationToken; var curSourceFile; /** * For performance, we keep navigation bar parents on a stack rather than passing them through each recursion. * `parent` is the current parent and is *not* stored in parentsStack. * `startNode` sets a new parent and `endNode` returns to the previous parent. */ var parentsStack = []; var parent; // NavigationBarItem requires an array, but will not mutate it, so just give it this for performance. var emptyChildItemArray = []; function getNavigationBarItems(sourceFile, cancellationToken) { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { return ts.map(topLevelItems(rootNavigationBarNode(sourceFile)), convertToTopLevelItem); } finally { reset(); } } NavigationBar.getNavigationBarItems = getNavigationBarItems; function getNavigationTree(sourceFile, cancellationToken) { curCancellationToken = cancellationToken; curSourceFile = sourceFile; try { return convertToTree(rootNavigationBarNode(sourceFile)); } finally { reset(); } } NavigationBar.getNavigationTree = getNavigationTree; function reset() { curSourceFile = undefined; curCancellationToken = undefined; parentsStack = []; parent = undefined; emptyChildItemArray = []; } function nodeText(node) { return node.getText(curSourceFile); } function navigationBarNodeKind(n) { return n.node.kind; } function pushChild(parent, child) { if (parent.children) { parent.children.push(child); } else { parent.children = [child]; } } function rootNavigationBarNode(sourceFile) { ts.Debug.assert(!parentsStack.length); var root = { node: sourceFile, additionalNodes: undefined, parent: undefined, children: undefined, indent: 0 }; parent = root; for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) { var statement = _a[_i]; addChildrenRecursively(statement); } endNode(); ts.Debug.assert(!parent && !parentsStack.length); return root; } function addLeafNode(node) { pushChild(parent, emptyNavigationBarNode(node)); } function emptyNavigationBarNode(node) { return { node: node, additionalNodes: undefined, parent: parent, children: undefined, indent: parent.indent + 1 }; } /** * Add a new level of NavigationBarNodes. * This pushes to the stack, so you must call `endNode` when you are done adding to this node. */ function startNode(node) { var navNode = emptyNavigationBarNode(node); pushChild(parent, navNode); // Save the old parent parentsStack.push(parent); parent = navNode; } /** Call after calling `startNode` and adding children to it. */ function endNode() { if (parent.children) { mergeChildren(parent.children); sortChildren(parent.children); } parent = parentsStack.pop(); } function addNodeWithRecursiveChild(node, child) { startNode(node); addChildrenRecursively(child); endNode(); } /** Look for navigation bar items in node's subtree, adding them to the current `parent`. */ function addChildrenRecursively(node) { curCancellationToken.throwIfCancellationRequested(); if (!node || ts.isToken(node)) { return; } switch (node.kind) { case 153 /* 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 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 151 /* MethodSignature */: if (!ts.hasDynamicName(node)) { addNodeWithRecursiveChild(node, node.body); } break; case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: if (!ts.hasDynamicName(node)) { addLeafNode(node); } break; case 240 /* 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 === 241 /* NamespaceImport */) { addLeafNode(namedBindings); } else { for (var _b = 0, _c = namedBindings.elements; _b < _c.length; _b++) { var element = _c[_b]; addLeafNode(element); } } } break; case 177 /* BindingElement */: case 227 /* VariableDeclaration */: var _d = node, name = _d.name, initializer = _d.initializer; if (ts.isBindingPattern(name)) { addChildrenRecursively(name); } else if (initializer && isFunctionOrClassExpression(initializer)) { if (initializer.name) { // Don't add a node for the VariableDeclaration, just for the initializer. addChildrenRecursively(initializer); } else { // Add a node for the VariableDeclaration, but not for the initializer. startNode(node); ts.forEachChild(initializer, addChildrenRecursively); endNode(); } } else { addNodeWithRecursiveChild(node, initializer); } break; case 188 /* ArrowFunction */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: addNodeWithRecursiveChild(node, node.body); break; case 233 /* EnumDeclaration */: startNode(node); for (var _e = 0, _f = node.members; _e < _f.length; _e++) { var member = _f[_e]; if (!isComputedProperty(member)) { addLeafNode(member); } } endNode(); break; case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: startNode(node); for (var _g = 0, _h = node.members; _g < _h.length; _g++) { var member = _h[_g]; addChildrenRecursively(member); } endNode(); break; case 234 /* ModuleDeclaration */: addNodeWithRecursiveChild(node, getInteriorModule(node).body); break; case 247 /* ExportSpecifier */: case 238 /* ImportEqualsDeclaration */: case 158 /* IndexSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 232 /* TypeAliasDeclaration */: addLeafNode(node); break; case 195 /* BinaryExpression */: { var special = ts.getSpecialPropertyAssignmentKind(node); switch (special) { case 1 /* ExportsProperty */: case 2 /* ModuleExports */: case 3 /* PrototypeProperty */: addNodeWithRecursiveChild(node, node.right); break; case 4 /* ThisProperty */: case 5 /* Property */: case 0 /* None */: break; default: ts.Debug.assertNever(special); } } // falls through default: if (ts.hasJSDocNodes(node)) { ts.forEach(node.jsDoc, function (jsDoc) { ts.forEach(jsDoc.tags, function (tag) { if (tag.kind === 288 /* JSDocTypedefTag */) { addLeafNode(tag); } }); }); } ts.forEachChild(node, addChildrenRecursively); } } /** Merge declarations of the same kind. */ function mergeChildren(children) { var nameToItems = ts.createMap(); ts.filterMutate(children, function (child) { var declName = ts.getNameOfDeclaration(child.node); var name = declName && nodeText(declName); if (!name) { // Anonymous items are never merged. return true; } var itemsWithSameName = nameToItems.get(name); if (!itemsWithSameName) { nameToItems.set(name, child); return true; } if (itemsWithSameName instanceof Array) { for (var _i = 0, itemsWithSameName_1 = itemsWithSameName; _i < itemsWithSameName_1.length; _i++) { var itemWithSameName = itemsWithSameName_1[_i]; if (tryMerge(itemWithSameName, child)) { return false; } } itemsWithSameName.push(child); return true; } else { var itemWithSameName = itemsWithSameName; if (tryMerge(itemWithSameName, child)) { return false; } nameToItems.set(name, [itemWithSameName, child]); return true; } }); } function tryMerge(a, b) { if (shouldReallyMerge(a.node, b.node)) { merge(a, b); return true; } return false; } /** a and b have the same name, but they may not be mergeable. */ function shouldReallyMerge(a, b) { if (a.kind !== b.kind) { return false; } switch (a.kind) { case 150 /* PropertyDeclaration */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return ts.hasModifier(a, 32 /* Static */) === ts.hasModifier(b, 32 /* Static */); case 234 /* ModuleDeclaration */: return areSameModule(a, b); default: return true; } } // 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) { return a.body.kind === b.body.kind && (a.body.kind !== 234 /* ModuleDeclaration */ || 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) { return ts.compareStringsCaseSensitiveUI(tryGetName(child1.node), tryGetName(child2.node)) || ts.compareValues(navigationBarNodeKind(child1), navigationBarNodeKind(child2)); } /** * This differs from getItemName because this is just used for sorting. * We only sort nodes by name that have a more-or-less "direct" name, as opposed to `new()` and the like. * So `new()` can still come before an `aardvark` method. */ function tryGetName(node) { if (node.kind === 234 /* ModuleDeclaration */) { return getModuleName(node); } var declName = ts.getNameOfDeclaration(node); if (declName) { return ts.unescapeLeadingUnderscores(ts.getPropertyNameForPropertyNameNode(declName)); } switch (node.kind) { case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 200 /* ClassExpression */: return getFunctionOrClassName(node); case 288 /* JSDocTypedefTag */: return getJSDocTypedefTagName(node); default: return undefined; } } function getItemName(node) { if (node.kind === 234 /* ModuleDeclaration */) { return getModuleName(node); } var name = ts.getNameOfDeclaration(node); if (name) { var text = nodeText(name); if (text.length > 0) { return text; } } switch (node.kind) { case 269 /* SourceFile */: var sourceFile = node; return ts.isExternalModule(sourceFile) ? "\"" + ts.escapeString(ts.getBaseFileName(ts.removeFileExtension(ts.normalizePath(sourceFile.fileName)))) + "\"" : ""; case 188 /* ArrowFunction */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: if (ts.getModifierFlags(node) & 512 /* Default */) { return "default"; } // We may get a string with newlines or other whitespace in the case of an object dereference // (eg: "app\n.onactivated"), so we should remove the whitespace for readabiltiy in the // navigation bar. return getFunctionOrClassName(node); case 153 /* Constructor */: return "constructor"; case 157 /* ConstructSignature */: return "new()"; case 156 /* CallSignature */: return "()"; case 158 /* IndexSignature */: return "[]"; case 288 /* JSDocTypedefTag */: return getJSDocTypedefTagName(node); default: return ""; } } function getJSDocTypedefTagName(node) { if (node.name) { return node.name.text; } else { var parentNode = node.parent && node.parent.parent; if (parentNode && parentNode.kind === 209 /* VariableStatement */) { if (parentNode.declarationList.declarations.length > 0) { var nameIdentifier = parentNode.declarationList.declarations[0].name; if (nameIdentifier.kind === 71 /* Identifier */) { return nameIdentifier.text; } } } return ""; } } /** 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 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 233 /* EnumDeclaration */: case 231 /* InterfaceDeclaration */: case 234 /* ModuleDeclaration */: case 269 /* SourceFile */: case 232 /* TypeAliasDeclaration */: case 288 /* JSDocTypedefTag */: return true; case 153 /* Constructor */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 227 /* VariableDeclaration */: return hasSomeImportantChild(item); case 188 /* ArrowFunction */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: return isTopLevelFunctionDeclaration(item); default: return false; } function isTopLevelFunctionDeclaration(item) { if (!item.node.body) { return false; } switch (navigationBarNodeKind(item.parent)) { case 235 /* ModuleBlock */: case 269 /* SourceFile */: case 152 /* MethodDeclaration */: case 153 /* Constructor */: return true; default: return hasSomeImportantChild(item); } } function hasSomeImportantChild(item) { return ts.forEach(item.children, function (child) { var childKind = navigationBarNodeKind(child); return childKind !== 227 /* VariableDeclaration */ && childKind !== 177 /* BindingElement */; }); } } } function convertToTree(n) { return { text: getItemName(n.node), kind: ts.getNodeKind(n.node), kindModifiers: getModifiers(n.node), spans: getSpans(n), childItems: ts.map(n.children, convertToTree) }; } function convertToTopLevelItem(n) { return { text: getItemName(n.node), kind: ts.getNodeKind(n.node), kindModifiers: getModifiers(n.node), spans: getSpans(n), childItems: ts.map(n.children, convertToChildItem) || emptyChildItemArray, indent: n.indent, bolded: false, grayed: false }; function convertToChildItem(n) { return { text: getItemName(n.node), kind: ts.getNodeKind(n.node), kindModifiers: ts.getNodeModifiers(n.node), spans: getSpans(n), childItems: emptyChildItemArray, indent: 0, bolded: false, grayed: false }; } } function getSpans(n) { var spans = [getNodeSpan(n.node)]; if (n.additionalNodes) { for (var _i = 0, _a = n.additionalNodes; _i < _a.length; _i++) { var node = _a[_i]; spans.push(getNodeSpan(node)); } } return spans; } function getModuleName(moduleDeclaration) { // We want to maintain quotation marks. if (ts.isAmbientModule(moduleDeclaration)) { return ts.getTextOfNode(moduleDeclaration.name); } // Otherwise, we need to aggregate each identifier to build up the qualified name. var result = []; result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name)); while (moduleDeclaration.body && moduleDeclaration.body.kind === 234 /* ModuleDeclaration */) { moduleDeclaration = moduleDeclaration.body; result.push(ts.getTextOfIdentifierOrLiteral(moduleDeclaration.name)); } return result.join("."); } /** * For 'module A.B.C', we want to get the node for 'C'. * We store 'A' as associated with a NavNode, and use getModuleName to traverse down again. */ function getInteriorModule(decl) { return decl.body.kind === 234 /* ModuleDeclaration */ ? getInteriorModule(decl.body) : decl; } function isComputedProperty(member) { return !member.name || member.name.kind === 145 /* ComputedPropertyName */; } function getNodeSpan(node) { return node.kind === 269 /* SourceFile */ ? ts.createTextSpanFromBounds(node.getFullStart(), node.getEnd()) : ts.createTextSpanFromNode(node, curSourceFile); } function getModifiers(node) { if (node.parent && node.parent.kind === 227 /* VariableDeclaration */) { node = node.parent; } return ts.getNodeModifiers(node); } function getFunctionOrClassName(node) { if (node.name && ts.getFullWidth(node.name) > 0) { return ts.declarationNameToString(node.name); } else if (node.parent.kind === 227 /* VariableDeclaration */) { return ts.declarationNameToString(node.parent.name); } else if (node.parent.kind === 195 /* BinaryExpression */ && node.parent.operatorToken.kind === 58 /* EqualsToken */) { return nodeText(node.parent.left).replace(whiteSpaceRegex, ""); } else if (node.parent.kind === 265 /* PropertyAssignment */ && node.parent.name) { return nodeText(node.parent.name); } else if (ts.getModifierFlags(node) & 512 /* Default */) { return "default"; } else { return ts.isClassLike(node) ? "" : ""; } } function isFunctionOrClassExpression(node) { switch (node.kind) { case 188 /* ArrowFunction */: case 187 /* FunctionExpression */: case 200 /* ClassExpression */: return true; default: return false; } } })(NavigationBar = ts.NavigationBar || (ts.NavigationBar = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var OutliningElementsCollector; (function (OutliningElementsCollector) { function collectElements(sourceFile, cancellationToken) { var res = []; addNodeOutliningSpans(sourceFile, cancellationToken, res); addRegionOutliningSpans(sourceFile, res); return res.sort(function (span1, span2) { return span1.textSpan.start - span2.textSpan.start; }); } OutliningElementsCollector.collectElements = collectElements; function addNodeOutliningSpans(sourceFile, cancellationToken, out) { var depthRemaining = 40; sourceFile.forEachChild(function walk(n) { if (depthRemaining === 0) return; cancellationToken.throwIfCancellationRequested(); if (ts.isDeclaration(n)) { addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out); } var span = getOutliningSpanForNode(n, sourceFile); if (span) out.push(span); depthRemaining--; n.forEachChild(walk); depthRemaining++; }); } function addRegionOutliningSpans(sourceFile, out) { var regions = []; var lineStarts = sourceFile.getLineStarts(); for (var i = 0; i < lineStarts.length; i++) { var currentLineStart = lineStarts[i]; var lineEnd = i + 1 === lineStarts.length ? sourceFile.getEnd() : lineStarts[i + 1] - 1; var lineText = sourceFile.text.substring(currentLineStart, lineEnd); var result = lineText.match(/^\s*\/\/\s*#(end)?region(?:\s+(.*))?$/); if (!result || ts.isInComment(sourceFile, currentLineStart)) { continue; } if (!result[1]) { var span_13 = ts.createTextSpanFromBounds(sourceFile.text.indexOf("//", currentLineStart), lineEnd); regions.push(createOutliningSpan(span_13, span_13, /*autoCollapse*/ false, result[2] || "#region")); } else { var region = regions.pop(); if (region) { region.textSpan.length = lineEnd - region.textSpan.start; region.hintSpan.length = lineEnd - region.textSpan.start; out.push(region); } } } } function addOutliningForLeadingCommentsForNode(n, sourceFile, cancellationToken, out) { var comments = ts.getLeadingCommentRangesOfNode(n, sourceFile); if (!comments) return; var firstSingleLineCommentStart = -1; var lastSingleLineCommentEnd = -1; var singleLineCommentCount = 0; for (var _i = 0, comments_3 = comments; _i < comments_3.length; _i++) { var _a = comments_3[_i], kind = _a.kind, pos = _a.pos, end = _a.end; cancellationToken.throwIfCancellationRequested(); switch (kind) { case 2 /* SingleLineCommentTrivia */: // 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 (singleLineCommentCount === 0) { firstSingleLineCommentStart = pos; } lastSingleLineCommentEnd = end; singleLineCommentCount++; break; case 3 /* MultiLineCommentTrivia */: combineAndAddMultipleSingleLineComments(); out.push(createOutliningSpanFromBounds(pos, end)); singleLineCommentCount = 0; break; default: ts.Debug.assertNever(kind); } } combineAndAddMultipleSingleLineComments(); function combineAndAddMultipleSingleLineComments() { // Only outline spans of two or more consecutive single line comments if (singleLineCommentCount > 1) { out.push(createOutliningSpanFromBounds(firstSingleLineCommentStart, lastSingleLineCommentEnd)); } } } function createOutliningSpanFromBounds(pos, end) { return createOutliningSpan(ts.createTextSpanFromBounds(pos, end)); } function getOutliningSpanForNode(n, sourceFile) { switch (n.kind) { case 208 /* Block */: if (ts.isFunctionBlock(n)) { return spanForNode(n.parent, /*autoCollapse*/ n.parent.kind !== 188 /* ArrowFunction */); } // 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. switch (n.parent.kind) { case 213 /* DoStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 215 /* ForStatement */: case 212 /* IfStatement */: case 214 /* WhileStatement */: case 221 /* WithStatement */: case 264 /* CatchClause */: return spanForNode(n.parent); case 225 /* TryStatement */: // Could be the try-block, or the finally-block. var tryStatement = n.parent; if (tryStatement.tryBlock === n) { return spanForNode(n.parent); } else if (tryStatement.finallyBlock === n) { return spanForNode(ts.findChildOfKind(tryStatement, 87 /* FinallyKeyword */, sourceFile)); } // falls through default: // Block was a standalone block. In this case we want to only collapse // the span of the block, independent of any parent span. return createOutliningSpan(ts.createTextSpanFromNode(n, sourceFile)); } case 235 /* ModuleBlock */: return spanForNode(n.parent); case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 236 /* CaseBlock */: return spanForNode(n); case 179 /* ObjectLiteralExpression */: return spanForObjectOrArrayLiteral(n); case 178 /* ArrayLiteralExpression */: return spanForObjectOrArrayLiteral(n, 21 /* OpenBracketToken */); } function spanForObjectOrArrayLiteral(node, open) { if (open === void 0) { open = 17 /* OpenBraceToken */; } // If the block has no leading keywords and is inside an array literal, // we only want to collapse the span of the block. // Otherwise, the collapsed section will include the end of the previous line. return spanForNode(node, /*autoCollapse*/ false, /*useFullStart*/ !ts.isArrayLiteralExpression(node.parent), open); } function spanForNode(hintSpanNode, autoCollapse, useFullStart, open) { if (autoCollapse === void 0) { autoCollapse = false; } if (useFullStart === void 0) { useFullStart = true; } if (open === void 0) { open = 17 /* OpenBraceToken */; } var openToken = ts.findChildOfKind(n, open, sourceFile); var close = open === 17 /* OpenBraceToken */ ? 18 /* CloseBraceToken */ : 22 /* CloseBracketToken */; var closeToken = ts.findChildOfKind(n, close, sourceFile); if (!openToken || !closeToken) { return undefined; } var textSpan = ts.createTextSpanFromBounds(useFullStart ? openToken.getFullStart() : openToken.getStart(sourceFile), closeToken.getEnd()); return createOutliningSpan(textSpan, ts.createTextSpanFromNode(hintSpanNode, sourceFile), autoCollapse); } } function createOutliningSpan(textSpan, hintSpan, autoCollapse, bannerText) { if (hintSpan === void 0) { hintSpan = textSpan; } if (autoCollapse === void 0) { autoCollapse = false; } if (bannerText === void 0) { bannerText = "..."; } return { textSpan: textSpan, hintSpan: hintSpan, bannerText: bannerText, autoCollapse: autoCollapse }; } })(OutliningElementsCollector = ts.OutliningElementsCollector || (ts.OutliningElementsCollector = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { // Note(cyrusn): this enum is ordered from strongest match type to weakest match type. var PatternMatchKind; (function (PatternMatchKind) { PatternMatchKind[PatternMatchKind["exact"] = 0] = "exact"; PatternMatchKind[PatternMatchKind["prefix"] = 1] = "prefix"; PatternMatchKind[PatternMatchKind["substring"] = 2] = "substring"; PatternMatchKind[PatternMatchKind["camelCase"] = 3] = "camelCase"; })(PatternMatchKind = ts.PatternMatchKind || (ts.PatternMatchKind = {})); function createPatternMatch(kind, punctuationStripped, isCaseSensitive, camelCaseWeight) { return { kind: kind, punctuationStripped: punctuationStripped, isCaseSensitive: isCaseSensitive, camelCaseWeight: camelCaseWeight }; } function createPatternMatcher(pattern) { // We'll often see the same candidate string many times when searching (For example, when // we see the name of a module that is used everywhere, or the name of an overload). As // such, we cache the information we compute about the candidate for the life of this // pattern matcher so we don't have to compute it multiple times. var stringToWordSpans = ts.createMap(); pattern = pattern.trim(); var dotSeparatedSegments = pattern.split(".").map(function (p) { return createSegment(p.trim()); }); var invalidPattern = dotSeparatedSegments.length === 0 || ts.forEach(dotSeparatedSegments, segmentIsInvalid); return { getMatches: getMatches, getMatchesForLastSegmentOfPattern: getMatchesForLastSegmentOfPattern, patternContainsDots: dotSeparatedSegments.length > 1 }; // Quick checks so we can bail out when asked to match a candidate. function skipMatch(candidate) { return invalidPattern || !candidate; } function getMatchesForLastSegmentOfPattern(candidate) { if (skipMatch(candidate)) { return undefined; } return matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments)); } function getMatches(candidateContainers, candidate) { if (skipMatch(candidate)) { return undefined; } // First, check that the last part of the dot separated pattern matches the name of the // candidate. If not, then there's no point in proceeding and doing the more // expensive work. var candidateMatch = matchSegment(candidate, ts.lastOrUndefined(dotSeparatedSegments)); if (!candidateMatch) { return undefined; } candidateContainers = candidateContainers || []; // -1 because the last part was checked against the name, and only the rest // of the parts are checked against the container. if (dotSeparatedSegments.length - 1 > candidateContainers.length) { // There weren't enough container parts to match against the pattern parts. // So this definitely doesn't match. return undefined; } // So far so good. Now break up the container for the candidate and check if all // the dotted parts match up correctly. var totalMatch = candidateMatch; for (var i = dotSeparatedSegments.length - 2, j = candidateContainers.length - 1; i >= 0; i -= 1, j -= 1) { var segment = dotSeparatedSegments[i]; var containerName = candidateContainers[j]; var containerMatch = matchSegment(containerName, segment); if (!containerMatch) { // This container didn't match the pattern piece. So there's no match at all. return undefined; } ts.addRange(totalMatch, containerMatch); } // Success, this symbol's full name matched against the dotted name the user was asking // about. return totalMatch; } function getWordSpans(word) { var spans = stringToWordSpans.get(word); if (!spans) { stringToWordSpans.set(word, spans = breakIntoWordSpans(word)); } return spans; } function matchTextChunk(candidate, chunk, punctuationStripped) { var index = indexOfIgnoringCase(candidate, chunk.textLowerCase); if (index === 0) { if (chunk.text.length === candidate.length) { // a) Check if the part matches the candidate entirely, in an case insensitive or // sensitive manner. If it does, return that there was an exact match. return createPatternMatch(PatternMatchKind.exact, punctuationStripped, /*isCaseSensitive:*/ candidate === chunk.text); } else { // b) Check if the part is a prefix of the candidate, in a case insensitive or sensitive // manner. If it does, return that there was a prefix match. return createPatternMatch(PatternMatchKind.prefix, punctuationStripped, /*isCaseSensitive:*/ ts.startsWith(candidate, chunk.text)); } } var isLowercase = chunk.isLowerCase; if (isLowercase) { if (index > 0) { // c) If the part is entirely lowercase, then check if it is contained anywhere in the // candidate in a case insensitive manner. If so, return that there was a substring // match. // // Note: We only have a substring match if the lowercase part is prefix match of some // word part. That way we don't match something like 'Class' when the user types 'a'. // But we would match 'FooAttribute' (since 'Attribute' starts with 'a'). var wordSpans = getWordSpans(candidate); for (var _i = 0, wordSpans_1 = wordSpans; _i < wordSpans_1.length; _i++) { var span_14 = wordSpans_1[_i]; if (partStartsWith(candidate, span_14, chunk.text, /*ignoreCase:*/ true)) { return createPatternMatch(PatternMatchKind.substring, punctuationStripped, /*isCaseSensitive:*/ partStartsWith(candidate, span_14, 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, 6 /* 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, 6 /* Latest */)) { return false; } // TODO: find a way to determine this for any unicode characters in a // non-allocating manner. var str = String.fromCharCode(ch); return str === str.toLowerCase(); } // Assumes 'value' is already lowercase. function indexOfIgnoringCase(str, value) { var n = str.length - value.length; for (var i = 0; i <= n; i++) { if (startsWithIgnoringCase(str, value, i)) { return i; } } return -1; } // Assumes 'value' is already lowercase. function startsWithIgnoringCase(str, value, start) { for (var i = 0; i < value.length; i++) { var ch1 = toLowerCase(str.charCodeAt(i + start)); var ch2 = value.charCodeAt(i); if (ch1 !== ch2) { return false; } } return true; } function toLowerCase(ch) { // Fast convert for the ascii range. if (ch >= 65 /* A */ && ch <= 90 /* Z */) { return 97 /* a */ + (ch - 65 /* A */); } if (ch < 127 /* maxAsciiCharacter */) { return ch; } // TODO: find a way to compute this for any unicode characters in a // non-allocating manner. return String.fromCharCode(ch).toLowerCase().charCodeAt(0); } function isDigit(ch) { // TODO(cyrusn): Find a way to support this for unicode digits. return ch >= 48 /* _0 */ && ch <= 57 /* _9 */; } function isWordChar(ch) { return isUpperCaseLetter(ch) || isLowerCaseLetter(ch) || isDigit(ch) || ch === 95 /* _ */ || ch === 36 /* $ */; } function breakPatternIntoTextChunks(pattern) { var result = []; var wordStart = 0; var wordLength = 0; for (var i = 0; i < pattern.length; i++) { var ch = pattern.charCodeAt(i); if (isWordChar(ch)) { if (wordLength === 0) { wordStart = i; } wordLength++; } else { if (wordLength > 0) { result.push(createTextChunk(pattern.substr(wordStart, wordLength))); wordLength = 0; } } } if (wordLength > 0) { result.push(createTextChunk(pattern.substr(wordStart, wordLength))); } return result; } function createTextChunk(text) { var textLowerCase = text.toLowerCase(); return { text: text, textLowerCase: textLowerCase, isLowerCase: text === textLowerCase, characterSpans: breakIntoCharacterSpans(text) }; } /* @internal */ function breakIntoCharacterSpans(identifier) { return breakIntoSpans(identifier, /*word:*/ false); } ts.breakIntoCharacterSpans = breakIntoCharacterSpans; /* @internal */ function breakIntoWordSpans(identifier) { return breakIntoSpans(identifier, /*word:*/ true); } ts.breakIntoWordSpans = breakIntoWordSpans; function breakIntoSpans(identifier, word) { var result = []; var wordStart = 0; for (var i = 1; i < identifier.length; i++) { var lastIsDigit = isDigit(identifier.charCodeAt(i - 1)); var currentIsDigit = isDigit(identifier.charCodeAt(i)); var hasTransitionFromLowerToUpper = transitionFromLowerToUpper(identifier, word, i); var hasTransitionFromUpperToLower = transitionFromUpperToLower(identifier, word, i, wordStart); if (charIsPunctuation(identifier.charCodeAt(i - 1)) || charIsPunctuation(identifier.charCodeAt(i)) || lastIsDigit !== currentIsDigit || hasTransitionFromLowerToUpper || hasTransitionFromUpperToLower) { if (!isAllPunctuation(identifier, wordStart, i)) { result.push(ts.createTextSpan(wordStart, i - wordStart)); } wordStart = i; } } if (!isAllPunctuation(identifier, wordStart, identifier.length)) { result.push(ts.createTextSpan(wordStart, identifier.length - wordStart)); } return result; } function charIsPunctuation(ch) { switch (ch) { case 33 /* exclamation */: case 34 /* doubleQuote */: case 35 /* hash */: case 37 /* percent */: case 38 /* ampersand */: case 39 /* singleQuote */: case 40 /* openParen */: case 41 /* closeParen */: case 42 /* asterisk */: case 44 /* comma */: case 45 /* minus */: case 46 /* dot */: case 47 /* slash */: case 58 /* colon */: case 59 /* semicolon */: case 63 /* question */: case 64 /* at */: case 91 /* openBracket */: case 92 /* backslash */: case 93 /* closeBracket */: case 95 /* _ */: case 123 /* openBrace */: case 125 /* closeBrace */: return true; } return false; } function isAllPunctuation(identifier, start, end) { for (var i = start; i < end; i++) { var ch = identifier.charCodeAt(i); // We don't consider _ or $ as punctuation as there may be things with that name. if (!charIsPunctuation(ch) || ch === 95 /* _ */ || ch === 36 /* $ */) { return false; } } return true; } function transitionFromUpperToLower(identifier, word, index, wordStart) { if (word) { // Cases this supports: // 1) IDisposable -> I, Disposable // 2) UIElement -> UI, Element // 3) HTMLDocument -> HTML, Document // // etc. if (index !== wordStart && index + 1 < identifier.length) { var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); var nextIsLower = isLowerCaseLetter(identifier.charCodeAt(index + 1)); if (currentIsUpper && nextIsLower) { // We have a transition from an upper to a lower letter here. But we only // want to break if all the letters that preceded are uppercase. i.e. if we // have "Foo" we don't want to break that into "F, oo". But if we have // "IFoo" or "UIFoo", then we want to break that into "I, Foo" and "UI, // Foo". i.e. the last uppercase letter belongs to the lowercase letters // that follows. Note: this will make the following not split properly: // "HELLOthere". However, these sorts of names do not show up in .Net // programs. for (var i = wordStart; i < index; i++) { if (!isUpperCaseLetter(identifier.charCodeAt(i))) { return false; } } return true; } } } return false; } function transitionFromLowerToUpper(identifier, word, index) { var lastIsUpper = isUpperCaseLetter(identifier.charCodeAt(index - 1)); var currentIsUpper = isUpperCaseLetter(identifier.charCodeAt(index)); // See if the casing indicates we're starting a new word. Note: if we're breaking on // words, then just seeing an upper case character isn't enough. Instead, it has to // be uppercase and the previous character can't be uppercase. // // For example, breaking "AddMetadata" on words would make: Add Metadata // // on characters would be: A dd M etadata // // Break "AM" on words would be: AM // // on characters would be: A M // // We break the search string on characters. But we break the symbol name on words. var transition = word ? (currentIsUpper && !lastIsUpper) : currentIsUpper; return transition; } })(ts || (ts = {})); var ts; (function (ts) { function preProcessFile(sourceText, readImportFiles, detectJavaScriptImports) { if (readImportFiles === void 0) { readImportFiles = true; } if (detectJavaScriptImports === void 0) { detectJavaScriptImports = false; } var referencedFiles = []; var typeReferenceDirectives = []; var importedFiles = []; var ambientExternalModules; var isNoDefaultLib = false; var braceNesting = 0; // assume that text represent an external module if it contains at least one top level import/export // ambient modules that are found inside external modules are interpreted as module augmentations var externalModule = false; function nextToken() { var token = ts.scanner.scan(); if (token === 17 /* OpenBraceToken */) { braceNesting++; } else if (token === 18 /* CloseBraceToken */) { braceNesting--; } return token; } function processTripleSlashDirectives() { var commentRanges = ts.getLeadingCommentRanges(sourceText, 0); ts.forEach(commentRanges, function (commentRange) { var comment = sourceText.substring(commentRange.pos, commentRange.end); var referencePathMatchResult = ts.getFileReferenceFromReferencePath(comment, commentRange); if (referencePathMatchResult) { isNoDefaultLib = referencePathMatchResult.isNoDefaultLib; var fileReference = referencePathMatchResult.fileReference; if (fileReference) { var collection = referencePathMatchResult.isTypeReferenceDirective ? typeReferenceDirectives : referencedFiles; collection.push(fileReference); } } }); } function getFileReference() { var fileName = ts.scanner.getTokenValue(); var pos = ts.scanner.getTokenPos(); return { fileName: fileName, pos: pos, end: pos + fileName.length }; } function recordAmbientExternalModule() { if (!ambientExternalModules) { ambientExternalModules = []; } ambientExternalModules.push({ ref: getFileReference(), depth: braceNesting }); } function recordModuleName() { importedFiles.push(getFileReference()); markAsExternalModuleIfTopLevel(); } function markAsExternalModuleIfTopLevel() { if (braceNesting === 0) { externalModule = true; } } /** * Returns true if at least one token was consumed from the stream */ function tryConsumeDeclare() { var token = ts.scanner.getToken(); if (token === 124 /* DeclareKeyword */) { // declare module "mod" token = nextToken(); if (token === 128 /* ModuleKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { recordAmbientExternalModule(); } } return true; } return false; } /** * Returns true if at least one token was consumed from the stream */ function tryConsumeImport() { var token = ts.scanner.getToken(); if (token === 91 /* ImportKeyword */) { token = nextToken(); if (token === 19 /* OpenParenToken */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // import("mod"); recordModuleName(); return true; } } else if (token === 9 /* StringLiteral */) { // import "mod"; recordModuleName(); return true; } else { if (token === 71 /* Identifier */ || ts.isKeyword(token)) { token = nextToken(); if (token === 141 /* FromKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // import d from "mod"; recordModuleName(); return true; } } else if (token === 58 /* EqualsToken */) { if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } else if (token === 26 /* CommaToken */) { // consume comma and keep going token = nextToken(); } else { // unknown syntax return true; } } if (token === 17 /* OpenBraceToken */) { token = nextToken(); // consume "{ a as B, c, d as D}" clauses // make sure that it stops on EOF while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) { token = nextToken(); } if (token === 18 /* CloseBraceToken */) { token = nextToken(); if (token === 141 /* FromKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // import {a as A} from "mod"; // import d, {a, b as B} from "mod" recordModuleName(); } } } } else if (token === 39 /* AsteriskToken */) { token = nextToken(); if (token === 118 /* AsKeyword */) { token = nextToken(); if (token === 71 /* Identifier */ || ts.isKeyword(token)) { token = nextToken(); if (token === 141 /* FromKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // import * as NS from "mod" // import d, * as NS from "mod" recordModuleName(); } } } } } } return true; } return false; } function tryConsumeExport() { var token = ts.scanner.getToken(); if (token === 84 /* ExportKeyword */) { markAsExternalModuleIfTopLevel(); token = nextToken(); if (token === 17 /* OpenBraceToken */) { token = nextToken(); // consume "{ a as B, c, d as D}" clauses // make sure it stops on EOF while (token !== 18 /* CloseBraceToken */ && token !== 1 /* EndOfFileToken */) { token = nextToken(); } if (token === 18 /* CloseBraceToken */) { token = nextToken(); if (token === 141 /* FromKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // export {a as A} from "mod"; // export {a, b as B} from "mod" recordModuleName(); } } } } else if (token === 39 /* AsteriskToken */) { token = nextToken(); if (token === 141 /* FromKeyword */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // export * from "mod" recordModuleName(); } } } else if (token === 91 /* ImportKeyword */) { token = nextToken(); if (token === 71 /* Identifier */ || ts.isKeyword(token)) { token = nextToken(); if (token === 58 /* EqualsToken */) { if (tryConsumeRequireCall(/*skipCurrentToken*/ true)) { return true; } } } } return true; } return false; } function tryConsumeRequireCall(skipCurrentToken) { var token = skipCurrentToken ? nextToken() : ts.scanner.getToken(); if (token === 132 /* RequireKeyword */) { token = nextToken(); if (token === 19 /* OpenParenToken */) { token = nextToken(); if (token === 9 /* StringLiteral */) { // require("mod"); recordModuleName(); } } return true; } return false; } function tryConsumeDefine() { var token = ts.scanner.getToken(); if (token === 71 /* Identifier */ && ts.scanner.getTokenValue() === "define") { token = nextToken(); if (token !== 19 /* OpenParenToken */) { return true; } token = nextToken(); if (token === 9 /* StringLiteral */) { // looks like define ("modname", ... - skip string literal and comma token = nextToken(); if (token === 26 /* CommaToken */) { token = nextToken(); } else { // unexpected token return true; } } // should be start of dependency list if (token !== 21 /* OpenBracketToken */) { return true; } // skip open bracket token = nextToken(); // scan until ']' or EOF while (token !== 22 /* CloseBracketToken */ && token !== 1 /* EndOfFileToken */) { // record string literals as module names if (token === 9 /* StringLiteral */) { recordModuleName(); } token = nextToken(); } return true; } return false; } function processImports() { ts.scanner.setText(sourceText); nextToken(); // Look for: // import "mod"; // import d from "mod" // import {a as A } from "mod"; // import * as NS from "mod" // import d, {a, b as B} from "mod" // import i = require("mod"); // import("mod"); // export * from "mod" // export {a as b} from "mod" // export import i = require("mod") // (for JavaScript files) require("mod") while (true) { if (ts.scanner.getToken() === 1 /* EndOfFileToken */) { break; } // check if at least one of alternative have moved scanner forward if (tryConsumeDeclare() || tryConsumeImport() || tryConsumeExport() || (detectJavaScriptImports && (tryConsumeRequireCall(/*skipCurrentToken*/ false) || tryConsumeDefine()))) { continue; } else { nextToken(); } } ts.scanner.setText(undefined); } if (readImportFiles) { processImports(); } processTripleSlashDirectives(); if (externalModule) { // for external modules module all nested ambient modules are augmentations if (ambientExternalModules) { // move all detected ambient modules to imported files since they need to be resolved for (var _i = 0, ambientExternalModules_1 = ambientExternalModules; _i < ambientExternalModules_1.length; _i++) { var decl = ambientExternalModules_1[_i]; importedFiles.push(decl.ref); } } return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: undefined }; } else { // for global scripts ambient modules still can have augmentations - look for ambient modules with depth > 0 var ambientModuleNames = void 0; if (ambientExternalModules) { for (var _a = 0, ambientExternalModules_2 = ambientExternalModules; _a < ambientExternalModules_2.length; _a++) { var decl = ambientExternalModules_2[_a]; if (decl.depth === 0) { if (!ambientModuleNames) { ambientModuleNames = []; } ambientModuleNames.push(decl.ref.fileName); } else { importedFiles.push(decl.ref); } } } return { referencedFiles: referencedFiles, typeReferenceDirectives: typeReferenceDirectives, importedFiles: importedFiles, isLibFile: isNoDefaultLib, ambientExternalModules: ambientModuleNames }; } } ts.preProcessFile = preProcessFile; })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var Rename; (function (Rename) { function getRenameInfo(typeChecker, defaultLibFileName, getCanonicalFileName, sourceFile, position) { var getCanonicalDefaultLibName = ts.memoize(function () { return getCanonicalFileName(ts.normalizePath(defaultLibFileName)); }); var node = ts.getTouchingWord(sourceFile, position, /*includeJsDocComment*/ true); var renameInfo = node && nodeIsEligibleForRename(node) ? getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile) : undefined; return renameInfo || getRenameInfoError(ts.Diagnostics.You_cannot_rename_this_element); function isDefinedInLibraryFile(declaration) { if (!defaultLibFileName) { return false; } var sourceFile = declaration.getSourceFile(); var canonicalName = getCanonicalFileName(ts.normalizePath(sourceFile.fileName)); return canonicalName === getCanonicalDefaultLibName(); } } Rename.getRenameInfo = getRenameInfo; function getRenameInfoForNode(node, typeChecker, sourceFile, isDefinedInLibraryFile) { var symbol = typeChecker.getSymbolAtLocation(node); // Only allow a symbol to be renamed if it actually has at least one declaration. if (symbol) { var declarations = symbol.getDeclarations(); if (declarations && declarations.length > 0) { // Disallow rename for elements that are defined in the standard TypeScript library. if (ts.some(declarations, isDefinedInLibraryFile)) { return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); } // Cannot rename `default` as in `import { default as foo } from "./someModule"; if (node.kind === 71 /* Identifier */ && node.originalKeywordKind === 79 /* DefaultKeyword */ && symbol.parent.flags & 1536 /* Module */) { return undefined; } var displayName = ts.stripQuotes(ts.getDeclaredName(typeChecker, symbol, node)); var kind = ts.SymbolDisplay.getSymbolKind(typeChecker, symbol, node); return kind ? getRenameInfoSuccess(displayName, typeChecker.getFullyQualifiedName(symbol), kind, ts.SymbolDisplay.getSymbolModifiers(symbol), node, sourceFile) : undefined; } } else if (node.kind === 9 /* StringLiteral */) { if (isDefinedInLibraryFile(node)) { return getRenameInfoError(ts.Diagnostics.You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library); } var displayName = ts.stripQuotes(node.text); return getRenameInfoSuccess(displayName, displayName, "var" /* variableElement */, "" /* none */, node, sourceFile); } } function getRenameInfoSuccess(displayName, fullDisplayName, kind, kindModifiers, node, sourceFile) { return { canRename: true, kind: kind, displayName: displayName, localizedErrorMessage: undefined, fullDisplayName: fullDisplayName, kindModifiers: kindModifiers, triggerSpan: createTriggerSpanForNode(node, sourceFile) }; } function getRenameInfoError(diagnostic) { return { canRename: false, localizedErrorMessage: ts.getLocaleSpecificMessage(diagnostic), displayName: undefined, fullDisplayName: undefined, kind: undefined, kindModifiers: undefined, triggerSpan: undefined }; } function createTriggerSpanForNode(node, sourceFile) { var start = node.getStart(sourceFile); var width = node.getWidth(sourceFile); if (node.kind === 9 /* StringLiteral */) { // Exclude the quotes start += 1; width -= 2; } return ts.createTextSpan(start, width); } function nodeIsEligibleForRename(node) { switch (node.kind) { case 71 /* Identifier */: case 9 /* StringLiteral */: case 99 /* ThisKeyword */: return true; case 8 /* NumericLiteral */: return ts.isLiteralNameOfPropertyDeclarationOrIndexAccess(node); default: return false; } } })(Rename = ts.Rename || (ts.Rename = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { var SignatureHelp; (function (SignatureHelp) { var ArgumentListKind; (function (ArgumentListKind) { ArgumentListKind[ArgumentListKind["TypeArguments"] = 0] = "TypeArguments"; ArgumentListKind[ArgumentListKind["CallArguments"] = 1] = "CallArguments"; ArgumentListKind[ArgumentListKind["TaggedTemplateArguments"] = 2] = "TaggedTemplateArguments"; ArgumentListKind[ArgumentListKind["JSXAttributesArguments"] = 3] = "JSXAttributesArguments"; })(ArgumentListKind = SignatureHelp.ArgumentListKind || (SignatureHelp.ArgumentListKind = {})); function getSignatureHelpItems(program, sourceFile, position, cancellationToken) { var typeChecker = program.getTypeChecker(); // Decide whether to show signature help var startingToken = ts.findTokenOnLeftOfPosition(sourceFile, position); if (!startingToken) { // We are at the beginning of the file return undefined; } var argumentInfo = getContainingArgumentInfo(startingToken, position, sourceFile); if (!argumentInfo) return undefined; cancellationToken.throwIfCancellationRequested(); // Semantic filtering of signature help var call = argumentInfo.invocation; var candidates = []; var resolvedSignature = typeChecker.getResolvedSignature(call, candidates, argumentInfo.argumentCount); cancellationToken.throwIfCancellationRequested(); if (!candidates.length) { // We didn't have any sig help items produced by the TS compiler. If this is a JS // file, then see if we can figure out anything better. if (ts.isSourceFileJavaScript(sourceFile)) { return createJavaScriptSignatureHelpItems(argumentInfo, program); } return undefined; } return createSignatureHelpItems(candidates, resolvedSignature, argumentInfo, typeChecker); } SignatureHelp.getSignatureHelpItems = getSignatureHelpItems; function createJavaScriptSignatureHelpItems(argumentInfo, program) { if (argumentInfo.invocation.kind !== 182 /* CallExpression */) { return undefined; } // See if we can find some symbol with the call expression name that has call signatures. var callExpression = argumentInfo.invocation; var expression = callExpression.expression; var name = expression.kind === 71 /* Identifier */ ? expression : expression.kind === 180 /* PropertyAccessExpression */ ? expression.name : undefined; if (!name || !name.escapedText) { return undefined; } var typeChecker = program.getTypeChecker(); for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; var nameToDeclarations = sourceFile.getNamedDeclarations(); var declarations = nameToDeclarations.get(name.text); if (declarations) { for (var _b = 0, declarations_12 = declarations; _b < declarations_12.length; _b++) { var declaration = declarations_12[_b]; var symbol = declaration.symbol; if (symbol) { var type = typeChecker.getTypeOfSymbolAtLocation(symbol, declaration); if (type) { var callSignatures = type.getCallSignatures(); if (callSignatures && callSignatures.length) { return createSignatureHelpItems(callSignatures, callSignatures[0], argumentInfo, typeChecker); } } } } } } } /** * Returns relevant information for the argument list and the current argument if we are * in the argument of an invocation; returns undefined otherwise. */ function getImmediatelyContainingArgumentInfo(node, position, sourceFile) { if (ts.isCallOrNewExpression(node.parent)) { var invocation = node.parent; var list = void 0; var argumentIndex = void 0; // There are 3 cases to handle: // 1. The token introduces a list, and should begin a signature help session // 2. The token is either not associated with a list, or ends a list, so the session should end // 3. The token is buried inside a list, and should give signature help // // The following are examples of each: // // Case 1: // foo<#T, U>(#a, b) -> The token introduces a list, and should begin a signature help session // Case 2: // fo#o#(a, b)# -> The token is either not associated with a list, or ends a list, so the session should end // Case 3: // foo(a#, #b#) -> The token is buried inside a list, and should give signature help // Find out if 'node' is an argument, a type argument, or neither if (node.kind === 27 /* LessThanToken */ || node.kind === 19 /* OpenParenToken */) { // Find the list that starts right *after* the < or ( token. // If the user has just opened a list, consider this item 0. list = getChildListThatStartsWithOpenerToken(invocation, node, sourceFile); ts.Debug.assert(list !== undefined); argumentIndex = 0; } else { // findListItemInfo can return undefined if we are not in parent's argument list // or type argument list. This includes cases where the cursor is: // - To the right of the closing parenthesis, non-substitution template, or template tail. // - Between the type arguments and the arguments (greater than token) // - On the target of the call (parent.func) // - On the 'new' keyword in a 'new' expression list = ts.findContainingList(node); if (!list) return undefined; argumentIndex = getArgumentIndex(list, node); } var kind = invocation.typeArguments && invocation.typeArguments.pos === list.pos ? 0 /* TypeArguments */ : 1 /* CallArguments */; var argumentCount = getArgumentCount(list); if (argumentIndex !== 0) { ts.Debug.assertLessThan(argumentIndex, argumentCount); } var argumentsSpan = getApplicableSpanForArguments(list, sourceFile); return { kind: kind, invocation: invocation, argumentsSpan: argumentsSpan, argumentIndex: argumentIndex, argumentCount: argumentCount }; } else if (node.kind === 13 /* NoSubstitutionTemplateLiteral */ && node.parent.kind === 184 /* TaggedTemplateExpression */) { // Check if we're actually inside the template; // otherwise we'll fall out and return undefined. if (ts.isInsideTemplateLiteral(node, position)) { return getArgumentListInfoForTemplate(node.parent, /*argumentIndex*/ 0, sourceFile); } } else if (node.kind === 14 /* TemplateHead */ && node.parent.parent.kind === 184 /* TaggedTemplateExpression */) { var templateExpression = node.parent; var tagExpression = templateExpression.parent; ts.Debug.assert(templateExpression.kind === 197 /* TemplateExpression */); var argumentIndex = ts.isInsideTemplateLiteral(node, position) ? 0 : 1; return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile); } else if (node.parent.kind === 206 /* TemplateSpan */ && node.parent.parent.parent.kind === 184 /* TaggedTemplateExpression */) { var templateSpan = node.parent; var templateExpression = templateSpan.parent; var tagExpression = templateExpression.parent; ts.Debug.assert(templateExpression.kind === 197 /* TemplateExpression */); // If we're just after a template tail, don't show signature help. if (node.kind === 16 /* TemplateTail */ && !ts.isInsideTemplateLiteral(node, position)) { return undefined; } var spanIndex = templateExpression.templateSpans.indexOf(templateSpan); var argumentIndex = getArgumentIndexForTemplatePiece(spanIndex, node, position); return getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile); } else if (node.parent && ts.isJsxOpeningLikeElement(node.parent)) { // Provide a signature help for JSX opening element or JSX self-closing element. // This is not guarantee that JSX tag-name is resolved into stateless function component. (that is done in "getSignatureHelpItems") // i.e // export function MainButton(props: ButtonProps, context: any): JSX.Element { ... } // ' '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' ''. 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' '' '' // That will give us 2 non-commas. We then add one for the last comma, giving us an // arg count of 3. var listChildren = argumentsList.getChildren(); var argumentCount = ts.countWhere(listChildren, function (arg) { return arg.kind !== 26 /* CommaToken */; }); if (listChildren.length > 0 && ts.lastOrUndefined(listChildren).kind === 26 /* CommaToken */) { argumentCount++; } return argumentCount; } // spanIndex is either the index for a given template span. // This does not give appropriate results for a NoSubstitutionTemplateLiteral function getArgumentIndexForTemplatePiece(spanIndex, node, position) { // Because the TemplateStringsArray is the first argument, we have to offset each substitution expression by 1. // There are three cases we can encounter: // 1. We are precisely in the template literal (argIndex = 0). // 2. We are in or to the right of the substitution expression (argIndex = spanIndex + 1). // 3. We are directly to the right of the template literal, but because we look for the token on the left, // not enough to put us in the substitution expression; we should consider ourselves part of // the *next* span's expression by offsetting the index (argIndex = (spanIndex + 1) + 1). // // Example: f `# abcd $#{# 1 + 1# }# efghi ${ #"#hello"# } # ` // ^ ^ ^ ^ ^ ^ ^ ^ ^ // Case: 1 1 3 2 1 3 2 2 1 ts.Debug.assert(position >= node.getStart(), "Assumed 'position' could not occur before node."); if (ts.isTemplateLiteralKind(node.kind)) { if (ts.isInsideTemplateLiteral(node, position)) { return 0; } return spanIndex + 2; } return spanIndex + 1; } function getArgumentListInfoForTemplate(tagExpression, argumentIndex, sourceFile) { // argumentCount is either 1 or (numSpans + 1) to account for the template strings array argument. var argumentCount = tagExpression.template.kind === 13 /* NoSubstitutionTemplateLiteral */ ? 1 : tagExpression.template.templateSpans.length + 1; if (argumentIndex !== 0) { ts.Debug.assertLessThan(argumentIndex, argumentCount); } return { kind: 2 /* TaggedTemplateArguments */, invocation: tagExpression, argumentsSpan: getApplicableSpanForTaggedTemplate(tagExpression, sourceFile), argumentIndex: argumentIndex, argumentCount: argumentCount }; } function getApplicableSpanForArguments(argumentsList, sourceFile) { // We use full start and skip trivia on the end because we want to include trivia on // both sides. For example, // // foo( /*comment */ a, b, c /*comment*/ ) // | | // // The applicable span is from the first bar to the second bar (inclusive, // but not including parentheses) var applicableSpanStart = argumentsList.getFullStart(); var applicableSpanEnd = ts.skipTrivia(sourceFile.text, argumentsList.getEnd(), /*stopAfterLineBreak*/ false); return ts.createTextSpan(applicableSpanStart, applicableSpanEnd - applicableSpanStart); } function getApplicableSpanForTaggedTemplate(taggedTemplate, sourceFile) { var template = taggedTemplate.template; var applicableSpanStart = template.getStart(); var applicableSpanEnd = template.getEnd(); // We need to adjust the end position for the case where the template does not have a tail. // Otherwise, we will not show signature help past the expression. // For example, // // ` ${ 1 + 1 foo(10) // | | // // This is because a Missing node has no width. However, what we actually want is to include trivia // leading up to the next token in case the user is about to type in a TemplateMiddle or TemplateTail. if (template.kind === 197 /* 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 !== 269 /* SourceFile */; n = n.parent) { if (ts.isFunctionBlock(n)) { return undefined; } // If the node is not a subspan of its parent, this is a big problem. // There have been crashes that might be caused by this violation. if (n.pos < n.parent.pos || n.end > n.parent.end) { ts.Debug.fail("Node of kind " + n.kind + " is not a subspan of its parent of kind " + n.parent.kind); } var argumentInfo = getImmediatelyContainingArgumentInfo(n, position, sourceFile); if (argumentInfo) { return argumentInfo; } // TODO: Handle generic call with incomplete syntax } return undefined; } SignatureHelp.getContainingArgumentInfo = getContainingArgumentInfo; function getChildListThatStartsWithOpenerToken(parent, openerToken, sourceFile) { var children = parent.getChildren(sourceFile); var indexOfOpenerToken = children.indexOf(openerToken); ts.Debug.assert(indexOfOpenerToken >= 0 && children.length > indexOfOpenerToken + 1); return children[indexOfOpenerToken + 1]; } function createSignatureHelpItems(candidates, resolvedSignature, argumentListInfo, typeChecker) { var argumentCount = argumentListInfo.argumentCount, applicableSpan = argumentListInfo.argumentsSpan, invocation = argumentListInfo.invocation, argumentIndex = argumentListInfo.argumentIndex; var isTypeParameterList = argumentListInfo.kind === 0 /* TypeArguments */; var callTarget = ts.getInvokedExpression(invocation); var callTargetSymbol = typeChecker.getSymbolAtLocation(callTarget); var callTargetDisplayParts = callTargetSymbol && ts.symbolToDisplayParts(typeChecker, callTargetSymbol, /*enclosingDeclaration*/ undefined, /*meaning*/ undefined); var items = ts.map(candidates, function (candidateSignature) { var signatureHelpParameters; var prefixDisplayParts = []; var suffixDisplayParts = []; if (callTargetDisplayParts) { ts.addRange(prefixDisplayParts, callTargetDisplayParts); } var isVariadic; if (isTypeParameterList) { isVariadic = false; // type parameter lists are not variadic prefixDisplayParts.push(ts.punctuationPart(27 /* LessThanToken */)); var typeParameters = (candidateSignature.target || candidateSignature).typeParameters; signatureHelpParameters = typeParameters && typeParameters.length > 0 ? ts.map(typeParameters, createSignatureHelpParameterForTypeParameter) : ts.emptyArray; suffixDisplayParts.push(ts.punctuationPart(29 /* GreaterThanToken */)); var parameterParts = ts.mapToDisplayParts(function (writer) { return typeChecker.getSymbolDisplayBuilder().buildDisplayForParametersAndDelimiters(candidateSignature.thisParameter, candidateSignature.parameters, writer, invocation); }); ts.addRange(suffixDisplayParts, parameterParts); } else { isVariadic = candidateSignature.hasRestParameter; var typeParameterParts = ts.mapToDisplayParts(function (writer) { return typeChecker.getSymbolDisplayBuilder().buildDisplayForTypeParametersAndDelimiters(candidateSignature.typeParameters, writer, invocation); }); ts.addRange(prefixDisplayParts, typeParameterParts); prefixDisplayParts.push(ts.punctuationPart(19 /* OpenParenToken */)); signatureHelpParameters = ts.map(candidateSignature.parameters, createSignatureHelpParameterForParameter); suffixDisplayParts.push(ts.punctuationPart(20 /* CloseParenToken */)); } var returnTypeParts = ts.mapToDisplayParts(function (writer) { return typeChecker.getSymbolDisplayBuilder().buildReturnTypeDisplay(candidateSignature, writer, invocation); }); ts.addRange(suffixDisplayParts, returnTypeParts); return { isVariadic: isVariadic, prefixDisplayParts: prefixDisplayParts, suffixDisplayParts: suffixDisplayParts, separatorDisplayParts: [ts.punctuationPart(26 /* CommaToken */), ts.spacePart()], parameters: signatureHelpParameters, documentation: candidateSignature.getDocumentationComment(typeChecker), tags: candidateSignature.getJsDocTags() }; }); if (argumentIndex !== 0) { ts.Debug.assertLessThan(argumentIndex, argumentCount); } var selectedItemIndex = candidates.indexOf(resolvedSignature); ts.Debug.assert(selectedItemIndex !== -1); // If candidates is non-empty it should always include bestSignature. We check for an empty candidates before calling this function. return { items: items, applicableSpan: applicableSpan, selectedItemIndex: selectedItemIndex, argumentIndex: argumentIndex, argumentCount: argumentCount }; function createSignatureHelpParameterForParameter(parameter) { var displayParts = ts.mapToDisplayParts(function (writer) { return typeChecker.getSymbolDisplayBuilder().buildParameterDisplay(parameter, writer, invocation); }); return { name: parameter.name, documentation: parameter.getDocumentationComment(typeChecker), displayParts: displayParts, isOptional: typeChecker.isOptionalParameter(parameter.valueDeclaration) }; } function createSignatureHelpParameterForTypeParameter(typeParameter) { var displayParts = ts.mapToDisplayParts(function (writer) { return typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(typeParameter, writer, invocation); }); return { name: typeParameter.symbol.name, documentation: ts.emptyArray, displayParts: displayParts, isOptional: false }; } } })(SignatureHelp = ts.SignatureHelp || (ts.SignatureHelp = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var SymbolDisplay; (function (SymbolDisplay) { // TODO(drosen): use contextual SemanticMeaning. function getSymbolKind(typeChecker, symbol, location) { var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol); if (flags & 32 /* Class */) { return ts.getDeclarationOfKind(symbol, 200 /* ClassExpression */) ? "local class" /* localClassElement */ : "class" /* classElement */; } if (flags & 384 /* Enum */) return "enum" /* enumElement */; if (flags & 524288 /* TypeAlias */) return "type" /* typeElement */; if (flags & 64 /* Interface */) return "interface" /* interfaceElement */; if (flags & 262144 /* TypeParameter */) return "type parameter" /* typeParameterElement */; var result = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location); if (result === "" /* unknown */) { if (flags & 262144 /* TypeParameter */) return "type parameter" /* typeParameterElement */; if (flags & 8 /* EnumMember */) return "enum member" /* enumMemberElement */; if (flags & 2097152 /* Alias */) return "alias" /* alias */; if (flags & 1536 /* Module */) return "module" /* moduleElement */; } return result; } SymbolDisplay.getSymbolKind = getSymbolKind; function getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location) { if (typeChecker.isUndefinedSymbol(symbol)) { return "var" /* variableElement */; } if (typeChecker.isArgumentsSymbol(symbol)) { return "local var" /* localVariableElement */; } if (location.kind === 99 /* ThisKeyword */ && ts.isExpression(location)) { return "parameter" /* parameterElement */; } var flags = ts.getCombinedLocalAndExportSymbolFlags(symbol); if (flags & 3 /* Variable */) { if (ts.isFirstDeclarationOfSymbolParameter(symbol)) { return "parameter" /* parameterElement */; } else if (symbol.valueDeclaration && ts.isConst(symbol.valueDeclaration)) { return "const" /* constElement */; } else if (ts.forEach(symbol.declarations, ts.isLet)) { return "let" /* letElement */; } return isLocalVariableOrFunction(symbol) ? "local var" /* localVariableElement */ : "var" /* variableElement */; } if (flags & 16 /* Function */) return isLocalVariableOrFunction(symbol) ? "local function" /* localFunctionElement */ : "function" /* functionElement */; if (flags & 32768 /* GetAccessor */) return "getter" /* memberGetAccessorElement */; if (flags & 65536 /* SetAccessor */) return "setter" /* memberSetAccessorElement */; if (flags & 8192 /* Method */) return "method" /* memberFunctionElement */; if (flags & 16384 /* Constructor */) return "constructor" /* constructorImplementationElement */; if (flags & 4 /* Property */) { if (flags & 33554432 /* Transient */ && symbol.checkFlags & 6 /* Synthetic */) { // If union property is result of union of non method (property/accessors/variables), it is labeled as property var unionPropertyKind = ts.forEach(typeChecker.getRootSymbols(symbol), function (rootSymbol) { var rootSymbolFlags = rootSymbol.getFlags(); if (rootSymbolFlags & (98308 /* PropertyOrAccessor */ | 3 /* Variable */)) { return "property" /* memberVariableElement */; } // May be a Function if this was from `typeof N` with `namespace N { function f();. }`. ts.Debug.assert(!!(rootSymbolFlags & (8192 /* Method */ | 16 /* Function */))); }); if (!unionPropertyKind) { // If this was union of all methods, // make sure it has call signatures before we can label it as method var typeOfUnionProperty = typeChecker.getTypeOfSymbolAtLocation(symbol, location); if (typeOfUnionProperty.getCallSignatures().length) { return "method" /* memberFunctionElement */; } return "property" /* memberVariableElement */; } return unionPropertyKind; } // If we requested completions after `x.` at the top-level, we may be at a source file location. switch (location.parent && location.parent.kind) { // If we've typed a character of the attribute name, will be 'JsxAttribute', else will be 'JsxOpeningElement'. case 252 /* JsxOpeningElement */: return location.kind === 71 /* Identifier */ ? "property" /* memberVariableElement */ : "JSX attribute" /* jsxAttribute */; case 257 /* JsxAttribute */: return "JSX attribute" /* jsxAttribute */; default: return "property" /* memberVariableElement */; } } return "" /* unknown */; } function getSymbolModifiers(symbol) { return symbol && symbol.declarations && symbol.declarations.length > 0 ? ts.getNodeModifiers(symbol.declarations[0]) : "" /* none */; } SymbolDisplay.getSymbolModifiers = getSymbolModifiers; // TODO(drosen): Currently completion entry details passes the SemanticMeaning.All instead of using semanticMeaning of location function getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, enclosingDeclaration, location, semanticMeaning) { if (semanticMeaning === void 0) { semanticMeaning = ts.getMeaningFromLocation(location); } var displayParts = []; var documentation; var tags; var symbolFlags = ts.getCombinedLocalAndExportSymbolFlags(symbol); var symbolKind = getSymbolKindOfConstructorPropertyMethodAccessorFunctionOrVar(typeChecker, symbol, location); var hasAddedSymbolInfo; var isThisExpression = location.kind === 99 /* ThisKeyword */ && ts.isExpression(location); var type; // Class at constructor site need to be shown as constructor apart from property,method, vars if (symbolKind !== "" /* unknown */ || symbolFlags & 32 /* Class */ || symbolFlags & 2097152 /* Alias */) { // If it is accessor they are allowed only if location is at name of the accessor if (symbolKind === "getter" /* memberGetAccessorElement */ || symbolKind === "setter" /* memberSetAccessorElement */) { symbolKind = "property" /* memberVariableElement */; } var signature = void 0; type = isThisExpression ? typeChecker.getTypeAtLocation(location) : typeChecker.getTypeOfSymbolAtLocation(symbol.exportSymbol || symbol, location); if (location.parent && location.parent.kind === 180 /* PropertyAccessExpression */) { var right = location.parent.name; // Either the location is on the right of a property access, or on the left and the right is missing if (right === location || (right && right.getFullWidth() === 0)) { location = location.parent; } } // try get the call/construct signature from the type if it matches var callExpressionLike = void 0; if (ts.isCallOrNewExpression(location)) { callExpressionLike = location; } else if (ts.isCallExpressionTarget(location) || ts.isNewExpressionTarget(location)) { callExpressionLike = location.parent; } else if (location.parent && ts.isJsxOpeningLikeElement(location.parent) && ts.isFunctionLike(symbol.valueDeclaration)) { callExpressionLike = location.parent; } if (callExpressionLike) { var candidateSignatures = []; signature = typeChecker.getResolvedSignature(callExpressionLike, candidateSignatures); var useConstructSignatures = callExpressionLike.kind === 183 /* NewExpression */ || (ts.isCallExpression(callExpressionLike) && callExpressionLike.expression.kind === 97 /* SuperKeyword */); var allSignatures = useConstructSignatures ? type.getConstructSignatures() : type.getCallSignatures(); if (!ts.contains(allSignatures, signature.target) && !ts.contains(allSignatures, signature)) { // Get the first signature if there is one -- allSignatures may contain // either the original signature or its target, so check for either signature = allSignatures.length ? allSignatures[0] : undefined; } if (signature) { if (useConstructSignatures && (symbolFlags & 32 /* Class */)) { // Constructor symbolKind = "constructor" /* constructorImplementationElement */; addPrefixForAnyFunctionOrVar(type.symbol, symbolKind); } else if (symbolFlags & 2097152 /* Alias */) { symbolKind = "alias" /* alias */; pushTypePart(symbolKind); displayParts.push(ts.spacePart()); if (useConstructSignatures) { displayParts.push(ts.keywordPart(94 /* NewKeyword */)); displayParts.push(ts.spacePart()); } addFullSymbolName(symbol); } else { addPrefixForAnyFunctionOrVar(symbol, symbolKind); } switch (symbolKind) { case "JSX attribute" /* jsxAttribute */: case "property" /* memberVariableElement */: case "var" /* variableElement */: case "const" /* constElement */: case "let" /* letElement */: case "parameter" /* parameterElement */: case "local var" /* localVariableElement */: // If it is call or construct signature of lambda's write type name displayParts.push(ts.punctuationPart(56 /* ColonToken */)); displayParts.push(ts.spacePart()); if (!(type.flags & 65536 /* Object */ && type.objectFlags & 16 /* Anonymous */) && type.symbol) { ts.addRange(displayParts, ts.symbolToDisplayParts(typeChecker, type.symbol, enclosingDeclaration, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */)); displayParts.push(ts.lineBreakPart()); } if (useConstructSignatures) { displayParts.push(ts.keywordPart(94 /* NewKeyword */)); displayParts.push(ts.spacePart()); } addSignatureDisplayParts(signature, allSignatures, 16 /* WriteArrowStyleSignature */); break; default: // Just signature addSignatureDisplayParts(signature, allSignatures); } hasAddedSymbolInfo = true; } } else if ((ts.isNameOfFunctionDeclaration(location) && !(symbolFlags & 98304 /* Accessor */)) || // name of function declaration (location.kind === 123 /* ConstructorKeyword */ && location.parent.kind === 153 /* Constructor */)) { // get the signature from the declaration and write it var functionDeclaration_1 = location.parent; // Use function declaration to write the signatures only if the symbol corresponding to this declaration var locationIsSymbolDeclaration = ts.find(symbol.declarations, function (declaration) { return declaration === (location.kind === 123 /* ConstructorKeyword */ ? functionDeclaration_1.parent : functionDeclaration_1); }); if (locationIsSymbolDeclaration) { var allSignatures = functionDeclaration_1.kind === 153 /* Constructor */ ? type.getNonNullableType().getConstructSignatures() : type.getNonNullableType().getCallSignatures(); if (!typeChecker.isImplementationOfOverload(functionDeclaration_1)) { signature = typeChecker.getSignatureFromDeclaration(functionDeclaration_1); } else { signature = allSignatures[0]; } if (functionDeclaration_1.kind === 153 /* Constructor */) { // show (constructor) Type(...) signature symbolKind = "constructor" /* constructorImplementationElement */; addPrefixForAnyFunctionOrVar(type.symbol, symbolKind); } else { // (function/method) symbol(..signature) addPrefixForAnyFunctionOrVar(functionDeclaration_1.kind === 156 /* 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, 200 /* 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 pushTypePart("local class" /* localClassElement */); } else { // Class declaration has name which is not local. displayParts.push(ts.keywordPart(75 /* ClassKeyword */)); } displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } if ((symbolFlags & 64 /* Interface */) && (semanticMeaning & 2 /* Type */)) { addNewLineIfDisplayPartsExist(); displayParts.push(ts.keywordPart(109 /* InterfaceKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); } if (symbolFlags & 524288 /* TypeAlias */) { addNewLineIfDisplayPartsExist(); displayParts.push(ts.keywordPart(138 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); writeTypeParametersOfSymbol(symbol, sourceFile); displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(58 /* EqualsToken */)); displayParts.push(ts.spacePart()); ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, typeChecker.getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, 1024 /* InTypeAlias */)); } if (symbolFlags & 384 /* Enum */) { addNewLineIfDisplayPartsExist(); if (ts.forEach(symbol.declarations, ts.isConstEnumDeclaration)) { displayParts.push(ts.keywordPart(76 /* ConstKeyword */)); displayParts.push(ts.spacePart()); } displayParts.push(ts.keywordPart(83 /* EnumKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } if (symbolFlags & 1536 /* Module */) { addNewLineIfDisplayPartsExist(); var declaration = ts.getDeclarationOfKind(symbol, 234 /* ModuleDeclaration */); var isNamespace = declaration && declaration.name && declaration.name.kind === 71 /* Identifier */; displayParts.push(ts.keywordPart(isNamespace ? 129 /* NamespaceKeyword */ : 128 /* ModuleKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } if ((symbolFlags & 262144 /* TypeParameter */) && (semanticMeaning & 2 /* Type */)) { addNewLineIfDisplayPartsExist(); displayParts.push(ts.punctuationPart(19 /* OpenParenToken */)); displayParts.push(ts.textPart("type parameter")); displayParts.push(ts.punctuationPart(20 /* CloseParenToken */)); displayParts.push(ts.spacePart()); addFullSymbolName(symbol); if (symbol.parent) { // Class/Interface type parameter addInPrefix(); addFullSymbolName(symbol.parent, enclosingDeclaration); writeTypeParametersOfSymbol(symbol.parent, enclosingDeclaration); } else { // Method/function type parameter var decl = ts.getDeclarationOfKind(symbol, 146 /* TypeParameter */); ts.Debug.assert(decl !== undefined); var declaration = decl.parent; if (declaration) { if (ts.isFunctionLikeKind(declaration.kind)) { addInPrefix(); var signature = typeChecker.getSignatureFromDeclaration(declaration); if (declaration.kind === 157 /* ConstructSignature */) { displayParts.push(ts.keywordPart(94 /* NewKeyword */)); displayParts.push(ts.spacePart()); } else if (declaration.kind !== 156 /* CallSignature */ && declaration.name) { addFullSymbolName(declaration.symbol); } ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, sourceFile, 64 /* WriteTypeArgumentsOfSignature */)); } else if (declaration.kind === 232 /* TypeAliasDeclaration */) { // Type alias type parameter // For example // type list = T[]; // Both T will go through same code path addInPrefix(); displayParts.push(ts.keywordPart(138 /* TypeKeyword */)); displayParts.push(ts.spacePart()); addFullSymbolName(declaration.symbol); writeTypeParametersOfSymbol(declaration.symbol, sourceFile); } } } } if (symbolFlags & 8 /* EnumMember */) { symbolKind = "enum member" /* enumMemberElement */; addPrefixForAnyFunctionOrVar(symbol, "enum member"); var declaration = symbol.declarations[0]; if (declaration.kind === 268 /* EnumMember */) { var constantValue = typeChecker.getConstantValue(declaration); if (constantValue !== undefined) { displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(58 /* EqualsToken */)); displayParts.push(ts.spacePart()); displayParts.push(ts.displayPart(ts.getTextOfConstantValue(constantValue), typeof constantValue === "number" ? ts.SymbolDisplayPartKind.numericLiteral : ts.SymbolDisplayPartKind.stringLiteral)); } } } if (symbolFlags & 2097152 /* Alias */) { addNewLineIfDisplayPartsExist(); switch (symbol.declarations[0].kind) { case 237 /* NamespaceExportDeclaration */: displayParts.push(ts.keywordPart(84 /* ExportKeyword */)); displayParts.push(ts.spacePart()); displayParts.push(ts.keywordPart(129 /* NamespaceKeyword */)); break; case 244 /* ExportAssignment */: displayParts.push(ts.keywordPart(84 /* ExportKeyword */)); displayParts.push(ts.spacePart()); displayParts.push(ts.keywordPart(symbol.declarations[0].isExportEquals ? 58 /* EqualsToken */ : 79 /* DefaultKeyword */)); break; default: displayParts.push(ts.keywordPart(91 /* ImportKeyword */)); } displayParts.push(ts.spacePart()); addFullSymbolName(symbol); ts.forEach(symbol.declarations, function (declaration) { if (declaration.kind === 238 /* ImportEqualsDeclaration */) { var importEqualsDeclaration = declaration; if (ts.isExternalModuleImportEqualsDeclaration(importEqualsDeclaration)) { displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(58 /* EqualsToken */)); displayParts.push(ts.spacePart()); displayParts.push(ts.keywordPart(132 /* RequireKeyword */)); displayParts.push(ts.punctuationPart(19 /* OpenParenToken */)); displayParts.push(ts.displayPart(ts.getTextOfNode(ts.getExternalModuleImportEqualsDeclarationExpression(importEqualsDeclaration)), ts.SymbolDisplayPartKind.stringLiteral)); displayParts.push(ts.punctuationPart(20 /* CloseParenToken */)); } else { var internalAliasSymbol = typeChecker.getSymbolAtLocation(importEqualsDeclaration.moduleReference); if (internalAliasSymbol) { displayParts.push(ts.spacePart()); displayParts.push(ts.operatorPart(58 /* EqualsToken */)); displayParts.push(ts.spacePart()); addFullSymbolName(internalAliasSymbol, enclosingDeclaration); } } return true; } }); } if (!hasAddedSymbolInfo) { if (symbolKind !== "" /* unknown */) { if (type) { if (isThisExpression) { addNewLineIfDisplayPartsExist(); displayParts.push(ts.keywordPart(99 /* ThisKeyword */)); } else { addPrefixForAnyFunctionOrVar(symbol, symbolKind); } // For properties, variables and local vars: show the type if (symbolKind === "property" /* memberVariableElement */ || symbolKind === "JSX attribute" /* jsxAttribute */ || symbolFlags & 3 /* Variable */ || symbolKind === "local var" /* localVariableElement */ || isThisExpression) { displayParts.push(ts.punctuationPart(56 /* ColonToken */)); displayParts.push(ts.spacePart()); // If the type is type parameter, format it specially if (type.symbol && type.symbol.flags & 262144 /* TypeParameter */) { var typeParameterParts = ts.mapToDisplayParts(function (writer) { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplay(type, writer, enclosingDeclaration); }); ts.addRange(displayParts, typeParameterParts); } else { ts.addRange(displayParts, ts.typeToDisplayParts(typeChecker, type, enclosingDeclaration)); } } else if (symbolFlags & 16 /* Function */ || symbolFlags & 8192 /* Method */ || symbolFlags & 16384 /* Constructor */ || symbolFlags & 131072 /* Signature */ || symbolFlags & 98304 /* Accessor */ || symbolKind === "method" /* memberFunctionElement */) { var allSignatures = type.getNonNullableType().getCallSignatures(); if (allSignatures.length) { addSignatureDisplayParts(allSignatures[0], allSignatures); } } } } else { symbolKind = getSymbolKind(typeChecker, symbol, location); } } if (!documentation) { documentation = symbol.getDocumentationComment(typeChecker); tags = symbol.getJsDocTags(); if (documentation.length === 0 && symbolFlags & 4 /* Property */) { // For some special property access expressions like `exports.foo = foo` or `module.exports.foo = foo` // there documentation comments might be attached to the right hand side symbol of their declarations. // The pattern of such special property access is that the parent symbol is the symbol of the file. if (symbol.parent && ts.forEach(symbol.parent.declarations, function (declaration) { return declaration.kind === 269 /* SourceFile */; })) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (!declaration.parent || declaration.parent.kind !== 195 /* BinaryExpression */) { continue; } var rhsSymbol = typeChecker.getSymbolAtLocation(declaration.parent.right); if (!rhsSymbol) { continue; } documentation = rhsSymbol.getDocumentationComment(typeChecker); tags = rhsSymbol.getJsDocTags(); if (documentation.length > 0) { break; } } } } } return { displayParts: displayParts, documentation: documentation, symbolKind: symbolKind, tags: tags }; function addNewLineIfDisplayPartsExist() { if (displayParts.length) { displayParts.push(ts.lineBreakPart()); } } function addInPrefix() { displayParts.push(ts.spacePart()); displayParts.push(ts.keywordPart(92 /* InKeyword */)); displayParts.push(ts.spacePart()); } function addFullSymbolName(symbol, enclosingDeclaration) { var fullSymbolDisplayParts = ts.symbolToDisplayParts(typeChecker, symbol, enclosingDeclaration || sourceFile, /*meaning*/ undefined, 1 /* WriteTypeParametersOrArguments */ | 2 /* UseOnlyExternalAliasing */); ts.addRange(displayParts, fullSymbolDisplayParts); } function addPrefixForAnyFunctionOrVar(symbol, symbolKind) { addNewLineIfDisplayPartsExist(); if (symbolKind) { pushTypePart(symbolKind); if (!ts.some(symbol.declarations, function (d) { return ts.isArrowFunction(d) || (ts.isFunctionExpression(d) || ts.isClassExpression(d)) && !d.name; })) { displayParts.push(ts.spacePart()); addFullSymbolName(symbol); } } } function pushTypePart(symbolKind) { switch (symbolKind) { case "var" /* variableElement */: case "function" /* functionElement */: case "let" /* letElement */: case "const" /* constElement */: case "constructor" /* constructorImplementationElement */: displayParts.push(ts.textOrKeywordPart(symbolKind)); return; default: displayParts.push(ts.punctuationPart(19 /* OpenParenToken */)); displayParts.push(ts.textOrKeywordPart(symbolKind)); displayParts.push(ts.punctuationPart(20 /* CloseParenToken */)); return; } } function addSignatureDisplayParts(signature, allSignatures, flags) { ts.addRange(displayParts, ts.signatureToDisplayParts(typeChecker, signature, enclosingDeclaration, flags | 64 /* WriteTypeArgumentsOfSignature */)); if (allSignatures.length > 1) { displayParts.push(ts.spacePart()); displayParts.push(ts.punctuationPart(19 /* OpenParenToken */)); displayParts.push(ts.operatorPart(37 /* PlusToken */)); displayParts.push(ts.displayPart((allSignatures.length - 1).toString(), ts.SymbolDisplayPartKind.numericLiteral)); displayParts.push(ts.spacePart()); displayParts.push(ts.textPart(allSignatures.length === 2 ? "overload" : "overloads")); displayParts.push(ts.punctuationPart(20 /* CloseParenToken */)); } documentation = signature.getDocumentationComment(typeChecker); tags = signature.getJsDocTags(); } function writeTypeParametersOfSymbol(symbol, enclosingDeclaration) { var typeParameterParts = ts.mapToDisplayParts(function (writer) { typeChecker.getSymbolDisplayBuilder().buildTypeParameterDisplayFromSymbol(symbol, writer, enclosingDeclaration); }); ts.addRange(displayParts, typeParameterParts); } } SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind = getSymbolDisplayPartsDocumentationAndSymbolKind; function isLocalVariableOrFunction(symbol) { if (symbol.parent) { return false; // This is exported symbol } return ts.forEach(symbol.declarations, function (declaration) { // Function expressions are local if (declaration.kind === 187 /* FunctionExpression */) { return true; } if (declaration.kind !== 227 /* VariableDeclaration */ && declaration.kind !== 229 /* FunctionDeclaration */) { return false; } // If the parent is not sourceFile or module block it is local variable for (var parent = declaration.parent; !ts.isFunctionBlock(parent); parent = parent.parent) { // Reached source file or module block if (parent.kind === 269 /* SourceFile */ || parent.kind === 235 /* ModuleBlock */) { return false; } } // parent is in function block return true; }); } })(SymbolDisplay = ts.SymbolDisplay || (ts.SymbolDisplay = {})); })(ts || (ts = {})); var ts; (function (ts) { /* * This function will compile source text from 'input' argument using specified compiler options. * If not options are provided - it will use a set of default compiler options. * Extra compiler options that will unconditionally be used by this function are: * - isolatedModules = true * - allowNonTsExtensions = true * - noLib = true * - noResolve = true */ function transpileModule(input, transpileOptions) { var diagnostics = []; var options = transpileOptions.compilerOptions ? fixupCompilerOptions(transpileOptions.compilerOptions, diagnostics) : ts.getDefaultCompilerOptions(); options.isolatedModules = true; // transpileModule does not write anything to disk so there is no need to verify that there are no conflicts between input and output paths. options.suppressOutputPathCheck = true; // Filename can be non-ts file. options.allowNonTsExtensions = true; // We are not returning a sourceFile for lib file when asked by the program, // so pass --noLib to avoid reporting a file not found error. options.noLib = true; // Clear out other settings that would not be used in transpiling this module options.lib = undefined; options.types = undefined; options.noEmit = undefined; options.noEmitOnError = undefined; options.paths = undefined; options.rootDirs = undefined; options.declaration = undefined; options.declarationDir = undefined; options.out = undefined; options.outFile = undefined; // We are not doing a full typecheck, we are not resolving the whole context, // so pass --noResolve to avoid reporting missing file errors. options.noResolve = true; // if jsx is specified then treat file as .tsx var inputFileName = transpileOptions.fileName || (options.jsx ? "module.tsx" : "module.ts"); var sourceFile = ts.createSourceFile(inputFileName, input, options.target); if (transpileOptions.moduleName) { sourceFile.moduleName = transpileOptions.moduleName; } if (transpileOptions.renamedDependencies) { sourceFile.renamedDependencies = ts.createMapFromTemplate(transpileOptions.renamedDependencies); } var newLine = ts.getNewLineCharacter(options); // Output var outputText; var sourceMapText; // Create a compilerHost object to allow the compiler to read and write files var compilerHost = { getSourceFile: function (fileName) { return fileName === ts.normalizePath(inputFileName) ? sourceFile : undefined; }, writeFile: function (name, text) { if (ts.fileExtensionIs(name, ".map")) { ts.Debug.assertEqual(sourceMapText, undefined, "Unexpected multiple source map outputs, file:", name); sourceMapText = text; } else { ts.Debug.assertEqual(outputText, undefined, "Unexpected multiple outputs, file:", name); outputText = text; } }, getDefaultLibFileName: function () { return "lib.d.ts"; }, useCaseSensitiveFileNames: function () { return false; }, getCanonicalFileName: function (fileName) { return fileName; }, getCurrentDirectory: function () { return ""; }, getNewLine: function () { return newLine; }, fileExists: function (fileName) { return fileName === inputFileName; }, readFile: function () { return ""; }, directoryExists: function () { return true; }, getDirectories: function () { return []; } }; var program = ts.createProgram([inputFileName], options, compilerHost); if (transpileOptions.reportDiagnostics) { ts.addRange(/*to*/ diagnostics, /*from*/ program.getSyntacticDiagnostics(sourceFile)); ts.addRange(/*to*/ diagnostics, /*from*/ program.getOptionsDiagnostics()); } // Emit program.emit(/*targetSourceFile*/ undefined, /*writeFile*/ undefined, /*cancellationToken*/ undefined, /*emitOnlyDtsFiles*/ undefined, transpileOptions.transformers); ts.Debug.assert(outputText !== undefined, "Output generation failed"); return { outputText: outputText, diagnostics: diagnostics, sourceMapText: sourceMapText }; } ts.transpileModule = transpileModule; /* * This is a shortcut function for transpileModule - it accepts transpileOptions as parameters and returns only outputText part of the result. */ function transpile(input, compilerOptions, fileName, diagnostics, moduleName) { var output = transpileModule(input, { compilerOptions: compilerOptions, fileName: fileName, reportDiagnostics: !!diagnostics, moduleName: moduleName }); // addRange correctly handles cases when wither 'from' or 'to' argument is missing ts.addRange(diagnostics, output.diagnostics); return output.outputText; } ts.transpile = transpile; var commandLineOptionsStringToEnum; /** JS users may pass in string values for enum compiler options (such as ModuleKind), so convert. */ /*@internal*/ function fixupCompilerOptions(options, diagnostics) { // Lazily create this value to fix module loading errors. commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || ts.filter(ts.optionDeclarations, function (o) { return typeof o.type === "object" && !ts.forEachEntry(o.type, function (v) { return typeof v !== "number"; }); }); options = ts.cloneCompilerOptions(options); var _loop_9 = function (opt) { if (!ts.hasProperty(options, opt.name)) { return "continue"; } var value = options[opt.name]; // Value should be a key of opt.type if (ts.isString(value)) { // If value is not a string, this will fail options[opt.name] = ts.parseCustomTypeOption(opt, value, diagnostics); } else { if (!ts.forEachEntry(opt.type, function (v) { return v === value; })) { // Supplied value isn't a valid enum value. diagnostics.push(ts.createCompilerDiagnosticForInvalidCustomType(opt)); } } }; for (var _i = 0, commandLineOptionsStringToEnum_1 = commandLineOptionsStringToEnum; _i < commandLineOptionsStringToEnum_1.length; _i++) { var opt = commandLineOptionsStringToEnum_1[_i]; _loop_9(opt); } return options; } ts.fixupCompilerOptions = fixupCompilerOptions; })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { var FormattingRequestKind; (function (FormattingRequestKind) { FormattingRequestKind[FormattingRequestKind["FormatDocument"] = 0] = "FormatDocument"; FormattingRequestKind[FormattingRequestKind["FormatSelection"] = 1] = "FormatSelection"; FormattingRequestKind[FormattingRequestKind["FormatOnEnter"] = 2] = "FormatOnEnter"; FormattingRequestKind[FormattingRequestKind["FormatOnSemicolon"] = 3] = "FormatOnSemicolon"; FormattingRequestKind[FormattingRequestKind["FormatOnOpeningCurlyBrace"] = 4] = "FormatOnOpeningCurlyBrace"; FormattingRequestKind[FormattingRequestKind["FormatOnClosingCurlyBrace"] = 5] = "FormatOnClosingCurlyBrace"; })(FormattingRequestKind = formatting.FormattingRequestKind || (formatting.FormattingRequestKind = {})); var FormattingContext = /** @class */ (function () { function FormattingContext(sourceFile, formattingRequestKind, options) { this.sourceFile = sourceFile; this.formattingRequestKind = formattingRequestKind; this.options = options; } FormattingContext.prototype.updateContext = function (currentRange, currentTokenParent, nextRange, nextTokenParent, commonParent) { ts.Debug.assert(currentRange !== undefined, "currentTokenSpan is null"); ts.Debug.assert(currentTokenParent !== undefined, "currentTokenParent is null"); ts.Debug.assert(nextRange !== undefined, "nextTokenSpan is null"); ts.Debug.assert(nextTokenParent !== undefined, "nextTokenParent is null"); ts.Debug.assert(commonParent !== undefined, "commonParent is null"); this.currentTokenSpan = currentRange; this.currentTokenParent = currentTokenParent; this.nextTokenSpan = nextRange; this.nextTokenParent = nextTokenParent; this.contextNode = commonParent; // drop cached results this.contextNodeAllOnSameLine = undefined; this.nextNodeAllOnSameLine = undefined; this.tokensAreOnSameLine = undefined; this.contextNodeBlockIsOnOneLine = undefined; this.nextNodeBlockIsOnOneLine = undefined; }; FormattingContext.prototype.ContextNodeAllOnSameLine = function () { if (this.contextNodeAllOnSameLine === undefined) { this.contextNodeAllOnSameLine = this.NodeIsOnOneLine(this.contextNode); } return this.contextNodeAllOnSameLine; }; FormattingContext.prototype.NextNodeAllOnSameLine = function () { if (this.nextNodeAllOnSameLine === undefined) { this.nextNodeAllOnSameLine = this.NodeIsOnOneLine(this.nextTokenParent); } return this.nextNodeAllOnSameLine; }; FormattingContext.prototype.TokensAreOnSameLine = function () { if (this.tokensAreOnSameLine === undefined) { var startLine = this.sourceFile.getLineAndCharacterOfPosition(this.currentTokenSpan.pos).line; var endLine = this.sourceFile.getLineAndCharacterOfPosition(this.nextTokenSpan.pos).line; this.tokensAreOnSameLine = (startLine === endLine); } return this.tokensAreOnSameLine; }; FormattingContext.prototype.ContextNodeBlockIsOnOneLine = function () { if (this.contextNodeBlockIsOnOneLine === undefined) { this.contextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.contextNode); } return this.contextNodeBlockIsOnOneLine; }; FormattingContext.prototype.NextNodeBlockIsOnOneLine = function () { if (this.nextNodeBlockIsOnOneLine === undefined) { this.nextNodeBlockIsOnOneLine = this.BlockIsOnOneLine(this.nextTokenParent); } return this.nextNodeBlockIsOnOneLine; }; FormattingContext.prototype.NodeIsOnOneLine = function (node) { var startLine = this.sourceFile.getLineAndCharacterOfPosition(node.getStart(this.sourceFile)).line; var endLine = this.sourceFile.getLineAndCharacterOfPosition(node.getEnd()).line; return startLine === endLine; }; FormattingContext.prototype.BlockIsOnOneLine = function (node) { var openBrace = ts.findChildOfKind(node, 17 /* OpenBraceToken */, this.sourceFile); var closeBrace = ts.findChildOfKind(node, 18 /* CloseBraceToken */, this.sourceFile); if (openBrace && closeBrace) { var startLine = this.sourceFile.getLineAndCharacterOfPosition(openBrace.getEnd()).line; var endLine = this.sourceFile.getLineAndCharacterOfPosition(closeBrace.getStart(this.sourceFile)).line; return startLine === endLine; } return false; }; return FormattingContext; }()); formatting.FormattingContext = FormattingContext; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// /// /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { var standardScanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ false, 0 /* Standard */); var jsxScanner = ts.createScanner(6 /* Latest */, /*skipTrivia*/ false, 1 /* JSX */); var ScanAction; (function (ScanAction) { ScanAction[ScanAction["Scan"] = 0] = "Scan"; ScanAction[ScanAction["RescanGreaterThanToken"] = 1] = "RescanGreaterThanToken"; ScanAction[ScanAction["RescanSlashToken"] = 2] = "RescanSlashToken"; ScanAction[ScanAction["RescanTemplateToken"] = 3] = "RescanTemplateToken"; ScanAction[ScanAction["RescanJsxIdentifier"] = 4] = "RescanJsxIdentifier"; ScanAction[ScanAction["RescanJsxText"] = 5] = "RescanJsxText"; })(ScanAction || (ScanAction = {})); function getFormattingScanner(text, languageVariant, startPos, endPos, cb) { var scanner = languageVariant === 1 /* JSX */ ? jsxScanner : standardScanner; scanner.setText(text); scanner.setTextPos(startPos); var wasNewLine = true; var leadingTrivia; var trailingTrivia; var savedPos; var lastScanAction; var lastTokenInfo; var res = cb({ advance: advance, readTokenInfo: readTokenInfo, isOnToken: isOnToken, getCurrentLeadingTrivia: function () { return leadingTrivia; }, lastTrailingTriviaWasNewLine: function () { return wasNewLine; }, skipToEndOf: skipToEndOf, }); lastTokenInfo = undefined; scanner.setText(undefined); return res; function advance() { lastTokenInfo = undefined; var isStarted = scanner.getStartPos() !== startPos; if (isStarted) { wasNewLine = trailingTrivia && ts.lastOrUndefined(trailingTrivia).kind === 4 /* NewLineTrivia */; } else { scanner.scan(); } leadingTrivia = undefined; trailingTrivia = undefined; var pos = scanner.getStartPos(); // Read leading trivia and token while (pos < endPos) { var t = scanner.getToken(); if (!ts.isTrivia(t)) { break; } // consume leading trivia scanner.scan(); var item = { pos: pos, end: scanner.getStartPos(), kind: t }; pos = scanner.getStartPos(); leadingTrivia = ts.append(leadingTrivia, item); } savedPos = scanner.getStartPos(); } function shouldRescanGreaterThanToken(node) { switch (node.kind) { case 31 /* GreaterThanEqualsToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: case 46 /* GreaterThanGreaterThanToken */: return true; } return false; } function shouldRescanJsxIdentifier(node) { if (node.parent) { switch (node.parent.kind) { case 257 /* JsxAttribute */: case 252 /* JsxOpeningElement */: case 253 /* JsxClosingElement */: case 251 /* JsxSelfClosingElement */: // May parse an identifier like `module-layout`; that will be scanned as a keyword at first, but we should parse the whole thing to get an identifier. return ts.isKeyword(node.kind) || node.kind === 71 /* Identifier */; } } return false; } function shouldRescanJsxText(node) { return node.kind === 10 /* JsxText */; } function shouldRescanSlashToken(container) { return container.kind === 12 /* RegularExpressionLiteral */; } function shouldRescanTemplateToken(container) { return container.kind === 15 /* TemplateMiddle */ || container.kind === 16 /* TemplateTail */; } function startsWithSlashToken(t) { return t === 41 /* SlashToken */ || t === 63 /* SlashEqualsToken */; } function readTokenInfo(n) { ts.Debug.assert(isOnToken()); // normally scanner returns the smallest available token // check the kind of context node to determine if scanner should have more greedy behavior and consume more text. var expectedScanAction = shouldRescanGreaterThanToken(n) ? 1 /* RescanGreaterThanToken */ : shouldRescanSlashToken(n) ? 2 /* RescanSlashToken */ : shouldRescanTemplateToken(n) ? 3 /* RescanTemplateToken */ : shouldRescanJsxIdentifier(n) ? 4 /* RescanJsxIdentifier */ : shouldRescanJsxText(n) ? 5 /* RescanJsxText */ : 0 /* Scan */; if (lastTokenInfo && expectedScanAction === lastScanAction) { // readTokenInfo was called before with the same expected scan action. // No need to re-scan text, return existing 'lastTokenInfo' // it is ok to call fixTokenKind here since it does not affect // what portion of text is consumed. In contrast rescanning can change it, // i.e. for '>=' when originally scanner eats just one character // and rescanning forces it to consume more. return fixTokenKind(lastTokenInfo, n); } if (scanner.getStartPos() !== savedPos) { ts.Debug.assert(lastTokenInfo !== undefined); // readTokenInfo was called before but scan action differs - rescan text scanner.setTextPos(savedPos); scanner.scan(); } var currentToken = getNextToken(n, expectedScanAction); var token = { pos: scanner.getStartPos(), end: scanner.getTextPos(), kind: currentToken }; // consume trailing trivia if (trailingTrivia) { trailingTrivia = undefined; } while (scanner.getStartPos() < endPos) { currentToken = scanner.scan(); if (!ts.isTrivia(currentToken)) { break; } var trivia = { pos: scanner.getStartPos(), end: scanner.getTextPos(), kind: currentToken }; if (!trailingTrivia) { trailingTrivia = []; } trailingTrivia.push(trivia); if (currentToken === 4 /* NewLineTrivia */) { // move past new line scanner.scan(); break; } } lastTokenInfo = { leadingTrivia: leadingTrivia, trailingTrivia: trailingTrivia, token: token }; return fixTokenKind(lastTokenInfo, n); } function getNextToken(n, expectedScanAction) { var token = scanner.getToken(); lastScanAction = 0 /* Scan */; switch (expectedScanAction) { case 1 /* RescanGreaterThanToken */: if (token === 29 /* GreaterThanToken */) { lastScanAction = 1 /* RescanGreaterThanToken */; var newToken = scanner.reScanGreaterToken(); ts.Debug.assert(n.kind === newToken); return newToken; } break; case 2 /* RescanSlashToken */: if (startsWithSlashToken(token)) { lastScanAction = 2 /* RescanSlashToken */; var newToken = scanner.reScanSlashToken(); ts.Debug.assert(n.kind === newToken); return newToken; } break; case 3 /* RescanTemplateToken */: if (token === 18 /* CloseBraceToken */) { lastScanAction = 3 /* RescanTemplateToken */; return scanner.reScanTemplateToken(); } break; case 4 /* RescanJsxIdentifier */: lastScanAction = 4 /* RescanJsxIdentifier */; return scanner.scanJsxIdentifier(); case 5 /* RescanJsxText */: lastScanAction = 5 /* RescanJsxText */; return scanner.reScanJsxToken(); case 0 /* Scan */: break; default: ts.Debug.assertNever(expectedScanAction); } return token; } function isOnToken() { var current = lastTokenInfo ? lastTokenInfo.token.kind : scanner.getToken(); var startPos = lastTokenInfo ? lastTokenInfo.token.pos : scanner.getStartPos(); return startPos < endPos && current !== 1 /* EndOfFileToken */ && !ts.isTrivia(current); } // when containing node in the tree is token // but its kind differs from the kind that was returned by the scanner, // then kind needs to be fixed. This might happen in cases // when parser interprets token differently, i.e keyword treated as identifier function fixTokenKind(tokenInfo, container) { if (ts.isToken(container) && tokenInfo.token.kind !== container.kind) { tokenInfo.token.kind = container.kind; } return tokenInfo; } function skipToEndOf(node) { scanner.setTextPos(node.end); savedPos = scanner.getStartPos(); lastScanAction = undefined; lastTokenInfo = undefined; wasNewLine = false; leadingTrivia = undefined; trailingTrivia = undefined; } } formatting.getFormattingScanner = getFormattingScanner; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { formatting.anyContext = ts.emptyArray; var RuleAction; (function (RuleAction) { RuleAction[RuleAction["Ignore"] = 1] = "Ignore"; RuleAction[RuleAction["Space"] = 2] = "Space"; RuleAction[RuleAction["NewLine"] = 4] = "NewLine"; RuleAction[RuleAction["Delete"] = 8] = "Delete"; })(RuleAction = formatting.RuleAction || (formatting.RuleAction = {})); var RuleFlags; (function (RuleFlags) { RuleFlags[RuleFlags["None"] = 0] = "None"; RuleFlags[RuleFlags["CanDeleteNewLines"] = 1] = "CanDeleteNewLines"; })(RuleFlags = formatting.RuleFlags || (formatting.RuleFlags = {})); })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { function getAllRules() { var allTokens = []; for (var token = 0 /* FirstToken */; token <= 143 /* LastToken */; token++) { allTokens.push(token); } function anyTokenExcept(token) { return { tokens: allTokens.filter(function (t) { return t !== token; }), isSpecific: false }; } var anyToken = { tokens: allTokens, isSpecific: false }; var anyTokenIncludingMultilineComments = tokenRangeFrom(allTokens.concat([3 /* MultiLineCommentTrivia */])); var keywords = tokenRangeFromRange(72 /* FirstKeyword */, 143 /* LastKeyword */); var binaryOperators = tokenRangeFromRange(27 /* FirstBinaryOperator */, 70 /* LastBinaryOperator */); var binaryKeywordOperators = [92 /* InKeyword */, 93 /* InstanceOfKeyword */, 143 /* OfKeyword */, 118 /* AsKeyword */, 126 /* IsKeyword */]; var unaryPrefixOperators = [43 /* PlusPlusToken */, 44 /* MinusMinusToken */, 52 /* TildeToken */, 51 /* ExclamationToken */]; var unaryPrefixExpressions = [ 8 /* NumericLiteral */, 71 /* Identifier */, 19 /* OpenParenToken */, 21 /* OpenBracketToken */, 17 /* OpenBraceToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */ ]; var unaryPreincrementExpressions = [71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */]; var unaryPostincrementExpressions = [71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */]; var unaryPredecrementExpressions = [71 /* Identifier */, 19 /* OpenParenToken */, 99 /* ThisKeyword */, 94 /* NewKeyword */]; var unaryPostdecrementExpressions = [71 /* Identifier */, 20 /* CloseParenToken */, 22 /* CloseBracketToken */, 94 /* NewKeyword */]; var comments = [2 /* SingleLineCommentTrivia */, 3 /* MultiLineCommentTrivia */]; var typeNames = [71 /* Identifier */].concat(ts.typeKeywords); // Place a space before open brace in a function declaration // TypeScript: Function can have return types, which can be made of tons of different token kinds var functionOpenBraceLeftTokenRange = anyTokenIncludingMultilineComments; // Place a space before open brace in a TypeScript declaration that has braces as children (class, module, enum, etc) var typeScriptOpenBraceLeftTokenRange = tokenRangeFrom([71 /* Identifier */, 3 /* MultiLineCommentTrivia */, 75 /* ClassKeyword */, 84 /* ExportKeyword */, 91 /* ImportKeyword */]); // Place a space before open brace in a control flow construct var controlOpenBraceLeftTokenRange = tokenRangeFrom([20 /* CloseParenToken */, 3 /* MultiLineCommentTrivia */, 81 /* DoKeyword */, 102 /* TryKeyword */, 87 /* FinallyKeyword */, 82 /* ElseKeyword */]); // These rules are higher in priority than user-configurable var highPriorityCommonRules = [ // Leave comments alone rule("IgnoreBeforeComment", anyToken, comments, formatting.anyContext, 1 /* Ignore */), rule("IgnoreAfterLineComment", 2 /* SingleLineCommentTrivia */, anyToken, formatting.anyContext, 1 /* Ignore */), rule("NoSpaceBeforeColon", anyToken, 56 /* ColonToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */), rule("SpaceAfterColon", 56 /* ColonToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 2 /* Space */), rule("NoSpaceBeforeQuestionMark", anyToken, 55 /* QuestionToken */, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */), // insert space after '?' only when it is used in conditional operator rule("SpaceAfterQuestionMarkInConditionalOperator", 55 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext, isConditionalOperatorContext], 2 /* Space */), // in other cases there should be no space between '?' and next token rule("NoSpaceAfterQuestionMark", 55 /* QuestionToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeDot", anyToken, 23 /* DotToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterDot", 23 /* DotToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */), // Special handling of unary operators. // Prefix operators generally shouldn't have a space between // them and their target unary expression. rule("NoSpaceAfterUnaryPrefixOperator", unaryPrefixOperators, unaryPrefixExpressions, [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */), rule("NoSpaceAfterUnaryPreincrementOperator", 43 /* PlusPlusToken */, unaryPreincrementExpressions, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterUnaryPredecrementOperator", 44 /* MinusMinusToken */, unaryPredecrementExpressions, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeUnaryPostincrementOperator", unaryPostincrementExpressions, 43 /* PlusPlusToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeUnaryPostdecrementOperator", unaryPostdecrementExpressions, 44 /* MinusMinusToken */, [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 rule("SpaceAfterPostincrementWhenFollowedByAdd", 43 /* PlusPlusToken */, 37 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterAddWhenFollowedByUnaryPlus", 37 /* PlusToken */, 37 /* PlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterAddWhenFollowedByPreincrement", 37 /* PlusToken */, 43 /* PlusPlusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterPostdecrementWhenFollowedBySubtract", 44 /* MinusMinusToken */, 38 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterSubtractWhenFollowedByUnaryMinus", 38 /* MinusToken */, 38 /* MinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterSubtractWhenFollowedByPredecrement", 38 /* MinusToken */, 44 /* MinusMinusToken */, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("NoSpaceAfterCloseBrace", 18 /* CloseBraceToken */, [22 /* CloseBracketToken */, 26 /* CommaToken */, 25 /* SemicolonToken */], [isNonJsxSameLineTokenContext], 8 /* Delete */), // For functions and control block place } on a new line [multi-line rule] rule("NewLineBeforeCloseBraceInBlockContext", anyTokenIncludingMultilineComments, 18 /* CloseBraceToken */, [isMultilineBlockContext], 4 /* NewLine */), // Space/new line after }. rule("SpaceAfterCloseBrace", 18 /* CloseBraceToken */, anyTokenExcept(20 /* CloseParenToken */), [isNonJsxSameLineTokenContext, 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 // Also should not apply to }) rule("SpaceBetweenCloseBraceAndElse", 18 /* CloseBraceToken */, 82 /* ElseKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBetweenCloseBraceAndWhile", 18 /* CloseBraceToken */, 106 /* WhileKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceBetweenEmptyBraceBrackets", 17 /* OpenBraceToken */, 18 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 8 /* Delete */), rule("NoSpaceBetweenFunctionKeywordAndStar", 89 /* FunctionKeyword */, 39 /* AsteriskToken */, [isFunctionDeclarationOrFunctionExpressionContext], 8 /* Delete */), rule("SpaceAfterStarInGeneratorDeclaration", 39 /* AsteriskToken */, [71 /* Identifier */, 19 /* OpenParenToken */], [isFunctionDeclarationOrFunctionExpressionContext], 2 /* Space */), rule("SpaceAfterFunctionInFuncDecl", 89 /* FunctionKeyword */, anyToken, [isFunctionDeclContext], 2 /* Space */), // Insert new line after { and before } in multi-line contexts. rule("NewLineAfterOpenBraceInBlockContext", 17 /* OpenBraceToken */, anyToken, [isMultilineBlockContext], 4 /* NewLine */), // For get/set members, we check for (identifier,identifier) since get/set don't have tokens and they are represented as just an identifier token. // Though, we do extra check on the context to make sure we are dealing with get/set node. Example: // get x() {} // set x(val) {} rule("SpaceAfterGetSetInMember", [125 /* GetKeyword */, 135 /* SetKeyword */], 71 /* Identifier */, [isFunctionDeclContext], 2 /* Space */), rule("NoSpaceBetweenYieldKeywordAndStar", 116 /* YieldKeyword */, 39 /* AsteriskToken */, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 8 /* Delete */), rule("SpaceBetweenYieldOrYieldStarAndOperand", [116 /* YieldKeyword */, 39 /* AsteriskToken */], anyToken, [isNonJsxSameLineTokenContext, isYieldOrYieldStarWithOperand], 2 /* Space */), rule("NoSpaceBetweenReturnAndSemicolon", 96 /* ReturnKeyword */, 25 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("SpaceAfterCertainKeywords", [104 /* VarKeyword */, 100 /* ThrowKeyword */, 94 /* NewKeyword */, 80 /* DeleteKeyword */, 96 /* ReturnKeyword */, 103 /* TypeOfKeyword */, 121 /* AwaitKeyword */], anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceAfterLetConstInVariableDeclaration", [110 /* LetKeyword */, 76 /* ConstKeyword */], anyToken, [isNonJsxSameLineTokenContext, isStartOfVariableDeclarationList], 2 /* Space */), rule("NoSpaceBeforeOpenParenInFuncCall", anyToken, 19 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isFunctionCallOrNewContext, isPreviousTokenNotComma], 8 /* Delete */), // Special case for binary operators (that are keywords). For these we have to add a space and shouldn't follow any user options. rule("SpaceBeforeBinaryKeywordOperator", anyToken, binaryKeywordOperators, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterBinaryKeywordOperator", binaryKeywordOperators, anyToken, [isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterVoidOperator", 105 /* VoidKeyword */, anyToken, [isNonJsxSameLineTokenContext, isVoidOpContext], 2 /* Space */), // Async-await rule("SpaceBetweenAsyncAndOpenParen", 120 /* AsyncKeyword */, 19 /* OpenParenToken */, [isArrowFunctionContext, isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBetweenAsyncAndFunctionKeyword", 120 /* AsyncKeyword */, 89 /* FunctionKeyword */, [isNonJsxSameLineTokenContext], 2 /* Space */), // template string rule("NoSpaceBetweenTagAndTemplateString", 71 /* Identifier */, [13 /* NoSubstitutionTemplateLiteral */, 14 /* TemplateHead */], [isNonJsxSameLineTokenContext], 8 /* Delete */), // JSX opening elements rule("SpaceBeforeJsxAttribute", anyToken, 71 /* Identifier */, [isNextTokenParentJsxAttribute, isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBeforeSlashInJsxOpeningElement", anyToken, 41 /* SlashToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceBeforeGreaterThanTokenInJsxOpeningElement", 41 /* SlashToken */, 29 /* GreaterThanToken */, [isJsxSelfClosingElementContext, isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeEqualInJsxAttribute", anyToken, 58 /* EqualsToken */, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterEqualInJsxAttribute", 58 /* EqualsToken */, anyToken, [isJsxAttributeContext, isNonJsxSameLineTokenContext], 8 /* Delete */), // TypeScript-specific rules // Use of module as a function call. e.g.: import m2 = module("m2"); rule("NoSpaceAfterModuleImport", [128 /* ModuleKeyword */, 132 /* RequireKeyword */], 19 /* OpenParenToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), // Add a space around certain TypeScript keywords rule("SpaceAfterCertainTypeScriptKeywords", [ 117 /* AbstractKeyword */, 75 /* ClassKeyword */, 124 /* DeclareKeyword */, 79 /* DefaultKeyword */, 83 /* EnumKeyword */, 84 /* ExportKeyword */, 85 /* ExtendsKeyword */, 125 /* GetKeyword */, 108 /* ImplementsKeyword */, 91 /* ImportKeyword */, 109 /* InterfaceKeyword */, 128 /* ModuleKeyword */, 129 /* NamespaceKeyword */, 112 /* PrivateKeyword */, 114 /* PublicKeyword */, 113 /* ProtectedKeyword */, 131 /* ReadonlyKeyword */, 135 /* SetKeyword */, 115 /* StaticKeyword */, 138 /* TypeKeyword */, 141 /* FromKeyword */, 127 /* KeyOfKeyword */, ], anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBeforeCertainTypeScriptKeywords", anyToken, [85 /* ExtendsKeyword */, 108 /* ImplementsKeyword */, 141 /* FromKeyword */], [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" { rule("SpaceAfterModuleName", 9 /* StringLiteral */, 17 /* OpenBraceToken */, [isModuleDeclContext], 2 /* Space */), // Lambda expressions rule("SpaceBeforeArrow", anyToken, 36 /* EqualsGreaterThanToken */, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceAfterArrow", 36 /* EqualsGreaterThanToken */, anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */), // Optional parameters and let args rule("NoSpaceAfterEllipsis", 24 /* DotDotDotToken */, 71 /* Identifier */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterOptionalParameters", 55 /* QuestionToken */, [20 /* CloseParenToken */, 26 /* CommaToken */], [isNonJsxSameLineTokenContext, isNotBinaryOpContext], 8 /* Delete */), // Remove spaces in empty interface literals. e.g.: x: {} rule("NoSpaceBetweenEmptyInterfaceBraceBrackets", 17 /* OpenBraceToken */, 18 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectTypeContext], 8 /* Delete */), // generics and type assertions rule("NoSpaceBeforeOpenAngularBracket", typeNames, 27 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */), rule("NoSpaceBetweenCloseParenAndAngularBracket", 20 /* CloseParenToken */, 27 /* LessThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */), rule("NoSpaceAfterOpenAngularBracket", 27 /* LessThanToken */, anyToken, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */), rule("NoSpaceBeforeCloseAngularBracket", anyToken, 29 /* GreaterThanToken */, [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */), rule("NoSpaceAfterCloseAngularBracket", 29 /* GreaterThanToken */, [19 /* OpenParenToken */, 21 /* OpenBracketToken */, 29 /* GreaterThanToken */, 26 /* CommaToken */], [isNonJsxSameLineTokenContext, isTypeArgumentOrParameterOrAssertionContext], 8 /* Delete */), // decorators rule("SpaceBeforeAt", anyToken, 57 /* AtToken */, [isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceAfterAt", 57 /* AtToken */, anyToken, [isNonJsxSameLineTokenContext], 8 /* Delete */), // Insert space after @ in decorator rule("SpaceAfterDecorator", anyToken, [ 117 /* AbstractKeyword */, 71 /* Identifier */, 84 /* ExportKeyword */, 79 /* DefaultKeyword */, 75 /* ClassKeyword */, 115 /* StaticKeyword */, 114 /* PublicKeyword */, 112 /* PrivateKeyword */, 113 /* ProtectedKeyword */, 125 /* GetKeyword */, 135 /* SetKeyword */, 21 /* OpenBracketToken */, 39 /* AsteriskToken */, ], [isEndOfDecoratorContextOnSameLine], 2 /* Space */), rule("NoSpaceBeforeNonNullAssertionOperator", anyToken, 51 /* ExclamationToken */, [isNonJsxSameLineTokenContext, isNonNullAssertionContext], 8 /* Delete */), rule("NoSpaceAfterNewKeywordOnConstructorSignature", 94 /* NewKeyword */, 19 /* OpenParenToken */, [isNonJsxSameLineTokenContext, isConstructorSignatureContext], 8 /* Delete */), ]; // These rules are applied after high priority var userConfigurableRules = [ // Treat constructor as an identifier in a function declaration, and remove spaces between constructor and following left parentheses rule("SpaceAfterConstructor", 123 /* ConstructorKeyword */, 19 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceAfterConstructor", 123 /* ConstructorKeyword */, 19 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], 8 /* Delete */), rule("SpaceAfterComma", 26 /* CommaToken */, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], 2 /* Space */), rule("NoSpaceAfterComma", 26 /* CommaToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], 8 /* Delete */), // Insert space after function keyword for anonymous functions rule("SpaceAfterAnonymousFunctionKeyword", 89 /* FunctionKeyword */, 19 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 2 /* Space */), rule("NoSpaceAfterAnonymousFunctionKeyword", 89 /* FunctionKeyword */, 19 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], 8 /* Delete */), // Insert space after keywords in control flow statements rule("SpaceAfterKeywordInControl", keywords, 19 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 2 /* Space */), rule("NoSpaceAfterKeywordInControl", keywords, 19 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterKeywordsInControlFlowStatements"), isControlDeclContext], 8 /* Delete */), // Insert space after opening and before closing nonempty parenthesis rule("SpaceAfterOpenParen", 19 /* OpenParenToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBeforeCloseParen", anyToken, 20 /* CloseParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBetweenOpenParens", 19 /* OpenParenToken */, 19 /* OpenParenToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceBetweenParens", 19 /* OpenParenToken */, 20 /* CloseParenToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterOpenParen", 19 /* OpenParenToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeCloseParen", anyToken, 20 /* CloseParenToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis"), isNonJsxSameLineTokenContext], 8 /* Delete */), // Insert space after opening and before closing nonempty brackets rule("SpaceAfterOpenBracket", 21 /* OpenBracketToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBeforeCloseBracket", anyToken, 22 /* CloseBracketToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceBetweenBrackets", 21 /* OpenBracketToken */, 22 /* CloseBracketToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterOpenBracket", 21 /* OpenBracketToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeCloseBracket", anyToken, 22 /* CloseBracketToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets"), isNonJsxSameLineTokenContext], 8 /* Delete */), // Insert a space after { and before } in single-line contexts, but remove space from empty object literals {}. rule("SpaceAfterOpenBrace", 17 /* OpenBraceToken */, anyToken, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 2 /* Space */), rule("SpaceBeforeCloseBrace", anyToken, 18 /* CloseBraceToken */, [isOptionEnabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isBraceWrappedContext], 2 /* Space */), rule("NoSpaceBetweenEmptyBraceBrackets", 17 /* OpenBraceToken */, 18 /* CloseBraceToken */, [isNonJsxSameLineTokenContext, isObjectContext], 8 /* Delete */), rule("NoSpaceAfterOpenBrace", 17 /* OpenBraceToken */, anyToken, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeCloseBrace", anyToken, 18 /* CloseBraceToken */, [isOptionDisabled("insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */), // Insert space after opening and before closing template string braces rule("SpaceAfterTemplateHeadAndMiddle", [14 /* TemplateHead */, 15 /* TemplateMiddle */], anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("SpaceBeforeTemplateMiddleAndTail", anyToken, [15 /* TemplateMiddle */, 16 /* TemplateTail */], [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 2 /* Space */), rule("NoSpaceAfterTemplateHeadAndMiddle", [14 /* TemplateHead */, 15 /* TemplateMiddle */], anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceBeforeTemplateMiddleAndTail", anyToken, [15 /* TemplateMiddle */, 16 /* TemplateTail */], [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces"), isNonJsxSameLineTokenContext], 8 /* Delete */), // No space after { and before } in JSX expression rule("SpaceAfterOpenBraceInJsxExpression", 17 /* OpenBraceToken */, anyToken, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 2 /* Space */), rule("SpaceBeforeCloseBraceInJsxExpression", anyToken, 18 /* CloseBraceToken */, [isOptionEnabled("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 2 /* Space */), rule("NoSpaceAfterOpenBraceInJsxExpression", 17 /* OpenBraceToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 8 /* Delete */), rule("NoSpaceBeforeCloseBraceInJsxExpression", anyToken, 18 /* CloseBraceToken */, [isOptionDisabledOrUndefined("insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces"), isNonJsxSameLineTokenContext, isJsxExpressionContext], 8 /* Delete */), // Insert space after semicolon in for statement rule("SpaceAfterSemicolonInFor", 25 /* SemicolonToken */, anyToken, [isOptionEnabled("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 2 /* Space */), rule("NoSpaceAfterSemicolonInFor", 25 /* SemicolonToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterSemicolonInForStatements"), isNonJsxSameLineTokenContext, isForContext], 8 /* Delete */), // Insert space before and after binary operators rule("SpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("SpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionEnabled("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 2 /* Space */), rule("NoSpaceBeforeBinaryOperator", anyToken, binaryOperators, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 8 /* Delete */), rule("NoSpaceAfterBinaryOperator", binaryOperators, anyToken, [isOptionDisabledOrUndefined("insertSpaceBeforeAndAfterBinaryOperators"), isNonJsxSameLineTokenContext, isBinaryOpContext], 8 /* Delete */), rule("SpaceBeforeOpenParenInFuncDecl", anyToken, 19 /* OpenParenToken */, [isOptionEnabled("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 2 /* Space */), rule("NoSpaceBeforeOpenParenInFuncDecl", anyToken, 19 /* OpenParenToken */, [isOptionDisabledOrUndefined("insertSpaceBeforeFunctionParenthesis"), isNonJsxSameLineTokenContext, isFunctionDeclContext], 8 /* Delete */), // Open Brace braces after control block rule("NewLineBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */), // Open Brace braces after function // TypeScript: Function can have return types, which can be made of tons of different token kinds rule("NewLineBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */), // Open Brace braces after TypeScript module/class/interface rule("NewLineBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionEnabled("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isBeforeMultilineBlockContext], 4 /* NewLine */, 1 /* CanDeleteNewLines */), rule("SpaceAfterTypeAssertion", 29 /* GreaterThanToken */, anyToken, [isOptionEnabled("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 2 /* Space */), rule("NoSpaceAfterTypeAssertion", 29 /* GreaterThanToken */, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterTypeAssertion"), isNonJsxSameLineTokenContext, isTypeAssertionContext], 8 /* Delete */), ]; // These rules are lower in priority than user-configurable var lowPriorityCommonRules = [ // Space after keyword but not before ; or : or ? rule("NoSpaceBeforeSemicolon", anyToken, 25 /* SemicolonToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("SpaceBeforeOpenBraceInControl", controlOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForControlBlocks"), isControlDeclContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */), rule("SpaceBeforeOpenBraceInFunction", functionOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isFunctionDeclContext, isBeforeBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */), rule("SpaceBeforeOpenBraceInTypeScriptDeclWithBlock", typeScriptOpenBraceLeftTokenRange, 17 /* OpenBraceToken */, [isOptionDisabledOrUndefinedOrTokensOnSameLine("placeOpenBraceOnNewLineForFunctions"), isTypeScriptDeclWithBlockContext, isNotFormatOnEnter, isSameLineTokenOrBeforeBlockContext], 2 /* Space */, 1 /* CanDeleteNewLines */), rule("NoSpaceBeforeComma", anyToken, 26 /* CommaToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), // No space before and after indexer rule("NoSpaceBeforeOpenBracket", anyTokenExcept(120 /* AsyncKeyword */), 21 /* OpenBracketToken */, [isNonJsxSameLineTokenContext], 8 /* Delete */), rule("NoSpaceAfterCloseBracket", 22 /* CloseBracketToken */, anyToken, [isNonJsxSameLineTokenContext, isNotBeforeBlockInFunctionDeclarationContext], 8 /* Delete */), rule("SpaceAfterSemicolon", 25 /* SemicolonToken */, anyToken, [isNonJsxSameLineTokenContext], 2 /* Space */), // 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] rule("SpaceBetweenStatements", [20 /* CloseParenToken */, 81 /* DoKeyword */, 82 /* ElseKeyword */, 73 /* CaseKeyword */], anyToken, [isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext], 2 /* Space */), // This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter. rule("SpaceAfterTryFinally", [102 /* TryKeyword */, 87 /* FinallyKeyword */], 17 /* OpenBraceToken */, [isNonJsxSameLineTokenContext], 2 /* Space */), ]; return highPriorityCommonRules.concat(userConfigurableRules, lowPriorityCommonRules); } formatting.getAllRules = getAllRules; function rule(debugName, left, right, context, action, flags) { if (flags === void 0) { flags = 0 /* None */; } return { leftTokenRange: toTokenRange(left), rightTokenRange: toTokenRange(right), rule: { debugName: debugName, context: context, action: action, flags: flags } }; } function tokenRangeFrom(tokens) { return { tokens: tokens, isSpecific: true }; } function toTokenRange(arg) { return typeof arg === "number" ? tokenRangeFrom([arg]) : ts.isArray(arg) ? tokenRangeFrom(arg) : arg; } function tokenRangeFromRange(from, to, except) { if (except === void 0) { except = []; } var tokens = []; for (var token = from; token <= to; token++) { if (!ts.contains(except, token)) { tokens.push(token); } } return tokenRangeFrom(tokens); } /// /// Contexts /// function isOptionEnabled(optionName) { return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !!context.options[optionName]; }; } function isOptionDisabled(optionName) { return function (context) { return context.options && context.options.hasOwnProperty(optionName) && !context.options[optionName]; }; } function isOptionDisabledOrUndefined(optionName) { return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName]; }; } function isOptionDisabledOrUndefinedOrTokensOnSameLine(optionName) { return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !context.options[optionName] || context.TokensAreOnSameLine(); }; } function isOptionEnabledOrUndefined(optionName) { return function (context) { return !context.options || !context.options.hasOwnProperty(optionName) || !!context.options[optionName]; }; } function isForContext(context) { return context.contextNode.kind === 215 /* ForStatement */; } function isNotForContext(context) { return !isForContext(context); } function isBinaryOpContext(context) { switch (context.contextNode.kind) { case 195 /* BinaryExpression */: case 196 /* ConditionalExpression */: case 203 /* AsExpression */: case 247 /* ExportSpecifier */: case 243 /* ImportSpecifier */: case 159 /* TypePredicate */: case 167 /* UnionType */: case 168 /* IntersectionType */: return true; // equals in binding elements: function foo([[x, y] = [1, 2]]) case 177 /* BindingElement */: // equals in type X = ... case 232 /* TypeAliasDeclaration */: // equal in import a = module('a'); case 238 /* ImportEqualsDeclaration */: // equal in let a = 0; case 227 /* VariableDeclaration */: // equal in p = 0; case 147 /* Parameter */: case 268 /* EnumMember */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: return context.currentTokenSpan.kind === 58 /* EqualsToken */ || context.nextTokenSpan.kind === 58 /* EqualsToken */; // "in" keyword in for (let x in []) { } case 216 /* ForInStatement */: // "in" keyword in [P in keyof T]: T[P] case 146 /* TypeParameter */: return context.currentTokenSpan.kind === 92 /* InKeyword */ || context.nextTokenSpan.kind === 92 /* InKeyword */; // Technically, "of" is not a binary operator, but format it the same way as "in" case 217 /* ForOfStatement */: return context.currentTokenSpan.kind === 143 /* OfKeyword */ || context.nextTokenSpan.kind === 143 /* OfKeyword */; } return false; } function isNotBinaryOpContext(context) { return !isBinaryOpContext(context); } function isConditionalOperatorContext(context) { return context.contextNode.kind === 196 /* ConditionalExpression */; } function isSameLineTokenOrBeforeBlockContext(context) { return context.TokensAreOnSameLine() || isBeforeBlockContext(context); } function isBraceWrappedContext(context) { return context.contextNode.kind === 175 /* ObjectBindingPattern */ || isSingleLineBlockContext(context); } // This check is done before an open brace in a control construct, a function, or a typescript block declaration function isBeforeMultilineBlockContext(context) { return isBeforeBlockContext(context) && !(context.NextNodeAllOnSameLine() || context.NextNodeBlockIsOnOneLine()); } function isMultilineBlockContext(context) { return isBlockContext(context) && !(context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); } function isSingleLineBlockContext(context) { return isBlockContext(context) && (context.ContextNodeAllOnSameLine() || context.ContextNodeBlockIsOnOneLine()); } function isBlockContext(context) { return nodeIsBlockContext(context.contextNode); } function isBeforeBlockContext(context) { return nodeIsBlockContext(context.nextTokenParent); } // IMPORTANT!!! This method must return true ONLY for nodes with open and close braces as immediate children function nodeIsBlockContext(node) { if (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 208 /* Block */: case 236 /* CaseBlock */: case 179 /* ObjectLiteralExpression */: case 235 /* ModuleBlock */: return true; } return false; } function isFunctionDeclContext(context) { switch (context.contextNode.kind) { case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: // case SyntaxKind.MemberFunctionDeclaration: case 154 /* GetAccessor */: case 155 /* SetAccessor */: // case SyntaxKind.MethodSignature: case 156 /* CallSignature */: case 187 /* FunctionExpression */: case 153 /* Constructor */: case 188 /* ArrowFunction */: // case SyntaxKind.ConstructorDeclaration: // case SyntaxKind.SimpleArrowFunctionExpression: // case SyntaxKind.ParenthesizedArrowFunctionExpression: case 231 /* InterfaceDeclaration */:// This one is not truly a function, but for formatting purposes, it acts just like one return true; } return false; } function isFunctionDeclarationOrFunctionExpressionContext(context) { return context.contextNode.kind === 229 /* FunctionDeclaration */ || context.contextNode.kind === 187 /* FunctionExpression */; } function isTypeScriptDeclWithBlockContext(context) { return nodeIsTypeScriptDeclWithBlockContext(context.contextNode); } function nodeIsTypeScriptDeclWithBlockContext(node) { switch (node.kind) { case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 164 /* TypeLiteral */: case 234 /* ModuleDeclaration */: case 245 /* ExportDeclaration */: case 246 /* NamedExports */: case 239 /* ImportDeclaration */: case 242 /* NamedImports */: return true; } return false; } function isAfterCodeBlockContext(context) { switch (context.currentTokenParent.kind) { case 230 /* ClassDeclaration */: case 234 /* ModuleDeclaration */: case 233 /* EnumDeclaration */: case 264 /* CatchClause */: case 235 /* ModuleBlock */: case 222 /* SwitchStatement */: return true; case 208 /* Block */: { var blockParent = context.currentTokenParent.parent; // In a codefix scenario, we can't rely on parents being set. So just always return true. if (!blockParent || blockParent.kind !== 188 /* ArrowFunction */ && blockParent.kind !== 187 /* FunctionExpression */) { return true; } } } return false; } function isControlDeclContext(context) { switch (context.contextNode.kind) { case 212 /* IfStatement */: case 222 /* SwitchStatement */: case 215 /* ForStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 214 /* WhileStatement */: case 225 /* TryStatement */: case 213 /* DoStatement */: case 221 /* WithStatement */: // TODO // case SyntaxKind.ElseClause: case 264 /* CatchClause */: return true; default: return false; } } function isObjectContext(context) { return context.contextNode.kind === 179 /* ObjectLiteralExpression */; } function isFunctionCallContext(context) { return context.contextNode.kind === 182 /* CallExpression */; } function isNewContext(context) { return context.contextNode.kind === 183 /* NewExpression */; } function isFunctionCallOrNewContext(context) { return isFunctionCallContext(context) || isNewContext(context); } function isPreviousTokenNotComma(context) { return context.currentTokenSpan.kind !== 26 /* CommaToken */; } function isNextTokenNotCloseBracket(context) { return context.nextTokenSpan.kind !== 22 /* CloseBracketToken */; } function isArrowFunctionContext(context) { return context.contextNode.kind === 188 /* ArrowFunction */; } function isNonJsxSameLineTokenContext(context) { return context.TokensAreOnSameLine() && context.contextNode.kind !== 10 /* JsxText */; } function isNonJsxElementContext(context) { return context.contextNode.kind !== 250 /* JsxElement */; } function isJsxExpressionContext(context) { return context.contextNode.kind === 260 /* JsxExpression */; } function isNextTokenParentJsxAttribute(context) { return context.nextTokenParent.kind === 257 /* JsxAttribute */; } function isJsxAttributeContext(context) { return context.contextNode.kind === 257 /* JsxAttribute */; } function isJsxSelfClosingElementContext(context) { return context.contextNode.kind === 251 /* JsxSelfClosingElement */; } function isNotBeforeBlockInFunctionDeclarationContext(context) { return !isFunctionDeclContext(context) && !isBeforeBlockContext(context); } function isEndOfDecoratorContextOnSameLine(context) { return context.TokensAreOnSameLine() && context.contextNode.decorators && nodeIsInDecoratorContext(context.currentTokenParent) && !nodeIsInDecoratorContext(context.nextTokenParent); } function nodeIsInDecoratorContext(node) { while (ts.isExpressionNode(node)) { node = node.parent; } return node.kind === 148 /* Decorator */; } function isStartOfVariableDeclarationList(context) { return context.currentTokenParent.kind === 228 /* VariableDeclarationList */ && context.currentTokenParent.getStart(context.sourceFile) === context.currentTokenSpan.pos; } function isNotFormatOnEnter(context) { return context.formattingRequestKind !== 2 /* FormatOnEnter */; } function isModuleDeclContext(context) { return context.contextNode.kind === 234 /* ModuleDeclaration */; } function isObjectTypeContext(context) { return context.contextNode.kind === 164 /* TypeLiteral */; // && context.contextNode.parent.kind !== SyntaxKind.InterfaceDeclaration; } function isConstructorSignatureContext(context) { return context.contextNode.kind === 157 /* ConstructSignature */; } function isTypeArgumentOrParameterOrAssertion(token, parent) { if (token.kind !== 27 /* LessThanToken */ && token.kind !== 29 /* GreaterThanToken */) { return false; } switch (parent.kind) { case 160 /* TypeReference */: case 185 /* TypeAssertionExpression */: case 232 /* TypeAliasDeclaration */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 182 /* CallExpression */: case 183 /* NewExpression */: case 202 /* ExpressionWithTypeArguments */: return true; default: return false; } } function isTypeArgumentOrParameterOrAssertionContext(context) { return isTypeArgumentOrParameterOrAssertion(context.currentTokenSpan, context.currentTokenParent) || isTypeArgumentOrParameterOrAssertion(context.nextTokenSpan, context.nextTokenParent); } function isTypeAssertionContext(context) { return context.contextNode.kind === 185 /* TypeAssertionExpression */; } function isVoidOpContext(context) { return context.currentTokenSpan.kind === 105 /* VoidKeyword */ && context.currentTokenParent.kind === 191 /* VoidExpression */; } function isYieldOrYieldStarWithOperand(context) { return context.contextNode.kind === 198 /* YieldExpression */ && context.contextNode.expression !== undefined; } function isNonNullAssertionContext(context) { return context.contextNode.kind === 204 /* NonNullExpression */; } })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { function getFormatContext(options) { return { options: options, getRule: getRulesMap() }; } formatting.getFormatContext = getFormatContext; var rulesMapCache; function getRulesMap() { if (rulesMapCache === undefined) { rulesMapCache = createRulesMap(formatting.getAllRules()); } return rulesMapCache; } function createRulesMap(rules) { var map = buildMap(rules); return function (context) { var bucket = map[getRuleBucketIndex(context.currentTokenSpan.kind, context.nextTokenSpan.kind)]; return bucket && ts.find(bucket, function (rule) { return ts.every(rule.context, function (c) { return c(context); }); }); }; } function buildMap(rules) { // Map from bucket index to array of rules var map = new Array(mapRowLength * mapRowLength); // This array is used only during construction of the rulesbucket in the map var rulesBucketConstructionStateList = new Array(map.length); for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) { var rule = rules_1[_i]; var specificRule = rule.leftTokenRange.isSpecific && rule.rightTokenRange.isSpecific; for (var _a = 0, _b = rule.leftTokenRange.tokens; _a < _b.length; _a++) { var left = _b[_a]; for (var _c = 0, _d = rule.rightTokenRange.tokens; _c < _d.length; _c++) { var right = _d[_c]; var index = getRuleBucketIndex(left, right); var rulesBucket = map[index]; if (rulesBucket === undefined) { rulesBucket = map[index] = []; } addRule(rulesBucket, rule.rule, specificRule, rulesBucketConstructionStateList, index); } } } return map; } function getRuleBucketIndex(row, column) { ts.Debug.assert(row <= 143 /* LastKeyword */ && column <= 143 /* LastKeyword */, "Must compute formatting context from tokens"); return (row * mapRowLength) + column; } var maskBitSize = 5; var mask = 31; // MaskBitSize bits var mapRowLength = 143 /* LastToken */ + 1; var RulesPosition; (function (RulesPosition) { RulesPosition[RulesPosition["IgnoreRulesSpecific"] = 0] = "IgnoreRulesSpecific"; RulesPosition[RulesPosition["IgnoreRulesAny"] = maskBitSize * 1] = "IgnoreRulesAny"; RulesPosition[RulesPosition["ContextRulesSpecific"] = maskBitSize * 2] = "ContextRulesSpecific"; RulesPosition[RulesPosition["ContextRulesAny"] = maskBitSize * 3] = "ContextRulesAny"; RulesPosition[RulesPosition["NoContextRulesSpecific"] = maskBitSize * 4] = "NoContextRulesSpecific"; RulesPosition[RulesPosition["NoContextRulesAny"] = maskBitSize * 5] = "NoContextRulesAny"; })(RulesPosition || (RulesPosition = {})); // 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. function addRule(rules, rule, specificTokens, constructionState, rulesBucketIndex) { var position = rule.action === 1 /* Ignore */ ? specificTokens ? RulesPosition.IgnoreRulesSpecific : RulesPosition.IgnoreRulesAny : rule.context !== formatting.anyContext ? specificTokens ? RulesPosition.ContextRulesSpecific : RulesPosition.ContextRulesAny : specificTokens ? RulesPosition.NoContextRulesSpecific : RulesPosition.NoContextRulesAny; var state = constructionState[rulesBucketIndex] || 0; rules.splice(getInsertionIndex(state, position), 0, rule); constructionState[rulesBucketIndex] = increaseInsertionIndex(state, position); } function getInsertionIndex(indexBitmap, maskPosition) { var index = 0; for (var pos = 0; pos <= maskPosition; pos += maskBitSize) { index += indexBitmap & mask; indexBitmap >>= maskBitSize; } return index; } function increaseInsertionIndex(indexBitmap, maskPosition) { var value = ((indexBitmap >> maskPosition) & mask) + 1; ts.Debug.assert((value & mask) === value, "Adding more rules into the sub-bucket than allowed. Maximum allowed is 32 rules."); return (indexBitmap & ~(mask << maskPosition)) | (value << maskPosition); } })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (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, formatContext) { 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, formatContext, 2 /* FormatOnEnter */); } formatting.formatOnEnter = formatOnEnter; function formatOnSemicolon(position, sourceFile, formatContext) { var semicolon = findImmediatelyPrecedingTokenOfKind(position, 25 /* SemicolonToken */, sourceFile); return formatNodeLines(findOutermostNodeWithinListLevel(semicolon), sourceFile, formatContext, 3 /* FormatOnSemicolon */); } formatting.formatOnSemicolon = formatOnSemicolon; function formatOnOpeningCurly(position, sourceFile, formatContext) { var openingCurly = findImmediatelyPrecedingTokenOfKind(position, 17 /* OpenBraceToken */, sourceFile); if (!openingCurly) { return []; } var curlyBraceRange = openingCurly.parent; var outermostNode = findOutermostNodeWithinListLevel(curlyBraceRange); /** * We limit the span to end at the opening curly to handle the case where * the brace matched to that just typed will be incorrect after further edits. * For example, we could type the opening curly for the following method * body without brace-matching activated: * ``` * class C { * foo() * } * ``` * and we wouldn't want to move the closing brace. */ var textRange = { pos: ts.getLineStartPositionForPosition(outermostNode.getStart(sourceFile), sourceFile), end: position }; return formatSpan(textRange, sourceFile, formatContext, 4 /* FormatOnOpeningCurlyBrace */); } formatting.formatOnOpeningCurly = formatOnOpeningCurly; function formatOnClosingCurly(position, sourceFile, formatContext) { var precedingToken = findImmediatelyPrecedingTokenOfKind(position, 18 /* CloseBraceToken */, sourceFile); return formatNodeLines(findOutermostNodeWithinListLevel(precedingToken), sourceFile, formatContext, 5 /* FormatOnClosingCurlyBrace */); } formatting.formatOnClosingCurly = formatOnClosingCurly; function formatDocument(sourceFile, formatContext) { var span = { pos: 0, end: sourceFile.text.length }; return formatSpan(span, sourceFile, formatContext, 0 /* FormatDocument */); } formatting.formatDocument = formatDocument; function formatSelection(start, end, sourceFile, formatContext) { // format from the beginning of the line var span = { pos: ts.getLineStartPositionForPosition(start, sourceFile), end: end, }; return formatSpan(span, sourceFile, formatContext, 1 /* FormatSelection */); } formatting.formatSelection = formatSelection; /** * Validating `expectedTokenKind` ensures the token was typed in the context we expect (eg: not a comment). * @param expectedTokenKind The kind of the last token constituting the desired parent node. */ function findImmediatelyPrecedingTokenOfKind(end, expectedTokenKind, sourceFile) { var precedingToken = ts.findPrecedingToken(end, sourceFile); return precedingToken && precedingToken.kind === expectedTokenKind && end === precedingToken.getEnd() ? precedingToken : undefined; } /** * Finds the highest node enclosing `node` at the same list level as `node` * and whose end does not exceed `node.end`. * * Consider typing the following * ``` * let x = 1; * while (true) { * } * ``` * Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding * variable declaration. */ function findOutermostNodeWithinListLevel(node) { var current = node; while (current && current.parent && current.parent.end === node.end && !isListElement(current.parent, current)) { current = current.parent; } return current; } // Returns true if node is a element in some list in parent // i.e. parent is class declaration with the list of members and node is one of members. function isListElement(parent, node) { switch (parent.kind) { case 230 /* ClassDeclaration */: case 231 /* InterfaceDeclaration */: return ts.rangeContainsRange(parent.members, node); case 234 /* ModuleDeclaration */: var body = parent.body; return body && body.kind === 235 /* ModuleBlock */ && ts.rangeContainsRange(body.statements, node); case 269 /* SourceFile */: case 208 /* Block */: case 235 /* ModuleBlock */: return ts.rangeContainsRange(parent.statements, node); case 264 /* CatchClause */: return ts.rangeContainsRange(parent.block.statements, node); } return false; } /** find node that fully contains given text range */ function findEnclosingNode(range, sourceFile) { return find(sourceFile); function find(n) { var candidate = ts.forEachChild(n, function (c) { return ts.startEndContainsRange(c.getStart(sourceFile), c.end, range) && c; }); if (candidate) { var result = find(candidate); if (result) { return result; } } return n; } } /** formatting is not applied to ranges that contain parse errors. * This function will return a predicate that for a given text range will tell * if there are any parse errors that overlap with the range. */ function prepareRangeContainsErrorFunction(errors, originalRange) { if (!errors.length) { return rangeHasNoErrors; } // pick only errors that fall in range var sorted = errors .filter(function (d) { return ts.rangeOverlapsWithStartEnd(originalRange, d.start, d.start + d.length); }) .sort(function (e1, e2) { return e1.start - e2.start; }); if (!sorted.length) { return rangeHasNoErrors; } var index = 0; return function (r) { // in current implementation sequence of arguments [r1, r2...] is monotonically increasing. // 'index' tracks the index of the most recent error that was checked. while (true) { if (index >= sorted.length) { // all errors in the range were already checked -> no error in specified range return false; } var error = sorted[index]; if (r.end <= error.start) { // specified range ends before the error refered by 'index' - no error in range return false; } if (ts.startEndOverlapsWithStartEnd(r.pos, r.end, error.start, error.start + error.length)) { // specified range overlaps with error range return true; } index++; } }; function rangeHasNoErrors() { return false; } } /** * Start of the original range might fall inside the comment - scanner will not yield appropriate results * This function will look for token that is located before the start of target range * and return its end as start position for the scanner. */ function getScanStartPosition(enclosingNode, originalRange, sourceFile) { var start = enclosingNode.getStart(sourceFile); if (start === originalRange.pos && enclosingNode.end === originalRange.end) { return start; } var precedingToken = ts.findPrecedingToken(originalRange.pos, sourceFile); if (!precedingToken) { // no preceding token found - start from the beginning of enclosing node return enclosingNode.pos; } // preceding token ends after the start of original range (i.e when originalRange.pos falls in the middle of literal) // start from the beginning of enclosingNode to handle the entire 'originalRange' if (precedingToken.end >= originalRange.pos) { return enclosingNode.pos; } return precedingToken.end; } /* * For cases like * if (a || * b ||$ * c) {...} * If we hit Enter at $ we want line ' b ||' to be indented. * Formatting will be applied to the last two lines. * Node that fully encloses these lines is binary expression 'a ||...'. * Initial indentation for this node will be 0. * Binary expressions don't introduce new indentation scopes, however it is possible * that some parent node on the same line does - like if statement in this case. * Note that we are considering parents only from the same line with initial node - * if parent is on the different line - its delta was already contributed * to the initial indentation. */ function getOwnOrInheritedDelta(n, options, sourceFile) { var previousLine = -1 /* Unknown */; var child; while (n) { var line = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)).line; if (previousLine !== -1 /* Unknown */ && line !== previousLine) { break; } if (formatting.SmartIndenter.shouldIndentChildNode(n, child)) { return options.indentSize; } previousLine = line; child = n; n = n.parent; } return 0; } /* @internal */ function formatNodeGivenIndentation(node, sourceFileLike, languageVariant, initialIndentation, delta, formatContext) { var range = { pos: 0, end: sourceFileLike.text.length }; return formatting.getFormattingScanner(sourceFileLike.text, languageVariant, range.pos, range.end, function (scanner) { return formatSpanWorker(range, node, initialIndentation, delta, scanner, formatContext, 1 /* FormatSelection */, function (_) { return false; }, // assume that node does not have any errors sourceFileLike); }); } formatting.formatNodeGivenIndentation = formatNodeGivenIndentation; function formatNodeLines(node, sourceFile, formatContext, requestKind) { if (!node) { return []; } var span = { pos: ts.getLineStartPositionForPosition(node.getStart(sourceFile), sourceFile), end: node.end }; return formatSpan(span, sourceFile, formatContext, requestKind); } function formatSpan(originalRange, sourceFile, formatContext, requestKind) { // find the smallest node that fully wraps the range and compute the initial indentation for the node var enclosingNode = findEnclosingNode(originalRange, sourceFile); return formatting.getFormattingScanner(sourceFile.text, sourceFile.languageVariant, getScanStartPosition(enclosingNode, originalRange, sourceFile), originalRange.end, function (scanner) { return formatSpanWorker(originalRange, enclosingNode, formatting.SmartIndenter.getIndentationForNode(enclosingNode, originalRange, sourceFile, formatContext.options), getOwnOrInheritedDelta(enclosingNode, formatContext.options, sourceFile), scanner, formatContext, requestKind, prepareRangeContainsErrorFunction(sourceFile.parseDiagnostics, originalRange), sourceFile); }); } function formatSpanWorker(originalRange, enclosingNode, initialIndentation, delta, formattingScanner, _a, requestKind, rangeContainsError, sourceFile) { var options = _a.options, getRule = _a.getRule; // formatting context is used by rules provider var formattingContext = new formatting.FormattingContext(sourceFile, requestKind, options); var previousRange; var previousParent; var previousRangeStartLine; var lastIndentedLine; var indentationOnLastIndentedLine; var edits = []; formattingScanner.advance(); if (formattingScanner.isOnToken()) { var startLine = sourceFile.getLineAndCharacterOfPosition(enclosingNode.getStart(sourceFile)).line; var undecoratedStartLine = startLine; if (enclosingNode.decorators) { undecoratedStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(enclosingNode, sourceFile)).line; } processNode(enclosingNode, enclosingNode, startLine, undecoratedStartLine, initialIndentation, delta); } if (!formattingScanner.isOnToken()) { var leadingTrivia = formattingScanner.getCurrentLeadingTrivia(); if (leadingTrivia) { processTrivia(leadingTrivia, enclosingNode, enclosingNode, /*dynamicIndentation*/ undefined); trimTrailingWhitespacesForRemainingRange(); } } return edits; // local functions /** Tries to compute the indentation for a list element. * If list element is not in range then * function will pick its actual indentation * so it can be pushed downstream as inherited indentation. * If list element is in the range - its indentation will be equal * to inherited indentation from its predecessors. */ function tryComputeIndentationForListItem(startPos, endPos, parentStartLine, range, inheritedIndentation) { if (ts.rangeOverlapsWithStartEnd(range, startPos, endPos) || ts.rangeContainsStartEnd(range, startPos, endPos) /* Not to miss zero-range nodes e.g. JsxText */) { if (inheritedIndentation !== -1 /* Unknown */) { return inheritedIndentation; } } else { var startLine = sourceFile.getLineAndCharacterOfPosition(startPos).line; var startLinePosition = ts.getLineStartPositionForPosition(startPos, sourceFile); var column = formatting.SmartIndenter.findFirstNonWhitespaceColumn(startLinePosition, startPos, sourceFile, options); if (startLine !== parentStartLine || startPos === column) { // Use the base indent size if it is greater than // the indentation of the inherited predecessor. var baseIndentSize = formatting.SmartIndenter.getBaseIndentation(options); return baseIndentSize > column ? baseIndentSize : column; } } return -1 /* Unknown */; } function computeIndentation(node, startLine, inheritedIndentation, parent, parentDynamicIndentation, effectiveParentStartLine) { var indentation = inheritedIndentation; var delta = formatting.SmartIndenter.shouldIndentChildNode(node) ? options.indentSize : 0; if (effectiveParentStartLine === startLine) { // if node is located on the same line with the parent // - inherit indentation from the parent // - push children if either parent of node itself has non-zero delta indentation = startLine === lastIndentedLine ? indentationOnLastIndentedLine : parentDynamicIndentation.getIndentation(); delta = Math.min(options.indentSize, parentDynamicIndentation.getDelta(node) + delta); } else if (indentation === -1 /* Unknown */) { if (formatting.SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement(parent, node, startLine, sourceFile)) { indentation = parentDynamicIndentation.getIndentation(); } else { indentation = parentDynamicIndentation.getIndentation() + parentDynamicIndentation.getDelta(node); } } return { indentation: indentation, delta: delta }; } function getFirstNonDecoratorTokenOfNode(node) { if (node.modifiers && node.modifiers.length) { return node.modifiers[0].kind; } switch (node.kind) { case 230 /* ClassDeclaration */: return 75 /* ClassKeyword */; case 231 /* InterfaceDeclaration */: return 109 /* InterfaceKeyword */; case 229 /* FunctionDeclaration */: return 89 /* FunctionKeyword */; case 233 /* EnumDeclaration */: return 233 /* EnumDeclaration */; case 154 /* GetAccessor */: return 125 /* GetKeyword */; case 155 /* SetAccessor */: return 135 /* SetKeyword */; case 152 /* MethodDeclaration */: if (node.asteriskToken) { return 39 /* AsteriskToken */; } // falls through case 150 /* PropertyDeclaration */: case 147 /* Parameter */: return ts.getNameOfDeclaration(node).kind; } } function getDynamicIndentation(node, nodeStartLine, indentation, delta) { return { getIndentationForComment: function (kind, tokenIndentation, container) { switch (kind) { // preceding comment to the token that closes the indentation scope inherits the indentation from the scope // .. { // // comment // } case 18 /* CloseBraceToken */: case 22 /* CloseBracketToken */: case 20 /* CloseParenToken */: return indentation + getEffectiveDelta(delta, container); } return tokenIndentation !== -1 /* Unknown */ ? tokenIndentation : indentation; }, getIndentationForToken: function (line, kind, container) { if (nodeStartLine !== line && node.decorators) { if (kind === getFirstNonDecoratorTokenOfNode(node)) { // if this token is the first token following the list of decorators, we do not need to indent return indentation; } } switch (kind) { // open and close brace, 'else' and 'while' (in do statement) tokens has indentation of the parent case 17 /* OpenBraceToken */: case 18 /* CloseBraceToken */: case 19 /* OpenParenToken */: case 20 /* CloseParenToken */: case 82 /* ElseKeyword */: case 106 /* WhileKeyword */: case 57 /* AtToken */: return indentation; case 41 /* SlashToken */: case 29 /* GreaterThanToken */: { if (container.kind === 252 /* JsxOpeningElement */ || container.kind === 253 /* JsxClosingElement */ || container.kind === 251 /* JsxSelfClosingElement */) { return indentation; } break; } case 21 /* OpenBracketToken */: case 22 /* CloseBracketToken */: { if (container.kind !== 173 /* MappedType */) { return indentation; } break; } } // if token line equals to the line of containing node (this is a first token in the node) - use node indentation return nodeStartLine !== line ? indentation + getEffectiveDelta(delta, container) : indentation; }, getIndentation: function () { return indentation; }, getDelta: function (child) { return getEffectiveDelta(delta, child); }, recomputeIndentation: function (lineAdded) { if (node.parent && formatting.SmartIndenter.shouldIndentChildNode(node.parent, node)) { if (lineAdded) { indentation += options.indentSize; } else { indentation -= options.indentSize; } if (formatting.SmartIndenter.shouldIndentChildNode(node)) { delta = options.indentSize; } else { delta = 0; } } } }; function getEffectiveDelta(delta, child) { // Delta value should be zero when the node explicitly prevents indentation of the child node return formatting.SmartIndenter.nodeWillIndentChild(node, child, /*indentByDefault*/ true) ? delta : 0; } } function processNode(node, contextNode, nodeStartLine, undecoratedNodeStartLine, indentation, delta) { if (!ts.rangeOverlapsWithStartEnd(originalRange, node.getStart(sourceFile), node.getEnd())) { return; } var nodeDynamicIndentation = getDynamicIndentation(node, nodeStartLine, indentation, delta); // a useful observations when tracking context node // / // [a] // / | \ // [b] [c] [d] // node 'a' is a context node for nodes 'b', 'c', 'd' // except for the leftmost leaf token in [b] - in this case context node ('e') is located somewhere above 'a' // this rule can be applied recursively to child nodes of 'a'. // // context node is set to parent node value after processing every child node // context node is set to parent of the token after processing every token var childContextNode = contextNode; // if there are any tokens that logically belong to node and interleave child nodes // such tokens will be consumed in processChildNode for for the child that follows them ts.forEachChild(node, function (child) { processChildNode(child, /*inheritedIndentation*/ -1 /* Unknown */, node, nodeDynamicIndentation, nodeStartLine, undecoratedNodeStartLine, /*isListItem*/ false); }, function (nodes) { processChildNodes(nodes, node, nodeStartLine, nodeDynamicIndentation); }); // proceed any tokens in the node that are located after child nodes while (formattingScanner.isOnToken()) { var tokenInfo = formattingScanner.readTokenInfo(node); if (tokenInfo.token.end > node.end) { break; } consumeTokenAndAdvanceScanner(tokenInfo, node, nodeDynamicIndentation, node); } function processChildNode(child, inheritedIndentation, parent, parentDynamicIndentation, parentStartLine, undecoratedParentStartLine, isListItem, isFirstListItem) { var childStartPos = child.getStart(sourceFile); var childStartLine = sourceFile.getLineAndCharacterOfPosition(childStartPos).line; var undecoratedChildStartLine = childStartLine; if (child.decorators) { undecoratedChildStartLine = sourceFile.getLineAndCharacterOfPosition(ts.getNonDecoratorTokenPosOfNode(child, sourceFile)).line; } // if child is a list item - try to get its indentation, only if parent is within the original range. var childIndentationAmount = -1 /* Unknown */; if (isListItem && ts.rangeContainsRange(originalRange, parent)) { childIndentationAmount = tryComputeIndentationForListItem(childStartPos, child.end, parentStartLine, originalRange, inheritedIndentation); if (childIndentationAmount !== -1 /* Unknown */) { inheritedIndentation = childIndentationAmount; } } // child node is outside the target range - do not dive inside if (!ts.rangeOverlapsWithStartEnd(originalRange, child.pos, child.end)) { if (child.end < originalRange.pos) { formattingScanner.skipToEndOf(child); } return inheritedIndentation; } if (child.getFullWidth() === 0) { return inheritedIndentation; } while (formattingScanner.isOnToken()) { // proceed any parent tokens that are located prior to child.getStart() var tokenInfo = formattingScanner.readTokenInfo(node); if (tokenInfo.token.end > childStartPos) { // stop when formatting scanner advances past the beginning of the child break; } consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, node); } if (!formattingScanner.isOnToken()) { return inheritedIndentation; } // JSX text shouldn't affect indenting if (ts.isToken(child) && child.kind !== 10 /* JsxText */) { // if child node is a token, it does not impact indentation, proceed it using parent indentation scope rules var tokenInfo = formattingScanner.readTokenInfo(child); ts.Debug.assert(tokenInfo.token.end === child.end, "Token end is child end"); consumeTokenAndAdvanceScanner(tokenInfo, node, parentDynamicIndentation, child); return inheritedIndentation; } var effectiveParentStartLine = child.kind === 148 /* Decorator */ ? childStartLine : undecoratedParentStartLine; var childIndentation = computeIndentation(child, childStartLine, childIndentationAmount, node, parentDynamicIndentation, effectiveParentStartLine); processNode(child, childContextNode, childStartLine, undecoratedChildStartLine, childIndentation.indentation, childIndentation.delta); if (child.kind === 10 /* JsxText */) { var range = { pos: child.getStart(), end: child.getEnd() }; indentMultilineCommentOrJsxText(range, childIndentation.indentation, /*firstLineIsIndented*/ true, /*indentFinalLine*/ false); } childContextNode = node; if (isFirstListItem && parent.kind === 178 /* ArrayLiteralExpression */ && inheritedIndentation === -1 /* Unknown */) { inheritedIndentation = childIndentation.indentation; } return inheritedIndentation; } function processChildNodes(nodes, parent, parentStartLine, parentDynamicIndentation) { ts.Debug.assert(ts.isNodeArray(nodes)); var listStartToken = getOpenTokenForList(parent, nodes); var listEndToken = getCloseTokenForOpenToken(listStartToken); var listDynamicIndentation = parentDynamicIndentation; var startLine = parentStartLine; if (listStartToken !== 0 /* Unknown */) { // introduce a new indentation scope for lists (including list start and end tokens) while (formattingScanner.isOnToken()) { var tokenInfo = formattingScanner.readTokenInfo(parent); if (tokenInfo.token.end > nodes.pos) { // stop when formatting scanner moves past the beginning of node list break; } else if (tokenInfo.token.kind === listStartToken) { // consume list start token startLine = sourceFile.getLineAndCharacterOfPosition(tokenInfo.token.pos).line; var indentation_1 = computeIndentation(tokenInfo.token, startLine, -1 /* Unknown */, parent, parentDynamicIndentation, parentStartLine); listDynamicIndentation = getDynamicIndentation(parent, parentStartLine, indentation_1.indentation, indentation_1.delta); consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent); } else { // consume any tokens that precede the list as child elements of 'node' using its indentation scope consumeTokenAndAdvanceScanner(tokenInfo, parent, parentDynamicIndentation, parent); } } } var inheritedIndentation = -1 /* Unknown */; for (var i = 0; i < nodes.length; i++) { var child = nodes[i]; inheritedIndentation = processChildNode(child, inheritedIndentation, node, listDynamicIndentation, startLine, startLine, /*isListItem*/ true, /*isFirstListItem*/ i === 0); } if (listEndToken !== 0 /* Unknown */) { if (formattingScanner.isOnToken()) { var tokenInfo = formattingScanner.readTokenInfo(parent); // consume the list end token only if it is still belong to the parent // there might be the case when current token matches end token but does not considered as one // function (x: function) <-- // without this check close paren will be interpreted as list end token for function expression which is wrong if (tokenInfo.token.kind === listEndToken && ts.rangeContainsRange(parent, tokenInfo.token)) { // consume list end token consumeTokenAndAdvanceScanner(tokenInfo, parent, listDynamicIndentation, parent); } } } } function consumeTokenAndAdvanceScanner(currentTokenInfo, parent, dynamicIndentation, container) { ts.Debug.assert(ts.rangeContainsRange(parent, currentTokenInfo.token)); var lastTriviaWasNewLine = formattingScanner.lastTrailingTriviaWasNewLine(); var indentToken = false; if (currentTokenInfo.leadingTrivia) { processTrivia(currentTokenInfo.leadingTrivia, parent, childContextNode, dynamicIndentation); } var lineAction = 0 /* None */; 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; lineAction = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation); // do not indent comments\token if token range overlaps with some error if (!rangeHasError) { if (lineAction === 0 /* None */) { // 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; } else { indentToken = lineAction === 1 /* LineAdded */; } } } 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) { indentMultilineCommentOrJsxText(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, lineAction === 1 /* 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 lineAction = 0 /* None */; if (!rangeHasError) { if (!previousRange) { // trim whitespaces starting from the beginning of the span up to the current line var originalStart = sourceFile.getLineAndCharacterOfPosition(originalRange.pos); trimTrailingWhitespacesForLines(originalStart.line, rangeStart.line); } else { lineAction = processPair(range, rangeStart.line, parent, previousRange, previousRangeStartLine, previousParent, contextNode, dynamicIndentation); } } previousRange = range; previousParent = parent; previousRangeStartLine = rangeStart.line; return lineAction; } function processPair(currentItem, currentStartLine, currentParent, previousItem, previousStartLine, previousParent, contextNode, dynamicIndentation) { formattingContext.updateContext(previousItem, previousParent, currentItem, currentParent, contextNode); var rule = getRule(formattingContext); var trimTrailingWhitespaces; var lineAction = 0 /* None */; if (rule) { applyRuleEdits(rule, previousItem, previousStartLine, currentItem, currentStartLine); if (rule.action & (2 /* Space */ | 8 /* Delete */) && currentStartLine !== previousStartLine) { lineAction = 2 /* LineRemoved */; // 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.action & 4 /* NewLine */ && currentStartLine === previousStartLine) { lineAction = 1 /* LineAdded */; // 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.action & 8 /* Delete */) && rule.flags !== 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 lineAction; } function insertIndentation(pos, indentation, lineAdded) { var indentationString = getIndentationString(indentation, options); if (lineAdded) { // new line is added before the token by the formatting rules // insert indentation string at the very beginning of the token recordReplace(pos, 0, indentationString); } else { var tokenStart = sourceFile.getLineAndCharacterOfPosition(pos); var startLinePosition = ts.getStartPositionOfLine(tokenStart.line, sourceFile); if (indentation !== characterToColumn(startLinePosition, tokenStart.character) || indentationIsDifferent(indentationString, startLinePosition)) { recordReplace(startLinePosition, tokenStart.character, indentationString); } } } function characterToColumn(startLinePosition, characterInLine) { var column = 0; for (var i = 0; i < characterInLine; i++) { if (sourceFile.text.charCodeAt(startLinePosition + i) === 9 /* tab */) { column += options.tabSize - column % options.tabSize; } else { column++; } } return column; } function indentationIsDifferent(indentationString, startLinePosition) { return indentationString !== sourceFile.text.substr(startLinePosition, indentationString.length); } function indentMultilineCommentOrJsxText(commentRange, indentation, firstLineIsIndented, indentFinalLine) { if (indentFinalLine === void 0) { indentFinalLine = true; } // 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); } if (indentFinalLine) { parts.push({ pos: startPos, end: commentRange.end }); } } var startLinePos = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceColumnInFirstPart = formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(startLinePos, parts[0].pos, sourceFile, options); if (indentation === nonWhitespaceColumnInFirstPart.column) { return; } var startIndex = 0; if (firstLineIsIndented) { startIndex = 1; startLine++; } // shift all parts on the delta size var delta = indentation - nonWhitespaceColumnInFirstPart.column; for (var i = startIndex; i < parts.length; i++, startLine++) { var startLinePos_1 = ts.getStartPositionOfLine(startLine, sourceFile); var nonWhitespaceCharacterAndColumn = i === 0 ? nonWhitespaceColumnInFirstPart : formatting.SmartIndenter.findFirstNonWhitespaceCharacterAndColumn(parts[i].pos, parts[i].end, sourceFile, options); var newIndentation = nonWhitespaceCharacterAndColumn.column + delta; if (newIndentation > 0) { var indentationString = getIndentationString(newIndentation, options); recordReplace(startLinePos_1, nonWhitespaceCharacterAndColumn.character, indentationString); } else { recordDelete(startLinePos_1, nonWhitespaceCharacterAndColumn.character); } } } function trimTrailingWhitespacesForLines(line1, line2, range) { for (var line = line1; line < line2; line++) { var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var lineEndPosition = ts.getEndLinePosition(line, sourceFile); // do not trim whitespaces in comments or template expression if (range && (ts.isComment(range.kind) || ts.isStringOrRegularExpressionOrTemplateLiteral(range.kind)) && range.pos <= lineEndPosition && range.end > lineEndPosition) { continue; } var whitespaceStart = getTrailingWhitespaceStartPosition(lineStartPosition, lineEndPosition); if (whitespaceStart !== -1) { ts.Debug.assert(whitespaceStart === lineStartPosition || !ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(whitespaceStart - 1))); recordDelete(whitespaceStart, lineEndPosition + 1 - whitespaceStart); } } } /** * @param start The position of the first character in range * @param end The position of the last character in range */ function getTrailingWhitespaceStartPosition(start, end) { var pos = end; while (pos >= start && ts.isWhiteSpaceSingleLine(sourceFile.text.charCodeAt(pos))) { pos--; } if (pos !== end) { return pos + 1; } return -1; } /** * Trimming will be done for lines after the previous range */ function trimTrailingWhitespacesForRemainingRange() { var startPosition = previousRange ? previousRange.end : originalRange.pos; var startLine = sourceFile.getLineAndCharacterOfPosition(startPosition).line; var endLine = sourceFile.getLineAndCharacterOfPosition(originalRange.end).line; trimTrailingWhitespacesForLines(startLine, endLine + 1, previousRange); } function newTextChange(start, len, newText) { return { span: ts.createTextSpan(start, len), newText: newText }; } function recordDelete(start, len) { if (len) { edits.push(newTextChange(start, len, "")); } } function recordReplace(start, len, newText) { if (len || newText) { edits.push(newTextChange(start, len, newText)); } } function applyRuleEdits(rule, previousRange, previousStartLine, currentRange, currentStartLine) { switch (rule.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.flags !== 1 /* CanDeleteNewLines */ && previousStartLine !== currentStartLine) { return; } // edit should not be applied if we have one line feed between elements var lineDelta = currentStartLine - previousStartLine; if (lineDelta !== 1) { recordReplace(previousRange.end, currentRange.pos - previousRange.end, options.newLineCharacter); } break; case 2 /* Space */: // exit early if we on different lines and rule cannot change number of newlines if (rule.flags !== 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; } } } var LineAction; (function (LineAction) { LineAction[LineAction["None"] = 0] = "None"; LineAction[LineAction["LineAdded"] = 1] = "LineAdded"; LineAction[LineAction["LineRemoved"] = 2] = "LineRemoved"; })(LineAction || (LineAction = {})); /** * @param precedingToken pass `null` if preceding token was already computed and result was `undefined`. */ function getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine, precedingToken, // tslint:disable-line:no-null-keyword tokenAtPosition, predicate) { if (tokenAtPosition === void 0) { tokenAtPosition = ts.getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); } var tokenStart = tokenAtPosition.getStart(sourceFile); if (tokenStart <= position && position < tokenAtPosition.getEnd()) { return undefined; } if (precedingToken === undefined) { precedingToken = ts.findPrecedingToken(position, sourceFile); } // Between two consecutive tokens, all comments are either trailing on the former // or leading on the latter (and none are in both lists). var trailingRangesOfPreviousToken = precedingToken && ts.getTrailingCommentRanges(sourceFile.text, precedingToken.end); var leadingCommentRangesOfNextToken = ts.getLeadingCommentRangesOfNode(tokenAtPosition, sourceFile); var commentRanges = trailingRangesOfPreviousToken && leadingCommentRangesOfNextToken ? trailingRangesOfPreviousToken.concat(leadingCommentRangesOfNextToken) : trailingRangesOfPreviousToken || leadingCommentRangesOfNextToken; if (commentRanges) { for (var _i = 0, commentRanges_1 = commentRanges; _i < commentRanges_1.length; _i++) { var range = commentRanges_1[_i]; // The end marker of a single-line comment does not include the newline character. // With caret at `^`, in the following case, we are inside a comment (^ denotes the cursor position): // // // asdf ^\n // // But for closed multi-line comments, we don't want to be inside the comment in the following case: // // /* asdf */^ // // However, unterminated multi-line comments *do* contain their end. // // Internally, we represent the end of the comment at the newline and closing '/', respectively. // if ((range.pos < position && position < range.end || position === range.end && (range.kind === 2 /* SingleLineCommentTrivia */ || position === sourceFile.getFullWidth()))) { return (range.kind === 3 /* MultiLineCommentTrivia */ || !onlyMultiLine) && (!predicate || predicate(range)) ? range : undefined; } } } return undefined; } formatting.getRangeOfEnclosingComment = getRangeOfEnclosingComment; function getOpenTokenForList(node, list) { switch (node.kind) { case 153 /* Constructor */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 188 /* ArrowFunction */: if (node.typeParameters === list) { return 27 /* LessThanToken */; } else if (node.parameters === list) { return 19 /* OpenParenToken */; } break; case 182 /* CallExpression */: case 183 /* NewExpression */: if (node.typeArguments === list) { return 27 /* LessThanToken */; } else if (node.arguments === list) { return 19 /* OpenParenToken */; } break; case 160 /* TypeReference */: if (node.typeArguments === list) { return 27 /* LessThanToken */; } } return 0 /* Unknown */; } function getCloseTokenForOpenToken(kind) { switch (kind) { case 19 /* OpenParenToken */: return 20 /* CloseParenToken */; case 27 /* LessThanToken */: return 29 /* GreaterThanToken */; } return 0 /* Unknown */; } var internedSizes; var internedTabsIndentation; var internedSpacesIndentation; function getIndentationString(indentation, options) { // reset interned strings if FormatCodeOptions were changed var resetInternedStrings = !internedSizes || (internedSizes.tabSize !== options.tabSize || internedSizes.indentSize !== options.indentSize); if (resetInternedStrings) { internedSizes = { tabSize: options.tabSize, indentSize: options.indentSize }; internedTabsIndentation = internedSpacesIndentation = undefined; } if (!options.convertTabsToSpaces) { var tabs = Math.floor(indentation / options.tabSize); var spaces = indentation - tabs * options.tabSize; var tabString = void 0; if (!internedTabsIndentation) { internedTabsIndentation = []; } if (internedTabsIndentation[tabs] === undefined) { internedTabsIndentation[tabs] = tabString = repeat("\t", tabs); } else { tabString = internedTabsIndentation[tabs]; } return spaces ? tabString + repeat(" ", spaces) : tabString; } else { var spacesString = void 0; var quotient = Math.floor(indentation / options.indentSize); var remainder = indentation % options.indentSize; if (!internedSpacesIndentation) { internedSpacesIndentation = []; } if (internedSpacesIndentation[quotient] === undefined) { spacesString = repeat(" ", options.indentSize * quotient); internedSpacesIndentation[quotient] = spacesString; } else { spacesString = internedSpacesIndentation[quotient]; } return remainder ? spacesString + repeat(" ", remainder) : spacesString; } function repeat(value, count) { var s = ""; for (var i = 0; i < count; i++) { s += value; } return s; } } formatting.getIndentationString = getIndentationString; })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var formatting; (function (formatting) { var SmartIndenter; (function (SmartIndenter) { var Value; (function (Value) { Value[Value["Unknown"] = -1] = "Unknown"; })(Value || (Value = {})); /** * @param assumeNewLineBeforeCloseBrace * `false` when called on text from a real source file. * `true` when we need to assume `position` is on a newline. * * This is useful for codefixes. Consider * ``` * function f() { * |} * ``` * with `position` at `|`. * * When inserting some text after an open brace, we would like to get indentation as if a newline was already there. * By default indentation at `position` will be 0 so 'assumeNewLineBeforeCloseBrace' overrides this behavior. */ function getIndentation(position, sourceFile, options, assumeNewLineBeforeCloseBrace) { if (assumeNewLineBeforeCloseBrace === void 0) { assumeNewLineBeforeCloseBrace = false; } if (position > sourceFile.text.length) { return getBaseIndentation(options); // past EOF } // no indentation when the indent style is set to none, // so we can return fast if (options.indentStyle === ts.IndentStyle.None) { return 0; } var precedingToken = ts.findPrecedingToken(position, sourceFile); var enclosingCommentRange = formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ true, precedingToken || null); // tslint:disable-line:no-null-keyword if (enclosingCommentRange) { return getCommentIndent(sourceFile, position, options, enclosingCommentRange); } if (!precedingToken) { return getBaseIndentation(options); } // no indentation in string \regex\template literals var precedingTokenIsLiteral = ts.isStringOrRegularExpressionOrTemplateLiteral(precedingToken.kind); if (precedingTokenIsLiteral && precedingToken.getStart(sourceFile) <= position && position < precedingToken.end) { return 0; } var lineAtPosition = sourceFile.getLineAndCharacterOfPosition(position).line; // indentation is first non-whitespace character in a previous line // for block indentation, we should look for a line which contains something that's not // whitespace. if (options.indentStyle === ts.IndentStyle.Block) { return getBlockIndent(sourceFile, position, options); } if (precedingToken.kind === 26 /* CommaToken */ && precedingToken.parent.kind !== 195 /* 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; } } return getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options); } SmartIndenter.getIndentation = getIndentation; function getCommentIndent(sourceFile, position, options, enclosingCommentRange) { var previousLine = ts.getLineAndCharacterOfPosition(sourceFile, position).line - 1; var commentStartLine = ts.getLineAndCharacterOfPosition(sourceFile, enclosingCommentRange.pos).line; ts.Debug.assert(commentStartLine >= 0); if (previousLine <= commentStartLine) { return findFirstNonWhitespaceColumn(ts.getStartPositionOfLine(commentStartLine, sourceFile), position, sourceFile, options); } var startPostionOfLine = ts.getStartPositionOfLine(previousLine, sourceFile); var _a = findFirstNonWhitespaceCharacterAndColumn(startPostionOfLine, position, sourceFile, options), column = _a.column, character = _a.character; if (column === 0) { return column; } var firstNonWhitespaceCharacterCode = sourceFile.text.charCodeAt(startPostionOfLine + character); return firstNonWhitespaceCharacterCode === 42 /* asterisk */ ? column - 1 : column; } function getBlockIndent(sourceFile, position, options) { // move backwards until we find a line with a non-whitespace character, // then find the first non-whitespace character for that line. var current = position; while (current > 0) { var char = sourceFile.text.charCodeAt(current); if (!ts.isWhiteSpaceLike(char)) { break; } current--; } var lineStart = ts.getLineStartPositionForPosition(current, sourceFile); return findFirstNonWhitespaceColumn(lineStart, current, sourceFile, options); } function getSmartIndent(sourceFile, position, precedingToken, lineAtPosition, assumeNewLineBeforeCloseBrace, options) { // 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; while (current) { if (ts.positionBelongsToNode(current, position, sourceFile) && shouldIndentChildNode(current, previous, /*isNextChild*/ true)) { var currentStart = getStartLineAndCharacterForNode(current, sourceFile); var nextTokenKind = nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile); var indentationDelta = nextTokenKind !== 0 /* Unknown */ // handle cases when codefix is about to be inserted before the close brace ? assumeNewLineBeforeCloseBrace && nextTokenKind === 2 /* CloseBrace */ ? options.indentSize : 0 : lineAtPosition !== currentStart.line ? options.indentSize : 0; return getIndentationForNodeWorker(current, currentStart, /*ignoreActualIndentationRange*/ undefined, indentationDelta, sourceFile, /*isNextChild*/ true, options); } // 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; } // no parent was found - return the base indentation of the SourceFile return getBaseIndentation(options); } function getIndentationForNode(n, ignoreActualIndentationRange, sourceFile, options) { var start = sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); return getIndentationForNodeWorker(n, start, ignoreActualIndentationRange, /*indentationDelta*/ 0, sourceFile, /*isNextChild*/ false, options); } SmartIndenter.getIndentationForNode = getIndentationForNode; function getBaseIndentation(options) { return options.baseIndentSize || 0; } SmartIndenter.getBaseIndentation = getBaseIndentation; function getIndentationForNodeWorker(current, currentStart, ignoreActualIndentationRange, indentationDelta, sourceFile, isNextChild, options) { var parent = current.parent; // Walk up the tree and collect indentation for parent-child node pairs. Indentation is not added if // * parent and child nodes start on the same line, or // * parent is an IfStatement and child starts on the same line as an 'else clause'. while (parent) { var useActualIndentation = true; if (ignoreActualIndentationRange) { var start = current.getStart(sourceFile); useActualIndentation = start < ignoreActualIndentationRange.pos || start > ignoreActualIndentationRange.end; } if (useActualIndentation) { // check if current node is a list item - if yes, take indentation from it var actualIndentation = getActualIndentationForListItem(current, sourceFile, options); if (actualIndentation !== -1 /* Unknown */) { return actualIndentation + indentationDelta; } } var containingListOrParentStart = getContainingListOrParentStart(parent, current, sourceFile); var parentAndChildShareLine = containingListOrParentStart.line === currentStart.line || childStartsOnTheSameLineWithElseInIfStatement(parent, current, currentStart.line, sourceFile); if (useActualIndentation) { // try to fetch actual indentation for current node from source text var actualIndentation = getActualIndentationForNode(current, parent, currentStart, parentAndChildShareLine, sourceFile, options); if (actualIndentation !== -1 /* Unknown */) { return actualIndentation + indentationDelta; } actualIndentation = getLineIndentationWhenExpressionIsInMultiLine(current, sourceFile, options); if (actualIndentation !== -1 /* Unknown */) { return actualIndentation + indentationDelta; } } // increase indentation if parent node wants its content to be indented and parent and child nodes don't start on the same line if (shouldIndentChildNode(parent, current, isNextChild) && !parentAndChildShareLine) { indentationDelta += options.indentSize; } // In our AST, a call argument's `parent` is the call-expression, not the argument list. // We would like to increase indentation based on the relationship between an argument and its argument-list, // so we spoof the starting position of the (parent) call-expression to match the (non-parent) argument-list. // But, the spoofed start-value could then cause a problem when comparing the start position of the call-expression // to *its* parent (in the case of an iife, an expression statement), adding an extra level of indentation. // // Instead, when at an argument, we unspoof the starting position of the enclosing call expression // *after* applying indentation for the argument. var useTrueStart = isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, current, currentStart.line, sourceFile); current = parent; parent = current.parent; currentStart = useTrueStart ? sourceFile.getLineAndCharacterOfPosition(current.getStart(sourceFile)) : containingListOrParentStart; } return indentationDelta + getBaseIndentation(options); } function getContainingListOrParentStart(parent, child, sourceFile) { var containingList = getContainingList(child, sourceFile); var startPos = containingList ? containingList.pos : parent.getStart(sourceFile); return sourceFile.getLineAndCharacterOfPosition(startPos); } /* * Function returns Value.Unknown if indentation cannot be determined */ function getActualIndentationForListItemBeforeComma(commaToken, sourceFile, options) { // previous token is comma that separates items in list - find the previous item and try to derive indentation from it var commaItemInfo = ts.findListItemInfo(commaToken); if (commaItemInfo && commaItemInfo.listItemIndex > 0) { return deriveActualIndentationFromList(commaItemInfo.list.getChildren(), commaItemInfo.listItemIndex - 1, sourceFile, options); } else { // handle broken code gracefully return -1 /* Unknown */; } } /* * Function returns Value.Unknown if actual indentation for node should not be used (i.e because node is nested expression) */ function getActualIndentationForNode(current, parent, currentLineAndChar, parentAndChildShareLine, sourceFile, options) { // actual indentation is used for statements\declarations if one of cases below is true: // - parent is SourceFile - by default immediate children of SourceFile are not indented except when user indents them manually // - parent and child are not on the same line var useActualIndentation = (ts.isDeclaration(current) || ts.isStatementButNotDeclaration(current)) && (parent.kind === 269 /* SourceFile */ || !parentAndChildShareLine); if (!useActualIndentation) { return -1 /* Unknown */; } return findColumnForFirstNonWhitespaceCharacterInLine(currentLineAndChar, sourceFile, options); } var NextTokenKind; (function (NextTokenKind) { NextTokenKind[NextTokenKind["Unknown"] = 0] = "Unknown"; NextTokenKind[NextTokenKind["OpenBrace"] = 1] = "OpenBrace"; NextTokenKind[NextTokenKind["CloseBrace"] = 2] = "CloseBrace"; })(NextTokenKind || (NextTokenKind = {})); function nextTokenIsCurlyBraceOnSameLineAsCursor(precedingToken, current, lineAtPosition, sourceFile) { var nextToken = ts.findNextToken(precedingToken, current); if (!nextToken) { return 0 /* Unknown */; } if (nextToken.kind === 17 /* OpenBraceToken */) { // open braces are always indented at the parent level return 1 /* OpenBrace */; } else if (nextToken.kind === 18 /* CloseBraceToken */) { // close braces are indented at the parent level if they are located on the same line with cursor // this means that if new line will be added at $ position, this case will be indented // class A { // $ // } /// and this one - not // class A { // $} var nextTokenStartLine = getStartLineAndCharacterForNode(nextToken, sourceFile).line; return lineAtPosition === nextTokenStartLine ? 2 /* CloseBrace */ : 0 /* Unknown */; } return 0 /* Unknown */; } function getStartLineAndCharacterForNode(n, sourceFile) { return sourceFile.getLineAndCharacterOfPosition(n.getStart(sourceFile)); } function isArgumentAndStartLineOverlapsExpressionBeingCalled(parent, child, childStartLine, sourceFile) { if (!(ts.isCallExpression(parent) && ts.contains(parent.arguments, child))) { return false; } var expressionOfCallExpressionEnd = parent.expression.getEnd(); var expressionOfCallExpressionEndLine = ts.getLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd).line; return expressionOfCallExpressionEndLine === childStartLine; } SmartIndenter.isArgumentAndStartLineOverlapsExpressionBeingCalled = isArgumentAndStartLineOverlapsExpressionBeingCalled; function childStartsOnTheSameLineWithElseInIfStatement(parent, child, childStartLine, sourceFile) { if (parent.kind === 212 /* IfStatement */ && parent.elseStatement === child) { var elseKeyword = ts.findChildOfKind(parent, 82 /* ElseKeyword */, sourceFile); ts.Debug.assert(elseKeyword !== undefined); var elseKeywordStartLine = getStartLineAndCharacterForNode(elseKeyword, sourceFile).line; return elseKeywordStartLine === childStartLine; } return false; } SmartIndenter.childStartsOnTheSameLineWithElseInIfStatement = childStartsOnTheSameLineWithElseInIfStatement; function getListIfStartEndIsInListRange(list, start, end) { return list && ts.rangeContainsStartEnd(list, start, end) ? list : undefined; } function getContainingList(node, sourceFile) { if (node.parent) { switch (node.parent.kind) { case 160 /* TypeReference */: return getListIfStartEndIsInListRange(node.parent.typeArguments, node.getStart(sourceFile), node.getEnd()); case 179 /* ObjectLiteralExpression */: return node.parent.properties; case 178 /* ArrayLiteralExpression */: return node.parent.elements; case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 188 /* ArrowFunction */: case 152 /* MethodDeclaration */: case 151 /* MethodSignature */: case 156 /* CallSignature */: case 153 /* Constructor */: case 162 /* ConstructorType */: case 157 /* ConstructSignature */: { var start = node.getStart(sourceFile); return getListIfStartEndIsInListRange(node.parent.typeParameters, start, node.getEnd()) || getListIfStartEndIsInListRange(node.parent.parameters, start, node.getEnd()); } case 230 /* ClassDeclaration */: return getListIfStartEndIsInListRange(node.parent.typeParameters, node.getStart(sourceFile), node.getEnd()); case 183 /* NewExpression */: case 182 /* CallExpression */: { var start = node.getStart(sourceFile); return getListIfStartEndIsInListRange(node.parent.typeArguments, start, node.getEnd()) || getListIfStartEndIsInListRange(node.parent.arguments, start, node.getEnd()); } case 228 /* VariableDeclarationList */: return getListIfStartEndIsInListRange(node.parent.declarations, node.getStart(sourceFile), node.getEnd()); case 242 /* NamedImports */: case 246 /* NamedExports */: return getListIfStartEndIsInListRange(node.parent.elements, node.getStart(sourceFile), node.getEnd()); } } return undefined; } SmartIndenter.getContainingList = getContainingList; function getActualIndentationForListItem(node, sourceFile, options) { var containingList = getContainingList(node, sourceFile); return containingList ? getActualIndentationFromList(containingList) : -1 /* Unknown */; function getActualIndentationFromList(list) { var index = ts.indexOf(list, node); return index !== -1 ? deriveActualIndentationFromList(list, index, sourceFile, options) : -1 /* Unknown */; } } function getLineIndentationWhenExpressionIsInMultiLine(node, sourceFile, options) { // actual indentation should not be used when: // - node is close parenthesis - this is the end of the expression if (node.kind === 20 /* CloseParenToken */) { return -1 /* Unknown */; } if (node.parent && ts.isCallOrNewExpression(node.parent) && node.parent.expression !== node) { var fullCallOrNewExpression = node.parent.expression; var startingExpression = getStartingExpression(fullCallOrNewExpression); if (fullCallOrNewExpression === startingExpression) { return -1 /* Unknown */; } var fullCallOrNewExpressionEnd = sourceFile.getLineAndCharacterOfPosition(fullCallOrNewExpression.end); var startingExpressionEnd = sourceFile.getLineAndCharacterOfPosition(startingExpression.end); if (fullCallOrNewExpressionEnd.line === startingExpressionEnd.line) { return -1 /* Unknown */; } return findColumnForFirstNonWhitespaceCharacterInLine(fullCallOrNewExpressionEnd, sourceFile, options); } return -1 /* Unknown */; function getStartingExpression(node) { while (true) { switch (node.kind) { case 182 /* CallExpression */: case 183 /* NewExpression */: case 180 /* PropertyAccessExpression */: case 181 /* ElementAccessExpression */: node = node.expression; break; default: return node; } } } } function deriveActualIndentationFromList(list, index, sourceFile, options) { ts.Debug.assert(index >= 0 && index < list.length); var node = list[index]; // walk toward the start of the list starting from current node and check if the line is the same for all items. // if end line for item [i - 1] differs from the start line for item [i] - find column of the first non-whitespace character on the line of item [i] var lineAndCharacter = getStartLineAndCharacterForNode(node, sourceFile); for (var i = index - 1; i >= 0; i--) { if (list[i].kind === 26 /* CommaToken */) { continue; } // skip list items that ends on the same line with the current list element var prevEndLine = sourceFile.getLineAndCharacterOfPosition(list[i].end).line; if (prevEndLine !== lineAndCharacter.line) { return findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options); } lineAndCharacter = getStartLineAndCharacterForNode(list[i], sourceFile); } return -1 /* Unknown */; } function findColumnForFirstNonWhitespaceCharacterInLine(lineAndCharacter, sourceFile, options) { var lineStart = sourceFile.getPositionOfLineAndCharacter(lineAndCharacter.line, 0); return findFirstNonWhitespaceColumn(lineStart, lineStart + lineAndCharacter.character, sourceFile, options); } /** * Character is the actual index of the character since the beginning of the line. * Column - position of the character after expanding tabs to spaces. * "0\t2$" * value of 'character' for '$' is 3 * value of 'column' for '$' is 6 (assuming that tab size is 4) */ function findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options) { var character = 0; var column = 0; for (var pos = startPos; pos < endPos; pos++) { var ch = sourceFile.text.charCodeAt(pos); if (!ts.isWhiteSpaceSingleLine(ch)) { break; } if (ch === 9 /* tab */) { column += options.tabSize + (column % options.tabSize); } else { column++; } character++; } return { column: column, character: character }; } SmartIndenter.findFirstNonWhitespaceCharacterAndColumn = findFirstNonWhitespaceCharacterAndColumn; function findFirstNonWhitespaceColumn(startPos, endPos, sourceFile, options) { return findFirstNonWhitespaceCharacterAndColumn(startPos, endPos, sourceFile, options).column; } SmartIndenter.findFirstNonWhitespaceColumn = findFirstNonWhitespaceColumn; function nodeContentIsAlwaysIndented(kind) { switch (kind) { case 211 /* ExpressionStatement */: case 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 233 /* EnumDeclaration */: case 232 /* TypeAliasDeclaration */: case 178 /* ArrayLiteralExpression */: case 208 /* Block */: case 235 /* ModuleBlock */: case 179 /* ObjectLiteralExpression */: case 164 /* TypeLiteral */: case 173 /* MappedType */: case 166 /* TupleType */: case 236 /* CaseBlock */: case 262 /* DefaultClause */: case 261 /* CaseClause */: case 186 /* ParenthesizedExpression */: case 180 /* PropertyAccessExpression */: case 182 /* CallExpression */: case 183 /* NewExpression */: case 209 /* VariableStatement */: case 227 /* VariableDeclaration */: case 244 /* ExportAssignment */: case 220 /* ReturnStatement */: case 196 /* ConditionalExpression */: case 176 /* ArrayBindingPattern */: case 175 /* ObjectBindingPattern */: case 252 /* JsxOpeningElement */: case 251 /* JsxSelfClosingElement */: case 260 /* JsxExpression */: case 151 /* MethodSignature */: case 156 /* CallSignature */: case 157 /* ConstructSignature */: case 147 /* Parameter */: case 161 /* FunctionType */: case 162 /* ConstructorType */: case 169 /* ParenthesizedType */: case 184 /* TaggedTemplateExpression */: case 192 /* AwaitExpression */: case 246 /* NamedExports */: case 242 /* NamedImports */: case 247 /* ExportSpecifier */: case 243 /* ImportSpecifier */: case 265 /* PropertyAssignment */: case 150 /* PropertyDeclaration */: return true; } return false; } function nodeWillIndentChild(parent, child, indentByDefault) { var childKind = child ? child.kind : 0 /* Unknown */; switch (parent.kind) { case 213 /* DoStatement */: case 214 /* WhileStatement */: case 216 /* ForInStatement */: case 217 /* ForOfStatement */: case 215 /* ForStatement */: case 212 /* IfStatement */: case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 152 /* MethodDeclaration */: case 188 /* ArrowFunction */: case 153 /* Constructor */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return childKind !== 208 /* Block */; case 245 /* ExportDeclaration */: return childKind !== 246 /* NamedExports */; case 239 /* ImportDeclaration */: return childKind !== 240 /* ImportClause */ || (!!child.namedBindings && child.namedBindings.kind !== 242 /* NamedImports */); case 250 /* JsxElement */: return childKind !== 253 /* JsxClosingElement */; } // No explicit rule for given nodes so the result will follow the default value argument return indentByDefault; } SmartIndenter.nodeWillIndentChild = nodeWillIndentChild; function isControlFlowEndingStatement(kind, parent) { switch (kind) { case 220 /* ReturnStatement */: case 224 /* ThrowStatement */: switch (parent.kind) { case 208 /* Block */: var grandParent = parent.parent; switch (grandParent && grandParent.kind) { case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: // We may want to write inner functions after this. return false; default: return true; } case 261 /* CaseClause */: case 262 /* DefaultClause */: case 269 /* SourceFile */: case 235 /* ModuleBlock */: return true; default: throw ts.Debug.fail(); } case 218 /* ContinueStatement */: case 219 /* BreakStatement */: return true; default: return false; } } /** * True when the parent node should indent the given child by an explicit rule. * @param isNextChild If true, we are judging indent of a hypothetical child *after* this one, not the current child. */ function shouldIndentChildNode(parent, child, isNextChild) { if (isNextChild === void 0) { isNextChild = false; } return (nodeContentIsAlwaysIndented(parent.kind) || nodeWillIndentChild(parent, child, /*indentByDefault*/ false)) && !(isNextChild && child && isControlFlowEndingStatement(child.kind, parent)); } SmartIndenter.shouldIndentChildNode = shouldIndentChildNode; })(SmartIndenter = formatting.SmartIndenter || (formatting.SmartIndenter = {})); })(formatting = ts.formatting || (ts.formatting = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var textChanges; (function (textChanges) { /** * Currently for simplicity we store recovered positions on the node itself. * It can be changed to side-table later if we decide that current design is too invasive. */ function getPos(n) { var result = n.__pos; ts.Debug.assert(typeof result === "number"); return result; } function setPos(n, pos) { ts.Debug.assert(typeof pos === "number"); n.__pos = pos; } function getEnd(n) { var result = n.__end; ts.Debug.assert(typeof result === "number"); return result; } function setEnd(n, end) { ts.Debug.assert(typeof end === "number"); n.__end = end; } var Position; (function (Position) { Position[Position["FullStart"] = 0] = "FullStart"; Position[Position["Start"] = 1] = "Start"; })(Position = textChanges.Position || (textChanges.Position = {})); function skipWhitespacesAndLineBreaks(text, start) { return ts.skipTrivia(text, start, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); } function hasCommentsBeforeLineBreak(text, start) { var i = start; while (i < text.length) { var ch = text.charCodeAt(i); if (ts.isWhiteSpaceSingleLine(ch)) { i++; continue; } return ch === 47 /* slash */; } return false; } var ChangeKind; (function (ChangeKind) { ChangeKind[ChangeKind["Remove"] = 0] = "Remove"; ChangeKind[ChangeKind["ReplaceWithSingleNode"] = 1] = "ReplaceWithSingleNode"; ChangeKind[ChangeKind["ReplaceWithMultipleNodes"] = 2] = "ReplaceWithMultipleNodes"; })(ChangeKind || (ChangeKind = {})); function getSeparatorCharacter(separator) { return ts.tokenToString(separator.kind); } textChanges.getSeparatorCharacter = getSeparatorCharacter; function getAdjustedStartPosition(sourceFile, node, options, position) { if (options.useNonAdjustedStartPosition) { return node.getFullStart(); } var fullStart = node.getFullStart(); var start = node.getStart(sourceFile); if (fullStart === start) { return start; } var fullStartLine = ts.getLineStartPositionForPosition(fullStart, sourceFile); var startLine = ts.getLineStartPositionForPosition(start, sourceFile); if (startLine === fullStartLine) { // full start and start of the node are on the same line // a, b; // ^ ^ // | start // fullstart // when b is replaced - we usually want to keep the leading trvia // when b is deleted - we delete it return position === Position.Start ? start : fullStart; } // get start position of the line following the line that contains fullstart position // (but only if the fullstart isn't the very beginning of the file) var nextLineStart = fullStart > 0 ? 1 : 0; var adjustedStartPosition = ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, fullStartLine) + nextLineStart, sourceFile); // skip whitespaces/newlines adjustedStartPosition = skipWhitespacesAndLineBreaks(sourceFile.text, adjustedStartPosition); return ts.getStartPositionOfLine(ts.getLineOfLocalPosition(sourceFile, adjustedStartPosition), sourceFile); } textChanges.getAdjustedStartPosition = getAdjustedStartPosition; function getAdjustedEndPosition(sourceFile, node, options) { if (options.useNonAdjustedEndPosition || ts.isExpression(node)) { return node.getEnd(); } var end = node.getEnd(); var newEnd = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true); return newEnd !== end && ts.isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)) ? newEnd : end; } textChanges.getAdjustedEndPosition = getAdjustedEndPosition; /** * Checks if 'candidate' argument is a legal separator in the list that contains 'node' as an element */ function isSeparator(node, candidate) { return candidate && node.parent && (candidate.kind === 26 /* CommaToken */ || (candidate.kind === 25 /* SemicolonToken */ && node.parent.kind === 179 /* ObjectLiteralExpression */)); } function spaces(count) { var s = ""; for (var i = 0; i < count; i++) { s += " "; } return s; } var ChangeTracker = /** @class */ (function () { function ChangeTracker(newLine, formatContext, validator) { this.newLine = newLine; this.formatContext = formatContext; this.validator = validator; this.changes = []; this.newLineCharacter = ts.getNewLineCharacter({ newLine: newLine }); } ChangeTracker.fromContext = function (context) { return new ChangeTracker(context.newLineCharacter === "\n" ? 1 /* LineFeed */ : 0 /* CarriageReturnLineFeed */, context.formatContext); }; ChangeTracker.with = function (context, cb) { var tracker = ChangeTracker.fromContext(context); cb(tracker); return tracker.getChanges(); }; ChangeTracker.prototype.deleteRange = function (sourceFile, range) { this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: range }); return this; }; ChangeTracker.prototype.deleteNode = function (sourceFile, node, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, node, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, node, options); this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeRange = function (sourceFile, startNode, endNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.FullStart); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); this.changes.push({ kind: ChangeKind.Remove, sourceFile: sourceFile, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.deleteNodeInList = function (sourceFile, node) { var containingList = ts.formatting.SmartIndenter.getContainingList(node, sourceFile); if (!containingList) { ts.Debug.fail("node is not a list element"); return this; } var index = ts.indexOfNode(containingList, node); if (index < 0) { return this; } if (containingList.length === 1) { this.deleteNode(sourceFile, node); return this; } if (index !== containingList.length - 1) { var nextToken = ts.getTokenAtPosition(sourceFile, node.end, /*includeJsDocComment*/ false); if (nextToken && isSeparator(node, nextToken)) { // find first non-whitespace position in the leading trivia of the node var startPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); var nextElement = containingList[index + 1]; /// find first non-whitespace position in the leading trivia of the next node var endPosition = ts.skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, nextElement, {}, Position.FullStart), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true); // shift next node so its first non-whitespace position will be moved to the first non-whitespace position of the deleted node this.deleteRange(sourceFile, { pos: startPosition, end: endPosition }); } } else { var previousToken = ts.getTokenAtPosition(sourceFile, containingList[index - 1].end, /*includeJsDocComment*/ false); if (previousToken && isSeparator(node, previousToken)) { this.deleteNodeRange(sourceFile, previousToken, node); } } return this; }; ChangeTracker.prototype.replaceRange = function (sourceFile, range, newNode, options) { if (options === void 0) { options = {}; } this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: range, options: options, node: newNode }); return this; }; ChangeTracker.prototype.replaceNode = function (sourceFile, oldNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceNodeRange = function (sourceFile, startNode, endNode, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); return this.replaceWithSingle(sourceFile, startPosition, endPosition, newNode, options); }; ChangeTracker.prototype.replaceWithSingle = function (sourceFile, startPosition, endPosition, newNode, options) { this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.replaceWithMultiple = function (sourceFile, startPosition, endPosition, newNodes, options) { this.changes.push({ kind: ChangeKind.ReplaceWithMultipleNodes, sourceFile: sourceFile, options: options, nodes: newNodes, range: { pos: startPosition, end: endPosition } }); return this; }; ChangeTracker.prototype.replaceNodeWithNodes = function (sourceFile, oldNode, newNodes, options) { var startPosition = getAdjustedStartPosition(sourceFile, oldNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, oldNode, options); return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); }; ChangeTracker.prototype.replaceNodesWithNodes = function (sourceFile, oldNodes, newNodes, options) { var startPosition = getAdjustedStartPosition(sourceFile, oldNodes[0], options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, ts.lastOrUndefined(oldNodes), options); return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); }; ChangeTracker.prototype.replaceRangeWithNodes = function (sourceFile, range, newNodes, options) { return this.replaceWithMultiple(sourceFile, range.pos, range.end, newNodes, options); }; ChangeTracker.prototype.replaceNodeRangeWithNodes = function (sourceFile, startNode, endNode, newNodes, options) { var startPosition = getAdjustedStartPosition(sourceFile, startNode, options, Position.Start); var endPosition = getAdjustedEndPosition(sourceFile, endNode, options); return this.replaceWithMultiple(sourceFile, startPosition, endPosition, newNodes, options); }; ChangeTracker.prototype.insertNodeAt = function (sourceFile, pos, newNode, options) { if (options === void 0) { options = {}; } this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: options, node: newNode, range: { pos: pos, end: pos } }); return this; }; ChangeTracker.prototype.insertNodeBefore = function (sourceFile, before, newNode, options) { if (options === void 0) { options = {}; } var startPosition = getAdjustedStartPosition(sourceFile, before, options, Position.Start); return this.replaceWithSingle(sourceFile, startPosition, startPosition, newNode, options); }; ChangeTracker.prototype.insertNodeAfter = function (sourceFile, after, newNode, options) { if (options === void 0) { options = {}; } if ((ts.isStatementButNotDeclaration(after)) || after.kind === 150 /* PropertyDeclaration */ || after.kind === 149 /* PropertySignature */ || after.kind === 151 /* MethodSignature */) { // check if previous statement ends with semicolon // if not - insert semicolon to preserve the code from changing the meaning due to ASI if (sourceFile.text.charCodeAt(after.end - 1) !== 59 /* semicolon */) { this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, options: {}, range: { pos: after.end, end: after.end }, node: ts.createToken(25 /* SemicolonToken */) }); } } var endPosition = getAdjustedEndPosition(sourceFile, after, options); return this.replaceWithSingle(sourceFile, endPosition, endPosition, newNode, options); }; /** * This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range, * i.e. arguments in arguments lists, parameters in parameter lists etc. * Note that separators are part of the node in statements and class elements. */ ChangeTracker.prototype.insertNodeInListAfter = function (sourceFile, after, newNode) { var containingList = ts.formatting.SmartIndenter.getContainingList(after, sourceFile); if (!containingList) { ts.Debug.fail("node is not a list element"); return this; } var index = ts.indexOfNode(containingList, after); if (index < 0) { return this; } var end = after.getEnd(); if (index !== containingList.length - 1) { // any element except the last one // use next sibling as an anchor var nextToken = ts.getTokenAtPosition(sourceFile, after.end, /*includeJsDocComment*/ false); if (nextToken && isSeparator(after, nextToken)) { // for list // a, b, c // create change for adding 'e' after 'a' as // - find start of next element after a (it is b) // - use this start as start and end position in final change // - build text of change by formatting the text of node + separator + whitespace trivia of b // in multiline case it will work as // a, // b, // c, // result - '*' denotes leading trivia that will be inserted after new text (displayed as '#') // a,* // ***insertedtext# // ###b, // c, // find line and character of the next element var lineAndCharOfNextElement = ts.getLineAndCharacterOfPosition(sourceFile, skipWhitespacesAndLineBreaks(sourceFile.text, containingList[index + 1].getFullStart())); // find line and character of the token that precedes next element (usually it is separator) var lineAndCharOfNextToken = ts.getLineAndCharacterOfPosition(sourceFile, nextToken.end); var prefix = void 0; var startPos = void 0; if (lineAndCharOfNextToken.line === lineAndCharOfNextElement.line) { // next element is located on the same line with separator: // a,$$$$b // ^ ^ // | |-next element // |-separator // where $$$ is some leading trivia // for a newly inserted node we'll maintain the same relative position comparing to separator and replace leading trivia with spaces // a, x,$$$$b // ^ ^ ^ // | | |-next element // | |-new inserted node padded with spaces // |-separator startPos = nextToken.end; prefix = spaces(lineAndCharOfNextElement.character - lineAndCharOfNextToken.character); } else { // next element is located on different line that separator // let insert position be the beginning of the line that contains next element startPos = ts.getStartPositionOfLine(lineAndCharOfNextElement.line, sourceFile); } this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: startPos, end: containingList[index + 1].getStart(sourceFile) }, node: newNode, options: { prefix: prefix, // write separator and leading trivia of the next element as suffix suffix: "" + ts.tokenToString(nextToken.kind) + sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile)) } }); } } else { var afterStart = after.getStart(sourceFile); var afterStartLinePosition = ts.getLineStartPositionForPosition(afterStart, sourceFile); var separator = void 0; var multilineList = false; // insert element after the last element in the list that has more than one item // pick the element preceding the after element to: // - pick the separator // - determine if list is a multiline if (containingList.length === 1) { // if list has only one element then we'll format is as multiline if node has comment in trailing trivia, or as singleline otherwise // i.e. var x = 1 // this is x // | new element will be inserted at this position separator = 26 /* CommaToken */; } else { // element has more than one element, pick separator from the list var tokenBeforeInsertPosition = ts.findPrecedingToken(after.pos, sourceFile); separator = isSeparator(after, tokenBeforeInsertPosition) ? tokenBeforeInsertPosition.kind : 26 /* CommaToken */; // determine if list is multiline by checking lines of after element and element that precedes it. var afterMinusOneStartLinePosition = ts.getLineStartPositionForPosition(containingList[index - 1].getStart(sourceFile), sourceFile); multilineList = afterMinusOneStartLinePosition !== afterStartLinePosition; } if (hasCommentsBeforeLineBreak(sourceFile.text, after.end)) { // in this case we'll always treat containing list as multiline multilineList = true; } if (multilineList) { // insert separator immediately following the 'after' node to preserve comments in trailing trivia this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: ts.createToken(separator), options: {} }); // use the same indentation as 'after' item var indentation = ts.formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options); // insert element before the line break on the line that contains 'after' element var insertPos = ts.skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true, /*stopAtComments*/ false); if (insertPos !== end && ts.isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) { insertPos--; } this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: insertPos, end: insertPos }, node: newNode, options: { indentation: indentation, prefix: this.newLineCharacter } }); } else { this.changes.push({ kind: ChangeKind.ReplaceWithSingleNode, sourceFile: sourceFile, range: { pos: end, end: end }, node: newNode, options: { prefix: ts.tokenToString(separator) + " " } }); } } return this; }; ChangeTracker.prototype.getChanges = function () { var _this = this; var changesPerFile = ts.createMap(); // group changes per file for (var _i = 0, _a = this.changes; _i < _a.length; _i++) { var c = _a[_i]; var changesInFile = changesPerFile.get(c.sourceFile.path); if (!changesInFile) { changesPerFile.set(c.sourceFile.path, changesInFile = []); } changesInFile.push(c); } // convert changes var fileChangesList = []; changesPerFile.forEach(function (changesInFile) { var sourceFile = changesInFile[0].sourceFile; var fileTextChanges = { fileName: sourceFile.fileName, textChanges: [] }; for (var _i = 0, _a = ChangeTracker.normalize(changesInFile); _i < _a.length; _i++) { var c = _a[_i]; fileTextChanges.textChanges.push({ span: _this.computeSpan(c, sourceFile), newText: _this.computeNewText(c, sourceFile) }); } fileChangesList.push(fileTextChanges); }); return fileChangesList; }; ChangeTracker.prototype.computeSpan = function (change, _sourceFile) { return ts.createTextSpanFromBounds(change.range.pos, change.range.end); }; ChangeTracker.prototype.computeNewText = function (change, sourceFile) { var _this = this; if (change.kind === ChangeKind.Remove) { // deletion case return ""; } var options = change.options || {}; var text; var pos = change.range.pos; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; if (change.kind === ChangeKind.ReplaceWithMultipleNodes) { var parts = change.nodes.map(function (n) { return _this.getFormattedTextOfNode(n, sourceFile, pos, options); }); text = parts.join(change.options.nodeSeparator); } else { ts.Debug.assert(change.kind === ChangeKind.ReplaceWithSingleNode, "change.kind === ReplaceWithSingleNode"); text = this.getFormattedTextOfNode(change.node, sourceFile, pos, options); } // strip initial indentation (spaces or tabs) if text will be inserted in the middle of the line text = (posStartsLine || options.indentation !== undefined) ? text : text.replace(/^\s+/, ""); return (options.prefix || "") + text + (options.suffix || ""); }; ChangeTracker.prototype.getFormattedTextOfNode = function (node, sourceFile, pos, options) { var nonformattedText = getNonformattedText(node, sourceFile, this.newLine); if (this.validator) { this.validator(nonformattedText); } var formatOptions = this.formatContext.options; var posStartsLine = ts.getLineStartPositionForPosition(pos, sourceFile) === pos; var initialIndentation = options.indentation !== undefined ? options.indentation : (options.useIndentationFromFile !== false) ? ts.formatting.SmartIndenter.getIndentation(pos, sourceFile, formatOptions, posStartsLine || (options.prefix === this.newLineCharacter)) : 0; var delta = options.delta !== undefined ? options.delta : ts.formatting.SmartIndenter.shouldIndentChildNode(node) ? (formatOptions.indentSize || 0) : 0; return applyFormatting(nonformattedText, sourceFile, initialIndentation, delta, this.formatContext); }; ChangeTracker.normalize = function (changes) { // order changes by start position var normalized = ts.stableSort(changes, function (a, b) { return a.range.pos - b.range.pos; }); // verify that change intervals do not overlap, except possibly at end points. for (var i = 0; i < normalized.length - 2; i++) { ts.Debug.assert(normalized[i].range.end <= normalized[i + 1].range.pos); } return normalized; }; return ChangeTracker; }()); textChanges.ChangeTracker = ChangeTracker; function getNonformattedText(node, sourceFile, newLine) { var options = { newLine: newLine, target: sourceFile && sourceFile.languageVersion }; var writer = new Writer(ts.getNewLineCharacter(options)); var printer = ts.createPrinter(options, writer); printer.writeNode(4 /* Unspecified */, node, sourceFile, writer); return { text: writer.getText(), node: assignPositionsToNode(node) }; } function applyFormatting(nonFormattedText, sourceFile, initialIndentation, delta, formatContext) { var lineMap = ts.computeLineStarts(nonFormattedText.text); var file = { text: nonFormattedText.text, lineMap: lineMap, getLineAndCharacterOfPosition: function (pos) { return ts.computeLineAndCharacterOfPosition(lineMap, pos); } }; var changes = ts.formatting.formatNodeGivenIndentation(nonFormattedText.node, file, sourceFile.languageVariant, initialIndentation, delta, formatContext); return applyChanges(nonFormattedText.text, changes); } function applyChanges(text, changes) { for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; text = "" + text.substring(0, change.span.start) + change.newText + text.substring(ts.textSpanEnd(change.span)); } return text; } textChanges.applyChanges = applyChanges; function isTrivia(s) { return ts.skipTrivia(s, 0) === s.length; } function assignPositionsToNode(node) { var visited = ts.visitEachChild(node, assignPositionsToNode, ts.nullTransformationContext, assignPositionsToNodeArray, assignPositionsToNode); // create proxy node for non synthesized nodes var newNode = ts.nodeIsSynthesized(visited) ? visited : Object.create(visited); newNode.pos = getPos(node); newNode.end = getEnd(node); return newNode; } function assignPositionsToNodeArray(nodes, visitor, test, start, count) { var visited = ts.visitNodes(nodes, visitor, test, start, count); if (!visited) { return visited; } // clone nodearray if necessary var nodeArray = visited === nodes ? ts.createNodeArray(visited.slice(0)) : visited; nodeArray.pos = getPos(nodes); nodeArray.end = getEnd(nodes); return nodeArray; } var Writer = /** @class */ (function () { function Writer(newLine) { var _this = this; this.lastNonTriviaPosition = 0; this.writer = ts.createTextWriter(newLine); this.onEmitNode = function (hint, node, printCallback) { if (node) { setPos(node, _this.lastNonTriviaPosition); } printCallback(hint, node); if (node) { setEnd(node, _this.lastNonTriviaPosition); } }; this.onBeforeEmitNodeArray = function (nodes) { if (nodes) { setPos(nodes, _this.lastNonTriviaPosition); } }; this.onAfterEmitNodeArray = function (nodes) { if (nodes) { setEnd(nodes, _this.lastNonTriviaPosition); } }; this.onBeforeEmitToken = function (node) { if (node) { setPos(node, _this.lastNonTriviaPosition); } }; this.onAfterEmitToken = function (node) { if (node) { setEnd(node, _this.lastNonTriviaPosition); } }; } Writer.prototype.setLastNonTriviaPosition = function (s, force) { if (force || !isTrivia(s)) { this.lastNonTriviaPosition = this.writer.getTextPos(); var i = 0; while (ts.isWhiteSpaceLike(s.charCodeAt(s.length - i - 1))) { i++; } // trim trailing whitespaces this.lastNonTriviaPosition -= i; } }; Writer.prototype.write = function (s) { this.writer.write(s); this.setLastNonTriviaPosition(s, /*force*/ false); }; Writer.prototype.writeTextOfNode = function (text, node) { this.writer.writeTextOfNode(text, node); }; Writer.prototype.writeLine = function () { this.writer.writeLine(); }; Writer.prototype.increaseIndent = function () { this.writer.increaseIndent(); }; Writer.prototype.decreaseIndent = function () { this.writer.decreaseIndent(); }; Writer.prototype.getText = function () { return this.writer.getText(); }; Writer.prototype.rawWrite = function (s) { this.writer.rawWrite(s); this.setLastNonTriviaPosition(s, /*force*/ false); }; Writer.prototype.writeLiteral = function (s) { this.writer.writeLiteral(s); this.setLastNonTriviaPosition(s, /*force*/ true); }; Writer.prototype.getTextPos = function () { return this.writer.getTextPos(); }; Writer.prototype.getLine = function () { return this.writer.getLine(); }; Writer.prototype.getColumn = function () { return this.writer.getColumn(); }; Writer.prototype.getIndent = function () { return this.writer.getIndent(); }; Writer.prototype.isAtStartOfLine = function () { return this.writer.isAtStartOfLine(); }; Writer.prototype.reset = function () { this.writer.reset(); this.lastNonTriviaPosition = 0; }; return Writer; }()); })(textChanges = ts.textChanges || (ts.textChanges = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { var codeFixes = []; function registerCodeFix(codeFix) { ts.forEach(codeFix.errorCodes, function (error) { var fixes = codeFixes[error]; if (!fixes) { fixes = []; codeFixes[error] = fixes; } fixes.push(codeFix); }); } codefix.registerCodeFix = registerCodeFix; function getSupportedErrorCodes() { return Object.keys(codeFixes); } codefix.getSupportedErrorCodes = getSupportedErrorCodes; function getFixes(context) { var fixes = codeFixes[context.errorCode]; var allActions = []; ts.forEach(fixes, function (f) { var actions = f.getCodeActions(context); if (actions && actions.length > 0) { for (var _i = 0, actions_1 = actions; _i < actions_1.length; _i++) { var action = actions_1[_i]; if (action === undefined) { context.host.log("Action for error code " + context.errorCode + " added an invalid action entry; please log a bug"); } else { allActions.push(action); } } } }); return allActions; } codefix.getFixes = getFixes; })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var refactor; (function (refactor_1) { // A map with the refactor code as key, the refactor itself as value // e.g. nonSuggestableRefactors[refactorCode] -> the refactor you want var refactors = ts.createMap(); function registerRefactor(refactor) { refactors.set(refactor.name, refactor); } refactor_1.registerRefactor = registerRefactor; function getApplicableRefactors(context) { return ts.flatMapIter(refactors.values(), function (refactor) { return context.cancellationToken && context.cancellationToken.isCancellationRequested() ? undefined : refactor.getAvailableActions(context); }); } refactor_1.getApplicableRefactors = getApplicableRefactors; function getEditsForRefactor(context, refactorName, actionName) { var refactor = refactors.get(refactorName); return refactor && refactor.getEditsForAction(context, actionName); } refactor_1.getEditsForRefactor = getEditsForRefactor; })(refactor = ts.refactor || (ts.refactor = {})); function getRefactorContextLength(context) { return context.endPosition === undefined ? 0 : context.endPosition - context.startPosition; } ts.getRefactorContextLength = getRefactorContextLength; })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics._0_accepts_too_few_arguments_to_be_used_as_a_decorator_here_Did_you_mean_to_call_it_first_and_write_0.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); var decorator = ts.getAncestor(token, 148 /* Decorator */); ts.Debug.assert(!!decorator, "Expected position to be owned by a decorator."); var replacement = ts.createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined); var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); changeTracker.replaceNode(sourceFile, decorator.expression, replacement); return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Call_decorator_expression), changes: changeTracker.getChanges() }]; } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); var qualifiedName = ts.getAncestor(token, 144 /* QualifiedName */); ts.Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name."); if (!ts.isIdentifier(qualifiedName.left)) { return undefined; } var leftText = qualifiedName.left.getText(sourceFile); var rightText = qualifiedName.right.getText(sourceFile); var replacement = ts.createIndexedAccessTypeNode(ts.createTypeReferenceNode(qualifiedName.left, /*typeArguments*/ undefined), ts.createLiteralTypeNode(ts.createLiteral(rightText))); var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); changeTracker.replaceNode(sourceFile, qualifiedName, replacement); return [{ description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Rewrite_as_the_indexed_access_type_0), [leftText + "[\"" + rightText + "\"]"]), changes: changeTracker.getChanges() }]; } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Class_0_incorrectly_implements_interface_1.code], getCodeActions: getActionForClassLikeIncorrectImplementsInterface }); function getActionForClassLikeIncorrectImplementsInterface(context) { var sourceFile = context.sourceFile; var start = context.span.start; var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); var checker = context.program.getTypeChecker(); var classDeclaration = ts.getContainingClass(token); if (!classDeclaration) { return undefined; } var openBrace = ts.getOpenBraceOfClassLike(classDeclaration, sourceFile); var classType = checker.getTypeAtLocation(classDeclaration); var implementedTypeNodes = ts.getClassImplementsHeritageClauseElements(classDeclaration); var hasNumericIndexSignature = !!checker.getIndexTypeOfType(classType, 1 /* Number */); var hasStringIndexSignature = !!checker.getIndexTypeOfType(classType, 0 /* String */); var result = []; for (var _i = 0, implementedTypeNodes_2 = implementedTypeNodes; _i < implementedTypeNodes_2.length; _i++) { var implementedTypeNode = implementedTypeNodes_2[_i]; // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. var implementedType = checker.getTypeAtLocation(implementedTypeNode); var implementedTypeSymbols = checker.getPropertiesOfType(implementedType); var nonPrivateMembers = implementedTypeSymbols.filter(function (symbol) { return !(ts.getModifierFlags(symbol.valueDeclaration) & 8 /* Private */); }); var newNodes = []; createAndAddMissingIndexSignatureDeclaration(implementedType, 1 /* Number */, hasNumericIndexSignature, newNodes); createAndAddMissingIndexSignatureDeclaration(implementedType, 0 /* String */, hasStringIndexSignature, newNodes); newNodes = newNodes.concat(codefix.createMissingMemberNodes(classDeclaration, nonPrivateMembers, checker)); var message = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_interface_0), [implementedTypeNode.getText()]); if (newNodes.length > 0) { pushAction(result, newNodes, message); } } return result; function createAndAddMissingIndexSignatureDeclaration(type, kind, hasIndexSigOfKind, newNodes) { if (hasIndexSigOfKind) { return; } var indexInfoOfKind = checker.getIndexInfoOfType(type, kind); if (!indexInfoOfKind) { return; } var newIndexSignatureDeclaration = checker.indexInfoToIndexSignatureDeclaration(indexInfoOfKind, kind, classDeclaration); newNodes.push(newIndexSignatureDeclaration); } function pushAction(result, newNodes, description) { result.push({ description: description, changes: codefix.newNodesToChanges(newNodes, openBrace, context) }); } } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1.code, ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code], getCodeActions: getActionsForAddMissingMember }); function getActionsForAddMissingMember(context) { var tokenSourceFile = context.sourceFile; var start = context.span.start; // The identifier of the missing property. eg: // this.missing = 1; // ^^^^^^^ var token = ts.getTokenAtPosition(tokenSourceFile, start, /*includeJsDocComment*/ false); if (token.kind !== 71 /* Identifier */) { return undefined; } if (!ts.isPropertyAccessExpression(token.parent)) { return undefined; } var tokenName = token.getText(tokenSourceFile); var makeStatic = false; var classDeclaration; if (token.parent.expression.kind === 99 /* ThisKeyword */) { var containingClassMemberDeclaration = ts.getThisContainer(token, /*includeArrowFunctions*/ false); if (!ts.isClassElement(containingClassMemberDeclaration)) { return undefined; } classDeclaration = containingClassMemberDeclaration.parent; // Property accesses on `this` in a static method are accesses of a static member. makeStatic = classDeclaration && ts.hasModifier(containingClassMemberDeclaration, 32 /* Static */); } else { var checker = context.program.getTypeChecker(); var leftExpression = token.parent.expression; var leftExpressionType = checker.getTypeAtLocation(leftExpression); if (leftExpressionType.flags & 65536 /* Object */) { var symbol = leftExpressionType.symbol; if (symbol.flags & 32 /* Class */) { classDeclaration = symbol.declarations && symbol.declarations[0]; if (leftExpressionType !== checker.getDeclaredTypeOfSymbol(symbol)) { // The expression is a class symbol but the type is not the instance-side. makeStatic = true; } } } } if (!classDeclaration || !ts.isClassLike(classDeclaration)) { return undefined; } var classDeclarationSourceFile = ts.getSourceFileOfNode(classDeclaration); var classOpenBrace = ts.getOpenBraceOfClassLike(classDeclaration, classDeclarationSourceFile); return ts.isInJavaScriptFile(classDeclarationSourceFile) ? getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) : getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic); function getActionsForAddMissingMemberInJavaScriptFile(classDeclaration, makeStatic) { var actions; var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ false); if (methodCodeAction) { actions = [methodCodeAction]; } if (makeStatic) { if (classDeclaration.kind === 200 /* ClassExpression */) { return actions; } var className = classDeclaration.name.getText(); var staticInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createIdentifier(className), tokenName), ts.createIdentifier("undefined"))); var staticInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context); staticInitializationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classDeclaration, staticInitialization, { prefix: context.newLineCharacter, suffix: context.newLineCharacter }); var initializeStaticAction = { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_static_property_0), [tokenName]), changes: staticInitializationChangeTracker.getChanges() }; (actions || (actions = [])).push(initializeStaticAction); return actions; } else { var classConstructor = ts.getFirstConstructorWithBody(classDeclaration); if (!classConstructor) { return actions; } var propertyInitialization = ts.createStatement(ts.createAssignment(ts.createPropertyAccess(ts.createThis(), tokenName), ts.createIdentifier("undefined"))); var propertyInitializationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context); propertyInitializationChangeTracker.insertNodeBefore(classDeclarationSourceFile, classConstructor.body.getLastToken(), propertyInitialization, { suffix: context.newLineCharacter }); var initializeAction = { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Initialize_property_0_in_the_constructor), [tokenName]), changes: propertyInitializationChangeTracker.getChanges() }; (actions || (actions = [])).push(initializeAction); return actions; } } function getActionsForAddMissingMemberInTypeScriptFile(classDeclaration, makeStatic) { var actions; var methodCodeAction = getActionForMethodDeclaration(/*includeTypeScriptSyntax*/ true); if (methodCodeAction) { actions = [methodCodeAction]; } var typeNode; if (token.parent.parent.kind === 195 /* BinaryExpression */) { var binaryExpression = token.parent.parent; var otherExpression = token.parent === binaryExpression.left ? binaryExpression.right : binaryExpression.left; var checker = context.program.getTypeChecker(); var widenedType = checker.getWidenedType(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(otherExpression))); typeNode = checker.typeToTypeNode(widenedType, classDeclaration); } typeNode = typeNode || ts.createKeywordTypeNode(119 /* AnyKeyword */); var property = ts.createProperty( /*decorators*/ undefined, /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, tokenName, /*questionToken*/ undefined, typeNode, /*initializer*/ undefined); var propertyChangeTracker = ts.textChanges.ChangeTracker.fromContext(context); propertyChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, property, { suffix: context.newLineCharacter }); var diag = makeStatic ? ts.Diagnostics.Declare_static_property_0 : ts.Diagnostics.Declare_property_0; actions = ts.append(actions, { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]), changes: propertyChangeTracker.getChanges() }); if (!makeStatic) { // Index signatures cannot have the static modifier. var stringTypeNode = ts.createKeywordTypeNode(136 /* StringKeyword */); var indexingParameter = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "x", /*questionToken*/ undefined, stringTypeNode, /*initializer*/ undefined); var indexSignature = ts.createIndexSignature( /*decorators*/ undefined, /*modifiers*/ undefined, [indexingParameter], typeNode); var indexSignatureChangeTracker = ts.textChanges.ChangeTracker.fromContext(context); indexSignatureChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, indexSignature, { suffix: context.newLineCharacter }); actions.push({ description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Add_index_signature_for_property_0), [tokenName]), changes: indexSignatureChangeTracker.getChanges() }); } return actions; } function getActionForMethodDeclaration(includeTypeScriptSyntax) { if (token.parent.parent.kind === 182 /* CallExpression */) { var callExpression = token.parent.parent; var methodDeclaration = codefix.createMethodFromCallExpression(callExpression, tokenName, includeTypeScriptSyntax, makeStatic); var methodDeclarationChangeTracker = ts.textChanges.ChangeTracker.fromContext(context); methodDeclarationChangeTracker.insertNodeAfter(classDeclarationSourceFile, classOpenBrace, methodDeclaration, { suffix: context.newLineCharacter }); var diag = makeStatic ? ts.Diagnostics.Declare_static_method_0 : ts.Diagnostics.Declare_method_0; return { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(diag), [tokenName]), changes: methodDeclarationChangeTracker.getChanges() }; } } } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Property_0_does_not_exist_on_type_1_Did_you_mean_2.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code], getCodeActions: getActionsForCorrectSpelling }); function getActionsForCorrectSpelling(context) { var sourceFile = context.sourceFile; // This is the identifier of the misspelled word. eg: // this.speling = 1; // ^^^^^^^ var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); // TODO: GH#15852 var checker = context.program.getTypeChecker(); var suggestion; if (ts.isPropertyAccessExpression(node.parent) && node.parent.name === node) { ts.Debug.assert(node.kind === 71 /* Identifier */); var containingType = checker.getTypeAtLocation(node.parent.expression); suggestion = checker.getSuggestionForNonexistentProperty(node, containingType); } else { var meaning = ts.getMeaningFromLocation(node); var name = ts.getTextOfNode(node); ts.Debug.assert(name !== undefined, "name should be defined"); suggestion = checker.getSuggestionForNonexistentSymbol(node, name, convertSemanticMeaningToSymbolFlags(meaning)); } if (suggestion) { return [{ description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_spelling_to_0), [suggestion]), changes: [{ fileName: sourceFile.fileName, textChanges: [{ span: { start: node.getStart(), length: node.getWidth() }, newText: suggestion }], }], }]; } } function convertSemanticMeaningToSymbolFlags(meaning) { var flags = 0; if (meaning & 4 /* Namespace */) { flags |= 1920 /* Namespace */; } if (meaning & 2 /* Type */) { flags |= 793064 /* Type */; } if (meaning & 1 /* Value */) { flags |= 107455 /* Value */; } return flags; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ ts.Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code, ], getCodeActions: function (context) { var sourceFile = context.sourceFile, start = context.span.start; var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); if (!ts.isStringLiteral(token)) { throw ts.Debug.fail(); // These errors should only happen on the module name. } var action = tryGetCodeActionForInstallPackageTypes(context.host, sourceFile.fileName, token.text); return action && [action]; }, }); function tryGetCodeActionForInstallPackageTypes(host, fileName, moduleName) { var packageName = ts.getPackageName(moduleName).packageName; if (!host.isKnownTypesPackageName(packageName)) { // If !registry, registry not available yet, can't do anything. return undefined; } var typesPackageName = ts.getTypesPackageName(packageName); return { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Install_0), [typesPackageName]), changes: [], commands: [{ type: "install package", file: fileName, packageName: typesPackageName }], }; } codefix.tryGetCodeActionForInstallPackageTypes = tryGetCodeActionForInstallPackageTypes; })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2.code], getCodeActions: getActionForClassLikeMissingAbstractMember }); codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Non_abstract_class_expression_does_not_implement_inherited_abstract_member_0_from_class_1.code], getCodeActions: getActionForClassLikeMissingAbstractMember }); function getActionForClassLikeMissingAbstractMember(context) { var sourceFile = context.sourceFile; var start = context.span.start; // This is the identifier in the case of a class declaration // or the class keyword token in the case of a class expression. var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); var checker = context.program.getTypeChecker(); if (ts.isClassLike(token.parent)) { var classDeclaration = token.parent; var extendsNode = ts.getClassExtendsHeritageClauseElement(classDeclaration); var instantiatedExtendsType = checker.getTypeAtLocation(extendsNode); // Note that this is ultimately derived from a map indexed by symbol names, // so duplicates cannot occur. var extendsSymbols = checker.getPropertiesOfType(instantiatedExtendsType); var abstractAndNonPrivateExtendsSymbols = extendsSymbols.filter(symbolPointsToNonPrivateAndAbstractMember); var newNodes = codefix.createMissingMemberNodes(classDeclaration, abstractAndNonPrivateExtendsSymbols, checker); var changes = codefix.newNodesToChanges(newNodes, ts.getOpenBraceOfClassLike(classDeclaration, sourceFile), context); if (changes && changes.length > 0) { return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Implement_inherited_abstract_class), changes: changes }]; } } return undefined; } function symbolPointsToNonPrivateAndAbstractMember(symbol) { var decls = symbol.getDeclarations(); ts.Debug.assert(!!(decls && decls.length > 0)); var flags = ts.getModifierFlags(decls[0]); return !(flags & 8 /* Private */) && !!(flags & 128 /* Abstract */); } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); if (token.kind !== 99 /* ThisKeyword */) { return undefined; } var constructor = ts.getContainingFunction(token); var superCall = findSuperCall(constructor.body); if (!superCall) { return undefined; } // figure out if the `this` access is actually inside the supercall // i.e. super(this.a), since in that case we won't suggest a fix if (superCall.expression && superCall.expression.kind === 182 /* CallExpression */) { var expressionArguments = superCall.expression.arguments; for (var _i = 0, expressionArguments_1 = expressionArguments; _i < expressionArguments_1.length; _i++) { var arg = expressionArguments_1[_i]; if (arg.expression === token) { return undefined; } } } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(constructor, sourceFile), superCall, { suffix: context.newLineCharacter }); changeTracker.deleteNode(sourceFile, superCall); return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Make_super_call_the_first_statement_in_the_constructor), changes: changeTracker.getChanges() }]; function findSuperCall(n) { if (n.kind === 211 /* ExpressionStatement */ && ts.isSuperCall(n.expression)) { return n; } if (ts.isFunctionLike(n)) { return undefined; } return ts.forEachChild(n, findSuperCall); } } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Constructors_for_derived_classes_must_contain_a_super_call.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); if (token.kind !== 123 /* ConstructorKeyword */) { return undefined; } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); var superCall = ts.createStatement(ts.createCall(ts.createSuper(), /*typeArguments*/ undefined, /*argumentsArray*/ ts.emptyArray)); changeTracker.insertNodeAfter(sourceFile, ts.getOpenBrace(token.parent, sourceFile), superCall, { suffix: context.newLineCharacter }); return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_missing_super_call), changes: changeTracker.getChanges() }]; } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Cannot_extend_an_interface_0_Did_you_mean_implements.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var start = context.span.start; var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); var classDeclNode = ts.getContainingClass(token); if (!(token.kind === 71 /* Identifier */ && ts.isClassLike(classDeclNode))) { return undefined; } var heritageClauses = classDeclNode.heritageClauses; if (!(heritageClauses && heritageClauses.length > 0)) { return undefined; } var extendsToken = heritageClauses[0].getFirstToken(); if (!(extendsToken && extendsToken.kind === 85 /* ExtendsKeyword */)) { return undefined; } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); changeTracker.replaceNode(sourceFile, extendsToken, ts.createToken(108 /* ImplementsKeyword */)); // We replace existing keywords with commas. for (var i = 1; i < heritageClauses.length; i++) { var keywordToken = heritageClauses[i].getFirstToken(); if (keywordToken) { changeTracker.replaceNode(sourceFile, keywordToken, ts.createToken(26 /* CommaToken */)); } } var result = [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Change_extends_to_implements), changes: changeTracker.getChanges() }]; return result; } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.Cannot_find_name_0_Did_you_mean_the_instance_member_this_0.code], getCodeActions: function (context) { var sourceFile = context.sourceFile; var token = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); if (token.kind !== 71 /* Identifier */) { return undefined; } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); changeTracker.replaceNode(sourceFile, token, ts.createPropertyAccess(ts.createThis(), token)); return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Add_this_to_unresolved_variable), changes: changeTracker.getChanges() }]; } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ ts.Diagnostics._0_is_declared_but_its_value_is_never_read.code, ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code ], getCodeActions: function (context) { var sourceFile = context.sourceFile; var start = context.span.start; var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); // this handles var ["computed"] = 12; if (token.kind === 21 /* OpenBracketToken */) { token = ts.getTokenAtPosition(sourceFile, start + 1, /*includeJsDocComment*/ false); } switch (token.kind) { case 71 /* Identifier */: return deleteIdentifierOrPrefixWithUnderscore(token, context.errorCode); case 150 /* PropertyDeclaration */: case 241 /* NamespaceImport */: return [deleteNode(token.parent)]; default: return deleteDefault(); } function deleteDefault() { if (ts.isDeclarationName(token)) { return [deleteNode(token.parent)]; } else if (ts.isLiteralComputedPropertyDeclarationName(token)) { return [deleteNode(token.parent.parent)]; } else { return undefined; } } function prefixIdentifierWithUnderscore(identifier) { var startPosition = identifier.getStart(sourceFile, /*includeJsDocComment*/ false); return { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Prefix_0_with_an_underscore), { 0: token.getText() }), changes: [{ fileName: sourceFile.path, textChanges: [{ span: { start: startPosition, length: 0 }, newText: "_" }] }] }; } function deleteIdentifierOrPrefixWithUnderscore(identifier, errorCode) { var parent = identifier.parent; switch (parent.kind) { case 227 /* VariableDeclaration */: return deleteVariableDeclarationOrPrefixWithUnderscore(identifier, parent); case 146 /* TypeParameter */: var typeParameters = parent.parent.typeParameters; if (typeParameters.length === 1) { var previousToken = ts.getTokenAtPosition(sourceFile, typeParameters.pos - 1, /*includeJsDocComment*/ false); var nextToken = ts.getTokenAtPosition(sourceFile, typeParameters.end, /*includeJsDocComment*/ false); ts.Debug.assert(previousToken.kind === 27 /* LessThanToken */); ts.Debug.assert(nextToken.kind === 29 /* GreaterThanToken */); return [deleteNodeRange(previousToken, nextToken)]; } else { return [deleteNodeInList(parent)]; } case 147 /* Parameter */: var functionDeclaration = parent.parent; var deleteAction = functionDeclaration.parameters.length === 1 ? deleteNode(parent) : deleteNodeInList(parent); return errorCode === ts.Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code ? [deleteAction] : [deleteAction, prefixIdentifierWithUnderscore(identifier)]; // handle case where 'import a = A;' case 238 /* ImportEqualsDeclaration */: var importEquals = ts.getAncestor(identifier, 238 /* ImportEqualsDeclaration */); return [deleteNode(importEquals)]; case 243 /* ImportSpecifier */: var namedImports = parent.parent; if (namedImports.elements.length === 1) { return deleteNamedImportBinding(namedImports); } else { // delete import specifier return [deleteNodeInList(parent)]; } case 240 /* ImportClause */:// this covers both 'import |d|' and 'import |d,| *' var importClause = parent; if (!importClause.namedBindings) { var importDecl = ts.getAncestor(importClause, 239 /* ImportDeclaration */); return [deleteNode(importDecl)]; } else { // import |d,| * as ns from './file' var start_6 = importClause.name.getStart(sourceFile); var nextToken = ts.getTokenAtPosition(sourceFile, importClause.name.end, /*includeJsDocComment*/ false); if (nextToken && nextToken.kind === 26 /* CommaToken */) { // shift first non-whitespace position after comma to the start position of the node return [deleteRange({ pos: start_6, end: ts.skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) })]; } else { return [deleteNode(importClause.name)]; } } case 241 /* NamespaceImport */: return deleteNamedImportBinding(parent); default: return deleteDefault(); } } function deleteNamedImportBinding(namedBindings) { if (namedBindings.parent.name) { // Delete named imports while preserving the default import // import d|, * as ns| from './file' // import d|, { a }| from './file' var previousToken = ts.getTokenAtPosition(sourceFile, namedBindings.pos - 1, /*includeJsDocComment*/ false); if (previousToken && previousToken.kind === 26 /* CommaToken */) { return [deleteRange({ pos: previousToken.getStart(), end: namedBindings.end })]; } return undefined; } else { // Delete the entire import declaration // |import * as ns from './file'| // |import { a } from './file'| var importDecl = ts.getAncestor(namedBindings, 239 /* ImportDeclaration */); return [deleteNode(importDecl)]; } } // token.parent is a variableDeclaration function deleteVariableDeclarationOrPrefixWithUnderscore(identifier, varDecl) { switch (varDecl.parent.parent.kind) { case 215 /* ForStatement */: var forStatement = varDecl.parent.parent; var forInitializer = forStatement.initializer; return [forInitializer.declarations.length === 1 ? deleteNode(forInitializer) : deleteNodeInList(varDecl)]; case 217 /* ForOfStatement */: var forOfStatement = varDecl.parent.parent; ts.Debug.assert(forOfStatement.initializer.kind === 228 /* VariableDeclarationList */); var forOfInitializer = forOfStatement.initializer; return [ replaceNode(forOfInitializer.declarations[0], ts.createObjectLiteral()), prefixIdentifierWithUnderscore(identifier) ]; case 216 /* ForInStatement */: // There is no valid fix in the case of: // for .. in return [prefixIdentifierWithUnderscore(identifier)]; default: var variableStatement = varDecl.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { return [deleteNode(variableStatement)]; } else { return [deleteNodeInList(varDecl)]; } } } function deleteNode(n) { return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNode(sourceFile, n)); } function deleteRange(range) { return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteRange(sourceFile, range)); } function deleteNodeInList(n) { return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeInList(sourceFile, n)); } function deleteNodeRange(start, end) { return makeChange(ts.textChanges.ChangeTracker.fromContext(context).deleteNodeRange(sourceFile, start, end)); } function replaceNode(n, newNode) { return makeChange(ts.textChanges.ChangeTracker.fromContext(context).replaceNode(sourceFile, n, newNode)); } function makeChange(changeTracker) { return { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), changes: changeTracker.getChanges() }; } } }); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ts.Diagnostics.JSDoc_types_can_only_be_used_inside_documentation_comments.code], getCodeActions: getActionsForJSDocTypes }); function getActionsForJSDocTypes(context) { var sourceFile = context.sourceFile; var node = ts.getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false); // NOTE: Some locations are not handled yet: // MappedTypeNode.typeParameters and SignatureDeclaration.typeParameters, as well as CallExpression.typeArguments var decl = ts.findAncestor(node, function (n) { return n.kind === 203 /* AsExpression */ || n.kind === 156 /* CallSignature */ || n.kind === 157 /* ConstructSignature */ || n.kind === 229 /* FunctionDeclaration */ || n.kind === 154 /* GetAccessor */ || n.kind === 158 /* IndexSignature */ || n.kind === 173 /* MappedType */ || n.kind === 152 /* MethodDeclaration */ || n.kind === 151 /* MethodSignature */ || n.kind === 147 /* Parameter */ || n.kind === 150 /* PropertyDeclaration */ || n.kind === 149 /* PropertySignature */ || n.kind === 155 /* SetAccessor */ || n.kind === 232 /* TypeAliasDeclaration */ || n.kind === 185 /* TypeAssertionExpression */ || n.kind === 227 /* VariableDeclaration */; }); if (!decl) return; var checker = context.program.getTypeChecker(); var jsdocType = decl.type; if (!jsdocType) return; var original = ts.getTextOfNode(jsdocType); var type = checker.getTypeFromTypeNode(jsdocType); var actions = [createAction(jsdocType, sourceFile.fileName, original, checker.typeToString(type, /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */))]; if (jsdocType.kind === 274 /* JSDocNullableType */) { // for nullable types, suggest the flow-compatible `T | null | undefined` // in addition to the jsdoc/closure-compatible `T | null` var replacementWithUndefined = checker.typeToString(checker.getNullableType(type, 4096 /* Undefined */), /*enclosingDeclaration*/ undefined, 8 /* NoTruncation */); actions.push(createAction(jsdocType, sourceFile.fileName, original, replacementWithUndefined)); } return actions; } function createAction(declaration, fileName, original, replacement) { return { description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Change_0_to_1), [original, replacement]), changes: [{ fileName: fileName, textChanges: [{ span: { start: declaration.getStart(), length: declaration.getWidth() }, newText: replacement }] }], }; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { var ChangeTracker = ts.textChanges.ChangeTracker; codefix.registerCodeFix({ errorCodes: [ ts.Diagnostics.Cannot_find_name_0.code, ts.Diagnostics.Cannot_find_name_0_Did_you_mean_1.code, ts.Diagnostics.Cannot_find_namespace_0.code, ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code ], getCodeActions: getImportCodeActions }); var ModuleSpecifierComparison; (function (ModuleSpecifierComparison) { ModuleSpecifierComparison[ModuleSpecifierComparison["Better"] = 0] = "Better"; ModuleSpecifierComparison[ModuleSpecifierComparison["Equal"] = 1] = "Equal"; ModuleSpecifierComparison[ModuleSpecifierComparison["Worse"] = 2] = "Worse"; })(ModuleSpecifierComparison || (ModuleSpecifierComparison = {})); var ImportCodeActionMap = /** @class */ (function () { function ImportCodeActionMap() { this.symbolIdToActionMap = []; } ImportCodeActionMap.prototype.addAction = function (symbolId, newAction) { var actions = this.symbolIdToActionMap[symbolId]; if (!actions) { this.symbolIdToActionMap[symbolId] = [newAction]; return; } if (newAction.kind === "CodeChange") { actions.push(newAction); return; } var updatedNewImports = []; for (var _i = 0, _a = this.symbolIdToActionMap[symbolId]; _i < _a.length; _i++) { var existingAction = _a[_i]; if (existingAction.kind === "CodeChange") { // only import actions should compare updatedNewImports.push(existingAction); continue; } switch (this.compareModuleSpecifiers(existingAction.moduleSpecifier, newAction.moduleSpecifier)) { case 0 /* Better */: // the new one is not worth considering if it is a new import. // However if it is instead a insertion into existing import, the user might want to use // the module specifier even it is worse by our standards. So keep it. if (newAction.kind === "NewImport") { return; } // falls through case 1 /* Equal */: // the current one is safe. But it is still possible that the new one is worse // than another existing one. For example, you may have new imports from "./foo/bar" // and "bar", when the new one is "bar/bar2" and the current one is "./foo/bar". The new // one and the current one are not comparable (one relative path and one absolute path), // but the new one is worse than the other one, so should not add to the list. updatedNewImports.push(existingAction); break; case 2 /* Worse */: // the existing one is worse, remove from the list. continue; } } // if we reach here, it means the new one is better or equal to all of the existing ones. updatedNewImports.push(newAction); this.symbolIdToActionMap[symbolId] = updatedNewImports; }; ImportCodeActionMap.prototype.addActions = function (symbolId, newActions) { for (var _i = 0, newActions_1 = newActions; _i < newActions_1.length; _i++) { var newAction = newActions_1[_i]; this.addAction(symbolId, newAction); } }; ImportCodeActionMap.prototype.getAllActions = function () { var result = []; for (var key in this.symbolIdToActionMap) { result = ts.concatenate(result, this.symbolIdToActionMap[key]); } return result; }; ImportCodeActionMap.prototype.compareModuleSpecifiers = function (moduleSpecifier1, moduleSpecifier2) { if (moduleSpecifier1 === moduleSpecifier2) { return 1 /* Equal */; } // if moduleSpecifier1 (ms1) is a substring of ms2, then it is better if (moduleSpecifier2.indexOf(moduleSpecifier1) === 0) { return 0 /* Better */; } if (moduleSpecifier1.indexOf(moduleSpecifier2) === 0) { return 2 /* Worse */; } // if both are relative paths, and ms1 has fewer levels, then it is better if (ts.isExternalModuleNameRelative(moduleSpecifier1) && ts.isExternalModuleNameRelative(moduleSpecifier2)) { var regex = new RegExp(ts.directorySeparator, "g"); var moduleSpecifier1LevelCount = (moduleSpecifier1.match(regex) || []).length; var moduleSpecifier2LevelCount = (moduleSpecifier2.match(regex) || []).length; return moduleSpecifier1LevelCount < moduleSpecifier2LevelCount ? 0 /* Better */ : moduleSpecifier1LevelCount === moduleSpecifier2LevelCount ? 1 /* Equal */ : 2 /* Worse */; } // the equal cases include when the two specifiers are not comparable. return 1 /* Equal */; }; return ImportCodeActionMap; }()); function createCodeAction(description, diagnosticArgs, changes, kind, moduleSpecifier) { return { description: ts.formatMessage.apply(undefined, [undefined, description].concat(diagnosticArgs)), changes: changes, kind: kind, moduleSpecifier: moduleSpecifier }; } function convertToImportCodeFixContext(context) { var useCaseSensitiveFileNames = context.host.useCaseSensitiveFileNames ? context.host.useCaseSensitiveFileNames() : false; var checker = context.program.getTypeChecker(); var symbolToken = ts.getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false); return { host: context.host, newLineCharacter: context.newLineCharacter, formatContext: context.formatContext, sourceFile: context.sourceFile, checker: checker, compilerOptions: context.program.getCompilerOptions(), cachedImportDeclarations: [], getCanonicalFileName: ts.createGetCanonicalFileName(useCaseSensitiveFileNames), symbolName: symbolToken.getText(), symbolToken: symbolToken, }; } var ImportKind; (function (ImportKind) { ImportKind[ImportKind["Named"] = 0] = "Named"; ImportKind[ImportKind["Default"] = 1] = "Default"; ImportKind[ImportKind["Namespace"] = 2] = "Namespace"; ImportKind[ImportKind["Equals"] = 3] = "Equals"; })(ImportKind = codefix.ImportKind || (codefix.ImportKind = {})); function getCodeActionForImport(moduleSymbols, context) { moduleSymbols = ts.toArray(moduleSymbols); var declarations = ts.flatMap(moduleSymbols, function (moduleSymbol) { return getImportDeclarations(moduleSymbol, context.checker, context.sourceFile, context.cachedImportDeclarations); }); var actions = []; if (context.symbolToken) { // It is possible that multiple import statements with the same specifier exist in the file. // e.g. // // import * as ns from "foo"; // import { member1, member2 } from "foo"; // // member3/**/ <-- cusor here // // in this case we should provie 2 actions: // 1. change "member3" to "ns.member3" // 2. add "member3" to the second import statement's import list // and it is up to the user to decide which one fits best. for (var _i = 0, declarations_13 = declarations; _i < declarations_13.length; _i++) { var declaration = declarations_13[_i]; var namespace = getNamespaceImportName(declaration); if (namespace) { actions.push(getCodeActionForUseExistingNamespaceImport(namespace.text, context, context.symbolToken)); } } } return actions.concat(getCodeActionsForAddImport(moduleSymbols, context, declarations)); } codefix.getCodeActionForImport = getCodeActionForImport; function getNamespaceImportName(declaration) { if (declaration.kind === 239 /* ImportDeclaration */) { var namedBindings = declaration.importClause && ts.isImportClause(declaration.importClause) && declaration.importClause.namedBindings; return namedBindings && namedBindings.kind === 241 /* NamespaceImport */ ? namedBindings.name : undefined; } else { return declaration.name; } } // TODO(anhans): This doesn't seem important to cache... just use an iterator instead of creating a new array? function getImportDeclarations(moduleSymbol, checker, _a, cachedImportDeclarations) { var imports = _a.imports; if (cachedImportDeclarations === void 0) { cachedImportDeclarations = []; } var moduleSymbolId = ts.getUniqueSymbolId(moduleSymbol, checker); var cached = cachedImportDeclarations[moduleSymbolId]; if (!cached) { cached = cachedImportDeclarations[moduleSymbolId] = ts.mapDefined(imports, function (importModuleSpecifier) { return checker.getSymbolAtLocation(importModuleSpecifier) === moduleSymbol ? getImportDeclaration(importModuleSpecifier) : undefined; }); } return cached; } function getImportDeclaration(_a) { var parent = _a.parent; switch (parent.kind) { case 239 /* ImportDeclaration */: return parent; case 249 /* ExternalModuleReference */: return parent.parent; case 245 /* ExportDeclaration */: case 182 /* CallExpression */:// For "require()" calls // Ignore these, can't add imports to them. return undefined; default: ts.Debug.fail(); } } function getCodeActionForNewImport(context, moduleSpecifier) { var kind = context.kind, sourceFile = context.sourceFile, newLineCharacter = context.newLineCharacter, symbolName = context.symbolName; var lastImportDeclaration = ts.findLast(sourceFile.statements, ts.isAnyImportSyntax); var moduleSpecifierWithoutQuotes = ts.stripQuotes(moduleSpecifier); var quotedModuleSpecifier = createStringLiteralWithQuoteStyle(sourceFile, moduleSpecifierWithoutQuotes); var importDecl = kind !== 3 /* Equals */ ? ts.createImportDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, createImportClauseOfKind(kind, symbolName), quotedModuleSpecifier) : ts.createImportEqualsDeclaration( /*decorators*/ undefined, /*modifiers*/ undefined, ts.createIdentifier(symbolName), ts.createExternalModuleReference(quotedModuleSpecifier)); var changes = ChangeTracker.with(context, function (changeTracker) { if (lastImportDeclaration) { changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl, { suffix: newLineCharacter }); } else { changeTracker.insertNodeAt(sourceFile, ts.getSourceFileImportLocation(sourceFile), importDecl, { suffix: "" + newLineCharacter + newLineCharacter }); } }); // if this file doesn't have any import statements, insert an import statement and then insert a new line // between the only import statement and user code. Otherwise just insert the statement because chances // are there are already a new line seperating code and import statements. return createCodeAction(ts.Diagnostics.Import_0_from_module_1, [symbolName, moduleSpecifierWithoutQuotes], changes, "NewImport", moduleSpecifierWithoutQuotes); } function createStringLiteralWithQuoteStyle(sourceFile, text) { var literal = ts.createLiteral(text); var firstModuleSpecifier = ts.firstOrUndefined(sourceFile.imports); literal.singleQuote = !!firstModuleSpecifier && !ts.isStringDoubleQuoted(firstModuleSpecifier, sourceFile); return literal; } function createImportClauseOfKind(kind, symbolName) { var id = ts.createIdentifier(symbolName); switch (kind) { case 1 /* Default */: return ts.createImportClause(id, /*namedBindings*/ undefined); case 2 /* Namespace */: return ts.createImportClause(/*name*/ undefined, ts.createNamespaceImport(id)); case 0 /* Named */: return ts.createImportClause(/*name*/ undefined, ts.createNamedImports([ts.createImportSpecifier(/*propertyName*/ undefined, id)])); default: ts.Debug.assertNever(kind); } } function getModuleSpecifiersForNewImport(sourceFile, moduleSymbols, options, getCanonicalFileName, host) { var baseUrl = options.baseUrl, paths = options.paths, rootDirs = options.rootDirs; var choicesForEachExportingModule = ts.mapIterator(ts.arrayIterator(moduleSymbols), function (moduleSymbol) { var moduleFileName = moduleSymbol.valueDeclaration.getSourceFile().fileName; var sourceDirectory = ts.getDirectoryPath(sourceFile.fileName); var global = tryGetModuleNameFromAmbientModule(moduleSymbol) || tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) || tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) || rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName); if (global) { return [global]; } var relativePath = removeExtensionAndIndexPostFix(getRelativePath(moduleFileName, sourceDirectory, getCanonicalFileName), options); if (!baseUrl) { return [relativePath]; } var relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName); if (!relativeToBaseUrl) { return [relativePath]; } var importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, options); if (paths) { var fromPaths = tryGetModuleNameFromPaths(ts.removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths); if (fromPaths) { return [fromPaths]; } } /* Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl. Suppose we have: baseUrl = /base sourceDirectory = /base/a/b moduleFileName = /base/foo/bar Then: relativePath = ../../foo/bar getRelativePathNParents(relativePath) = 2 pathFromSourceToBaseUrl = ../../ getRelativePathNParents(pathFromSourceToBaseUrl) = 2 2 < 2 = false In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar". Suppose we have: baseUrl = /base sourceDirectory = /base/foo/a moduleFileName = /base/foo/bar Then: relativePath = ../a getRelativePathNParents(relativePath) = 1 pathFromSourceToBaseUrl = ../../ getRelativePathNParents(pathFromSourceToBaseUrl) = 2 1 < 2 = true In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a". */ var pathFromSourceToBaseUrl = getRelativePath(baseUrl, sourceDirectory, getCanonicalFileName); var relativeFirst = getRelativePathNParents(pathFromSourceToBaseUrl) < getRelativePathNParents(relativePath); return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath]; }); // Only return results for the re-export with the shortest possible path (and also give the other path even if that's long.) return ts.best(choicesForEachExportingModule, function (a, b) { return a[0].length < b[0].length; }); } codefix.getModuleSpecifiersForNewImport = getModuleSpecifiersForNewImport; function getRelativePathNParents(relativePath) { var count = 0; for (var i = 0; i + 3 <= relativePath.length && relativePath.slice(i, i + 3) === "../"; i += 3) { count++; } return count; } function tryGetModuleNameFromAmbientModule(moduleSymbol) { var decl = moduleSymbol.valueDeclaration; if (ts.isModuleDeclaration(decl) && ts.isStringLiteral(decl.name)) { return decl.name.text; } } function tryGetModuleNameFromPaths(relativeNameWithIndex, relativeName, paths) { for (var key in paths) { for (var _i = 0, _a = paths[key]; _i < _a.length; _i++) { var pattern = _a[_i]; var indexOfStar = pattern.indexOf("*"); if (indexOfStar === 0 && pattern.length === 1) { continue; } else if (indexOfStar !== -1) { var prefix = pattern.substr(0, indexOfStar); var suffix = pattern.substr(indexOfStar + 1); if (relativeName.length >= prefix.length + suffix.length && ts.startsWith(relativeName, prefix) && ts.endsWith(relativeName, suffix)) { var matchedStar = relativeName.substr(prefix.length, relativeName.length - suffix.length); return key.replace("\*", matchedStar); } } else if (pattern === relativeName || pattern === relativeNameWithIndex) { return key; } } } } function tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) { var normalizedTargetPath = getPathRelativeToRootDirs(moduleFileName, rootDirs, getCanonicalFileName); if (normalizedTargetPath === undefined) { return undefined; } var normalizedSourcePath = getPathRelativeToRootDirs(sourceDirectory, rootDirs, getCanonicalFileName); var relativePath = normalizedSourcePath !== undefined ? getRelativePath(normalizedTargetPath, normalizedSourcePath, getCanonicalFileName) : normalizedTargetPath; return ts.removeFileExtension(relativePath); } function tryGetModuleNameFromTypeRoots(options, host, getCanonicalFileName, moduleFileName) { var roots = ts.getEffectiveTypeRoots(options, host); return roots && ts.firstDefined(roots, function (unNormalizedTypeRoot) { var typeRoot = ts.toPath(unNormalizedTypeRoot, /*basePath*/ undefined, getCanonicalFileName); if (ts.startsWith(moduleFileName, typeRoot)) { return removeExtensionAndIndexPostFix(moduleFileName.substring(typeRoot.length + 1), options); } }); } function tryGetModuleNameAsNodeModule(options, moduleFileName, host, getCanonicalFileName, sourceDirectory) { if (ts.getEmitModuleResolutionKind(options) !== ts.ModuleResolutionKind.NodeJs) { // nothing to do here return undefined; } var parts = getNodeModulePathParts(moduleFileName); if (!parts) { return undefined; } // Simplify the full file path to something that can be resolved by Node. // If the module could be imported by a directory name, use that directory's name var moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName); // Get a path that's relative to node_modules or the importing file's path moduleSpecifier = getNodeResolvablePath(moduleSpecifier); // If the module was found in @types, get the actual Node package name return ts.getPackageNameFromAtTypesDirectory(moduleSpecifier); function getDirectoryOrExtensionlessFileName(path) { // If the file is the main module, it can be imported by the package name var packageRootPath = path.substring(0, parts.packageRootIndex); var packageJsonPath = ts.combinePaths(packageRootPath, "package.json"); if (host.fileExists(packageJsonPath)) { var packageJsonContent = JSON.parse(host.readFile(packageJsonPath)); if (packageJsonContent) { var mainFileRelative = packageJsonContent.typings || packageJsonContent.types || packageJsonContent.main; if (mainFileRelative) { var mainExportFile = ts.toPath(mainFileRelative, packageRootPath, getCanonicalFileName); if (mainExportFile === getCanonicalFileName(path)) { return packageRootPath; } } } } // We still have a file name - remove the extension var fullModulePathWithoutExtension = ts.removeFileExtension(path); // If the file is /index, it can be imported by its directory name if (getCanonicalFileName(fullModulePathWithoutExtension.substring(parts.fileNameIndex)) === "/index") { return fullModulePathWithoutExtension.substring(0, parts.fileNameIndex); } return fullModulePathWithoutExtension; } function getNodeResolvablePath(path) { var basePath = path.substring(0, parts.topLevelNodeModulesIndex); if (sourceDirectory.indexOf(basePath) === 0) { // if node_modules folder is in this folder or any of its parent folders, no need to keep it. return path.substring(parts.topLevelPackageNameIndex + 1); } else { return getRelativePath(path, sourceDirectory, getCanonicalFileName); } } } function getNodeModulePathParts(fullPath) { // If fullPath can't be valid module file within node_modules, returns undefined. // Example of expected pattern: /base/path/node_modules/[@scope/otherpackage/@otherscope/node_modules/]package/[subdirectory/]file.js // Returns indices: ^ ^ ^ ^ var topLevelNodeModulesIndex = 0; var topLevelPackageNameIndex = 0; var packageRootIndex = 0; var fileNameIndex = 0; var States; (function (States) { States[States["BeforeNodeModules"] = 0] = "BeforeNodeModules"; States[States["NodeModules"] = 1] = "NodeModules"; States[States["Scope"] = 2] = "Scope"; States[States["PackageContent"] = 3] = "PackageContent"; })(States || (States = {})); var partStart = 0; var partEnd = 0; var state = 0 /* BeforeNodeModules */; while (partEnd >= 0) { partStart = partEnd; partEnd = fullPath.indexOf("/", partStart + 1); switch (state) { case 0 /* BeforeNodeModules */: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { topLevelNodeModulesIndex = partStart; topLevelPackageNameIndex = partEnd; state = 1 /* NodeModules */; } break; case 1 /* NodeModules */: case 2 /* Scope */: if (state === 1 /* NodeModules */ && fullPath.charAt(partStart + 1) === "@") { state = 2 /* Scope */; } else { packageRootIndex = partEnd; state = 3 /* PackageContent */; } break; case 3 /* PackageContent */: if (fullPath.indexOf("/node_modules/", partStart) === partStart) { state = 1 /* NodeModules */; } else { state = 3 /* PackageContent */; } break; } } fileNameIndex = partStart; return state > 1 /* NodeModules */ ? { topLevelNodeModulesIndex: topLevelNodeModulesIndex, topLevelPackageNameIndex: topLevelPackageNameIndex, packageRootIndex: packageRootIndex, fileNameIndex: fileNameIndex } : undefined; } function getPathRelativeToRootDirs(path, rootDirs, getCanonicalFileName) { return ts.firstDefined(rootDirs, function (rootDir) { return getRelativePathIfInDirectory(path, rootDir, getCanonicalFileName); }); } function removeExtensionAndIndexPostFix(fileName, options) { var noExtension = ts.removeFileExtension(fileName); return ts.getEmitModuleResolutionKind(options) === ts.ModuleResolutionKind.NodeJs ? ts.removeSuffix(noExtension, "/index") : noExtension; } function getRelativePathIfInDirectory(path, directoryPath, getCanonicalFileName) { var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); return ts.isRootedDiskPath(relativePath) || ts.startsWith(relativePath, "..") ? undefined : relativePath; } function getRelativePath(path, directoryPath, getCanonicalFileName) { var relativePath = ts.getRelativePathToDirectoryOrUrl(directoryPath, path, directoryPath, getCanonicalFileName, /*isAbsolutePathAnUrl*/ false); return !ts.pathIsRelative(relativePath) ? "./" + relativePath : relativePath; } function getCodeActionsForAddImport(moduleSymbols, ctx, declarations) { var fromExistingImport = ts.firstDefined(declarations, function (declaration) { if (declaration.kind === 239 /* ImportDeclaration */ && declaration.importClause) { var changes = tryUpdateExistingImport(ctx, ts.isImportClause(declaration.importClause) && declaration.importClause || undefined); if (changes) { var moduleSpecifierWithoutQuotes = ts.stripQuotes(declaration.moduleSpecifier.getText()); return createCodeAction(ts.Diagnostics.Add_0_to_existing_import_declaration_from_1, [ctx.symbolName, moduleSpecifierWithoutQuotes], changes, "InsertingIntoExistingImport", moduleSpecifierWithoutQuotes); } } }); if (fromExistingImport) { return [fromExistingImport]; } var existingDeclaration = ts.firstDefined(declarations, moduleSpecifierFromAnyImport); var moduleSpecifiers = existingDeclaration ? [existingDeclaration] : getModuleSpecifiersForNewImport(ctx.sourceFile, moduleSymbols, ctx.compilerOptions, ctx.getCanonicalFileName, ctx.host); return moduleSpecifiers.map(function (spec) { return getCodeActionForNewImport(ctx, spec); }); } function moduleSpecifierFromAnyImport(node) { var expression = node.kind === 239 /* ImportDeclaration */ ? node.moduleSpecifier : node.moduleReference.kind === 249 /* ExternalModuleReference */ ? node.moduleReference.expression : undefined; return expression && ts.isStringLiteral(expression) ? expression.text : undefined; } function tryUpdateExistingImport(context, importClause) { var symbolName = context.symbolName, sourceFile = context.sourceFile, kind = context.kind; var name = importClause.name; var namedBindings = (importClause.kind !== 238 /* ImportEqualsDeclaration */ && importClause).namedBindings; switch (kind) { case 1 /* Default */: return name ? undefined : ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, importClause, ts.createImportClause(ts.createIdentifier(symbolName), namedBindings)); }); case 0 /* Named */: { var newImportSpecifier_1 = ts.createImportSpecifier(/*propertyName*/ undefined, ts.createIdentifier(symbolName)); if (namedBindings && namedBindings.kind === 242 /* NamedImports */ && namedBindings.elements.length !== 0) { // There are already named imports; add another. return ChangeTracker.with(context, function (t) { return t.insertNodeInListAfter(sourceFile, namedBindings.elements[namedBindings.elements.length - 1], newImportSpecifier_1); }); } if (!namedBindings || namedBindings.kind === 242 /* NamedImports */ && namedBindings.elements.length === 0) { return ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamedImports([newImportSpecifier_1]))); }); } return undefined; } case 2 /* Namespace */: return namedBindings ? undefined : ChangeTracker.with(context, function (t) { return t.replaceNode(sourceFile, importClause, ts.createImportClause(name, ts.createNamespaceImport(ts.createIdentifier(symbolName)))); }); case 3 /* Equals */: return undefined; default: ts.Debug.assertNever(kind); } } function getCodeActionForUseExistingNamespaceImport(namespacePrefix, context, symbolToken) { var symbolName = context.symbolName, sourceFile = context.sourceFile; /** * Cases: * import * as ns from "mod" * import default, * as ns from "mod" * import ns = require("mod") * * Because there is no import list, we alter the reference to include the * namespace instead of altering the import declaration. For example, "foo" would * become "ns.foo" */ return createCodeAction(ts.Diagnostics.Change_0_to_1, [symbolName, namespacePrefix + "." + symbolName], ChangeTracker.with(context, function (tracker) { return tracker.replaceNode(sourceFile, symbolToken, ts.createPropertyAccess(ts.createIdentifier(namespacePrefix), symbolName)); }), "CodeChange", /*moduleSpecifier*/ undefined); } function getImportCodeActions(context) { var importFixContext = convertToImportCodeFixContext(context); return context.errorCode === ts.Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code ? getActionsForUMDImport(importFixContext) : getActionsForNonUMDImport(importFixContext, context.program.getSourceFiles(), context.cancellationToken); } function getActionsForUMDImport(context) { var checker = context.checker, symbolToken = context.symbolToken, compilerOptions = context.compilerOptions; var umdSymbol = checker.getSymbolAtLocation(symbolToken); var symbol; var symbolName; if (umdSymbol.flags & 2097152 /* Alias */) { symbol = checker.getAliasedSymbol(umdSymbol); symbolName = context.symbolName; } else if (ts.isJsxOpeningLikeElement(symbolToken.parent) && symbolToken.parent.tagName === symbolToken) { // The error wasn't for the symbolAtLocation, it was for the JSX tag itself, which needs access to e.g. `React`. symbol = checker.getAliasedSymbol(checker.resolveName(checker.getJsxNamespace(), symbolToken.parent.tagName, 107455 /* Value */)); symbolName = symbol.name; } else { throw ts.Debug.fail("Either the symbol or the JSX namespace should be a UMD global if we got here"); } return getCodeActionForImport(symbol, __assign({}, context, { symbolName: symbolName, kind: getUmdImportKind(compilerOptions) })); } function getUmdImportKind(compilerOptions) { // Import a synthetic `default` if enabled. if (ts.getAllowSyntheticDefaultImports(compilerOptions)) { return 1 /* Default */; } // When a synthetic `default` is unavailable, use `import..require` if the module kind supports it. var moduleKind = ts.getEmitModuleKind(compilerOptions); switch (moduleKind) { case ts.ModuleKind.AMD: case ts.ModuleKind.CommonJS: case ts.ModuleKind.UMD: return 3 /* Equals */; case ts.ModuleKind.System: case ts.ModuleKind.ES2015: case ts.ModuleKind.ESNext: case ts.ModuleKind.None: // Fall back to the `import * as ns` style import. return 2 /* Namespace */; default: throw ts.Debug.assertNever(moduleKind); } } function getActionsForNonUMDImport(context, allSourceFiles, cancellationToken) { var sourceFile = context.sourceFile, checker = context.checker, symbolName = context.symbolName, symbolToken = context.symbolToken; // "default" is a keyword and not a legal identifier for the import, so we don't expect it here ts.Debug.assert(symbolName !== "default"); var symbolIdActionMap = new ImportCodeActionMap(); var currentTokenMeaning = ts.getMeaningFromLocation(symbolToken); forEachExternalModuleToImportFrom(checker, sourceFile, allSourceFiles, function (moduleSymbol) { cancellationToken.throwIfCancellationRequested(); // check the default export var defaultExport = checker.tryGetMemberInModuleExports("default", moduleSymbol); if (defaultExport) { var localSymbol = ts.getLocalSymbolForExportDefault(defaultExport); if ((localSymbol && localSymbol.escapedName === symbolName || moduleSymbolToValidIdentifier(moduleSymbol, context.compilerOptions.target) === symbolName) && checkSymbolHasMeaning(localSymbol || defaultExport, currentTokenMeaning)) { // check if this symbol is already used var symbolId = ts.getUniqueSymbolId(localSymbol || defaultExport, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 1 /* Default */ }))); } } // check exports with the same name var exportSymbolWithIdenticalName = checker.tryGetMemberInModuleExportsAndProperties(symbolName, moduleSymbol); if (exportSymbolWithIdenticalName && checkSymbolHasMeaning(exportSymbolWithIdenticalName, currentTokenMeaning)) { var symbolId = ts.getUniqueSymbolId(exportSymbolWithIdenticalName, checker); symbolIdActionMap.addActions(symbolId, getCodeActionForImport(moduleSymbol, __assign({}, context, { kind: 0 /* Named */ }))); } }); return symbolIdActionMap.getAllActions(); } function checkSymbolHasMeaning(_a, meaning) { var declarations = _a.declarations; return ts.some(declarations, function (decl) { return !!(ts.getMeaningFromDeclaration(decl) & meaning); }); } function forEachExternalModuleToImportFrom(checker, from, allSourceFiles, cb) { forEachExternalModule(checker, allSourceFiles, function (module, sourceFile) { if (sourceFile === undefined || sourceFile !== from && isImportablePath(from.fileName, sourceFile.fileName)) { cb(module); } }); } codefix.forEachExternalModuleToImportFrom = forEachExternalModuleToImportFrom; function forEachExternalModule(checker, allSourceFiles, cb) { for (var _i = 0, _a = checker.getAmbientModules(); _i < _a.length; _i++) { var ambient = _a[_i]; cb(ambient, /*sourceFile*/ undefined); } for (var _b = 0, allSourceFiles_1 = allSourceFiles; _b < allSourceFiles_1.length; _b++) { var sourceFile = allSourceFiles_1[_b]; if (ts.isExternalOrCommonJsModule(sourceFile)) { cb(sourceFile.symbol, sourceFile); } } } codefix.forEachExternalModule = forEachExternalModule; /** * Don't include something from a `node_modules` that isn't actually reachable by a global import. * A relative import to node_modules is usually a bad idea. */ function isImportablePath(fromPath, toPath) { // If it's in a `node_modules` but is not reachable from here via a global import, don't bother. var toNodeModules = ts.forEachAncestorDirectory(toPath, function (ancestor) { return ts.getBaseFileName(ancestor) === "node_modules" ? ancestor : undefined; }); return toNodeModules === undefined || ts.startsWith(fromPath, ts.getDirectoryPath(toNodeModules)); } function moduleSymbolToValidIdentifier(moduleSymbol, target) { return moduleSpecifierToValidIdentifier(ts.removeFileExtension(ts.getBaseFileName(moduleSymbol.name)), target); } codefix.moduleSymbolToValidIdentifier = moduleSymbolToValidIdentifier; function moduleSpecifierToValidIdentifier(moduleSpecifier, target) { var res = ""; var lastCharWasValid = true; var firstCharCode = moduleSpecifier.charCodeAt(0); if (ts.isIdentifierStart(firstCharCode, target)) { res += String.fromCharCode(firstCharCode); } else { lastCharWasValid = false; } for (var i = 1; i < moduleSpecifier.length; i++) { var ch = moduleSpecifier.charCodeAt(i); var isValid = ts.isIdentifierPart(ch, target); if (isValid) { var char = String.fromCharCode(ch); if (!lastCharWasValid) { char = char.toUpperCase(); } res += char; } lastCharWasValid = isValid; } // Need `|| "_"` to ensure result isn't empty. return !ts.isStringANonContextualKeyword(res) ? res || "_" : "_" + res; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: getApplicableDiagnosticCodes(), getCodeActions: getDisableJsDiagnosticsCodeActions }); function getApplicableDiagnosticCodes() { var allDiagnostcs = ts.Diagnostics; return Object.keys(allDiagnostcs) .filter(function (d) { return allDiagnostcs[d] && allDiagnostcs[d].category === ts.DiagnosticCategory.Error; }) .map(function (d) { return allDiagnostcs[d].code; }); } function getIgnoreCommentLocationForLocation(sourceFile, position, newLineCharacter) { var line = ts.getLineAndCharacterOfPosition(sourceFile, position).line; var lineStartPosition = ts.getStartPositionOfLine(line, sourceFile); var startPosition = ts.getFirstNonSpaceCharacterPosition(sourceFile.text, lineStartPosition); // First try to see if we can put the '// @ts-ignore' on the previous line. // We need to make sure that we are not in the middle of a string literal or a comment. // We also want to check if the previous line holds a comment for a node on the next line // if so, we do not want to separate the node from its comment if we can. if (!ts.isInComment(sourceFile, startPosition) && !ts.isInString(sourceFile, startPosition) && !ts.isInTemplateString(sourceFile, startPosition)) { var token = ts.getTouchingToken(sourceFile, startPosition, /*includeJsDocComment*/ false); var tokenLeadingCommnets = ts.getLeadingCommentRangesOfNode(token, sourceFile); if (!tokenLeadingCommnets || !tokenLeadingCommnets.length || tokenLeadingCommnets[0].pos >= startPosition) { return { span: { start: startPosition, length: 0 }, newText: "// @ts-ignore" + newLineCharacter }; } } // If all fails, add an extra new line immediately before the error span. return { span: { start: position, length: 0 }, newText: (position === startPosition ? "" : newLineCharacter) + "// @ts-ignore" + newLineCharacter }; } function getDisableJsDiagnosticsCodeActions(context) { var sourceFile = context.sourceFile, program = context.program, newLineCharacter = context.newLineCharacter, span = context.span; if (!ts.isInJavaScriptFile(sourceFile) || !ts.isCheckJsEnabledForFile(sourceFile, program.getCompilerOptions())) { return undefined; } return [{ description: ts.getLocaleSpecificMessage(ts.Diagnostics.Ignore_this_error_message), changes: [{ fileName: sourceFile.fileName, textChanges: [getIgnoreCommentLocationForLocation(sourceFile, span.start, newLineCharacter)] }] }, { description: ts.getLocaleSpecificMessage(ts.Diagnostics.Disable_checking_for_this_file), changes: [{ fileName: sourceFile.fileName, textChanges: [{ span: { start: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.pos : 0, length: sourceFile.checkJsDirective ? sourceFile.checkJsDirective.end - sourceFile.checkJsDirective.pos : 0 }, newText: "// @ts-nocheck" + newLineCharacter }] }] }]; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { function newNodesToChanges(newNodes, insertAfter, context) { var sourceFile = context.sourceFile; var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); for (var _i = 0, newNodes_1 = newNodes; _i < newNodes_1.length; _i++) { var newNode = newNodes_1[_i]; changeTracker.insertNodeAfter(sourceFile, insertAfter, newNode, { suffix: context.newLineCharacter }); } var changes = changeTracker.getChanges(); if (!ts.some(changes)) { return changes; } ts.Debug.assert(changes.length === 1); var consolidatedChanges = [{ fileName: changes[0].fileName, textChanges: [{ span: changes[0].textChanges[0].span, newText: changes[0].textChanges.reduce(function (prev, cur) { return prev + cur.newText; }, "") }] }]; return consolidatedChanges; } codefix.newNodesToChanges = newNodesToChanges; /** * Finds members of the resolved type that are missing in the class pointed to by class decl * and generates source code for the missing members. * @param possiblyMissingSymbols The collection of symbols to filter and then get insertions for. * @returns Empty string iff there are no member insertions. */ function createMissingMemberNodes(classDeclaration, possiblyMissingSymbols, checker) { var classMembers = classDeclaration.symbol.members; var missingMembers = possiblyMissingSymbols.filter(function (symbol) { return !classMembers.has(symbol.escapedName); }); var newNodes = []; for (var _i = 0, missingMembers_1 = missingMembers; _i < missingMembers_1.length; _i++) { var symbol = missingMembers_1[_i]; var newNode = createNewNodeForMemberSymbol(symbol, classDeclaration, checker); if (newNode) { if (Array.isArray(newNode)) { newNodes = newNodes.concat(newNode); } else { newNodes.push(newNode); } } } return newNodes; } codefix.createMissingMemberNodes = createMissingMemberNodes; /** * @returns Empty string iff there we can't figure out a representation for `symbol` in `enclosingDeclaration`. */ function createNewNodeForMemberSymbol(symbol, enclosingDeclaration, checker) { var declarations = symbol.getDeclarations(); if (!(declarations && declarations.length)) { return undefined; } var declaration = declarations[0]; // Clone name to remove leading trivia. var name = ts.getSynthesizedClone(ts.getNameOfDeclaration(declaration)); var visibilityModifier = createVisibilityModifier(ts.getModifierFlags(declaration)); var modifiers = visibilityModifier ? ts.createNodeArray([visibilityModifier]) : undefined; var type = checker.getWidenedType(checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration)); var optional = !!(symbol.flags & 16777216 /* Optional */); switch (declaration.kind) { case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 149 /* PropertySignature */: case 150 /* PropertyDeclaration */: var typeNode = checker.typeToTypeNode(type, enclosingDeclaration); var property = ts.createProperty( /*decorators*/ undefined, modifiers, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeNode, /*initializer*/ undefined); return property; case 151 /* MethodSignature */: case 152 /* MethodDeclaration */: // The signature for the implementation appears as an entry in `signatures` iff // there is only one signature. // If there are overloads and an implementation signature, it appears as an // extra declaration that isn't a signature for `type`. // If there is more than one overload but no implementation signature // (eg: an abstract method or interface declaration), there is a 1-1 // correspondence of declarations and signatures. var signatures = checker.getSignaturesOfType(type, 0 /* Call */); if (!ts.some(signatures)) { return undefined; } if (declarations.length === 1) { ts.Debug.assert(signatures.length === 1); var signature = signatures[0]; return signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody()); } var signatureDeclarations = []; for (var _i = 0, signatures_8 = signatures; _i < signatures_8.length; _i++) { var signature = signatures_8[_i]; var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration); if (methodDeclaration) { signatureDeclarations.push(methodDeclaration); } } if (declarations.length > signatures.length) { var signature = checker.getSignatureFromDeclaration(declarations[declarations.length - 1]); var methodDeclaration = signatureToMethodDeclaration(signature, enclosingDeclaration, createStubbedMethodBody()); if (methodDeclaration) { signatureDeclarations.push(methodDeclaration); } } else { ts.Debug.assert(declarations.length === signatures.length); var methodImplementingSignatures = createMethodImplementingSignatures(signatures, name, optional, modifiers); signatureDeclarations.push(methodImplementingSignatures); } return signatureDeclarations; default: return undefined; } function signatureToMethodDeclaration(signature, enclosingDeclaration, body) { var signatureDeclaration = checker.signatureToSignatureDeclaration(signature, 152 /* MethodDeclaration */, enclosingDeclaration, ts.NodeBuilderFlags.SuppressAnyReturnType); if (signatureDeclaration) { signatureDeclaration.decorators = undefined; signatureDeclaration.modifiers = modifiers; signatureDeclaration.name = name; signatureDeclaration.questionToken = optional ? ts.createToken(55 /* QuestionToken */) : undefined; signatureDeclaration.body = body; } return signatureDeclaration; } } function createMethodFromCallExpression(callExpression, methodName, includeTypeScriptSyntax, makeStatic) { var parameters = createDummyParameters(callExpression.arguments.length, /*names*/ undefined, /*minArgumentCount*/ undefined, includeTypeScriptSyntax); var typeParameters; if (includeTypeScriptSyntax) { var typeArgCount = ts.length(callExpression.typeArguments); for (var i = 0; i < typeArgCount; i++) { var name = typeArgCount < 8 ? String.fromCharCode(84 /* T */ + i) : "T" + i; var typeParameter = ts.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined); (typeParameters ? typeParameters : typeParameters = []).push(typeParameter); } } var newMethod = ts.createMethod( /*decorators*/ undefined, /*modifiers*/ makeStatic ? [ts.createToken(115 /* StaticKeyword */)] : undefined, /*asteriskToken*/ undefined, methodName, /*questionToken*/ undefined, typeParameters, parameters, /*type*/ includeTypeScriptSyntax ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, createStubbedMethodBody()); return newMethod; } codefix.createMethodFromCallExpression = createMethodFromCallExpression; function createDummyParameters(argCount, names, minArgumentCount, addAnyType) { var parameters = []; for (var i = 0; i < argCount; i++) { var newParameter = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ names && names[i] || "arg" + i, /*questionToken*/ minArgumentCount !== undefined && i >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, /*type*/ addAnyType ? ts.createKeywordTypeNode(119 /* AnyKeyword */) : undefined, /*initializer*/ undefined); parameters.push(newParameter); } return parameters; } function createMethodImplementingSignatures(signatures, name, optional, modifiers) { /** This is *a* signature with the maximal number of arguments, * such that if there is a "maximal" signature without rest arguments, * this is one of them. */ var maxArgsSignature = signatures[0]; var minArgumentCount = signatures[0].minArgumentCount; var someSigHasRestParameter = false; for (var _i = 0, signatures_9 = signatures; _i < signatures_9.length; _i++) { var sig = signatures_9[_i]; minArgumentCount = Math.min(sig.minArgumentCount, minArgumentCount); if (sig.hasRestParameter) { someSigHasRestParameter = true; } if (sig.parameters.length >= maxArgsSignature.parameters.length && (!sig.hasRestParameter || maxArgsSignature.hasRestParameter)) { maxArgsSignature = sig; } } var maxNonRestArgs = maxArgsSignature.parameters.length - (maxArgsSignature.hasRestParameter ? 1 : 0); var maxArgsParameterSymbolNames = maxArgsSignature.parameters.map(function (symbol) { return symbol.name; }); var parameters = createDummyParameters(maxNonRestArgs, maxArgsParameterSymbolNames, minArgumentCount, /*addAnyType*/ true); if (someSigHasRestParameter) { var anyArrayType = ts.createArrayTypeNode(ts.createKeywordTypeNode(119 /* AnyKeyword */)); var restParameter = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, ts.createToken(24 /* DotDotDotToken */), maxArgsParameterSymbolNames[maxNonRestArgs] || "rest", /*questionToken*/ maxNonRestArgs >= minArgumentCount ? ts.createToken(55 /* QuestionToken */) : undefined, anyArrayType, /*initializer*/ undefined); parameters.push(restParameter); } return createStubbedMethod(modifiers, name, optional, /*typeParameters*/ undefined, parameters, /*returnType*/ undefined); } function createStubbedMethod(modifiers, name, optional, typeParameters, parameters, returnType) { return ts.createMethod( /*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, name, optional ? ts.createToken(55 /* QuestionToken */) : undefined, typeParameters, parameters, returnType, createStubbedMethodBody()); } codefix.createStubbedMethod = createStubbedMethod; function createStubbedMethodBody() { return ts.createBlock([ts.createThrow(ts.createNew(ts.createIdentifier("Error"), /*typeArguments*/ undefined, [ts.createLiteral("Method not implemented.")]))], /*multiline*/ true); } function createVisibilityModifier(flags) { if (flags & 4 /* Public */) { return ts.createToken(114 /* PublicKeyword */); } else if (flags & 16 /* Protected */) { return ts.createToken(113 /* ProtectedKeyword */); } return undefined; } })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var codefix; (function (codefix) { codefix.registerCodeFix({ errorCodes: [ // Variable declarations ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code, // Variable uses ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code, // Parameter declarations ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code, ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code, // Get Accessor declarations ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code, ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code, // Set Accessor declarations ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code, // Property declarations ts.Diagnostics.Member_0_implicitly_has_an_1_type.code, ], getCodeActions: getActionsForAddExplicitTypeAnnotation }); function getActionsForAddExplicitTypeAnnotation(_a) { var sourceFile = _a.sourceFile, program = _a.program, start = _a.span.start, errorCode = _a.errorCode, cancellationToken = _a.cancellationToken; var token = ts.getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false); var writer; if (ts.isInJavaScriptFile(token)) { return undefined; } switch (token.kind) { case 71 /* Identifier */: case 24 /* DotDotDotToken */: case 114 /* PublicKeyword */: case 112 /* PrivateKeyword */: case 113 /* ProtectedKeyword */: case 131 /* ReadonlyKeyword */: // Allowed break; default: return undefined; } var containingFunction = ts.getContainingFunction(token); var checker = program.getTypeChecker(); switch (errorCode) { // Variable and Property declarations case ts.Diagnostics.Member_0_implicitly_has_an_1_type.code: case ts.Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code: return getCodeActionForVariableDeclaration(token.parent); case ts.Diagnostics.Variable_0_implicitly_has_an_1_type.code: return getCodeActionForVariableUsage(token); // Parameter declarations case ts.Diagnostics.Parameter_0_implicitly_has_an_1_type.code: if (ts.isSetAccessor(containingFunction)) { return getCodeActionForSetAccessor(containingFunction); } // falls through case ts.Diagnostics.Rest_parameter_0_implicitly_has_an_any_type.code: return getCodeActionForParameters(token.parent); // Get Accessor declarations case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_get_accessor_lacks_a_return_type_annotation.code: case ts.Diagnostics._0_which_lacks_return_type_annotation_implicitly_has_an_1_return_type.code: return ts.isGetAccessor(containingFunction) ? getCodeActionForGetAccessor(containingFunction) : undefined; // Set Accessor declarations case ts.Diagnostics.Property_0_implicitly_has_type_any_because_its_set_accessor_lacks_a_parameter_type_annotation.code: return ts.isSetAccessor(containingFunction) ? getCodeActionForSetAccessor(containingFunction) : undefined; } return undefined; function getCodeActionForVariableDeclaration(declaration) { if (!ts.isIdentifier(declaration.name)) { return undefined; } var type = inferTypeForVariableFromUsage(declaration.name); var typeString = type && typeToString(type, declaration); if (!typeString) { return undefined; } return createCodeActions(declaration.name.getText(), declaration.name.getEnd(), ": " + typeString); } function getCodeActionForVariableUsage(token) { var symbol = checker.getSymbolAtLocation(token); return symbol && symbol.valueDeclaration && getCodeActionForVariableDeclaration(symbol.valueDeclaration); } function isApplicableFunctionForInference(declaration) { switch (declaration.kind) { case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: case 153 /* Constructor */: return true; case 187 /* FunctionExpression */: return !!declaration.name; } return false; } function getCodeActionForParameters(parameterDeclaration) { if (!ts.isIdentifier(parameterDeclaration.name) || !isApplicableFunctionForInference(containingFunction)) { return undefined; } var types = inferTypeForParametersFromUsage(containingFunction) || ts.map(containingFunction.parameters, function (p) { return ts.isIdentifier(p.name) && inferTypeForVariableFromUsage(p.name); }); if (!types) { return undefined; } var textChanges = ts.zipWith(containingFunction.parameters, types, function (parameter, type) { if (type && !parameter.type && !parameter.initializer) { var typeString = typeToString(type, containingFunction); return typeString ? { span: { start: parameter.end, length: 0 }, newText: ": " + typeString } : undefined; } }).filter(function (c) { return !!c; }); return textChanges.length ? [{ description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_parameter_types_from_usage), [parameterDeclaration.name.getText()]), changes: [{ fileName: sourceFile.fileName, textChanges: textChanges }] }] : undefined; } function getCodeActionForSetAccessor(setAccessorDeclaration) { var setAccessorParameter = setAccessorDeclaration.parameters[0]; if (!setAccessorParameter || !ts.isIdentifier(setAccessorDeclaration.name) || !ts.isIdentifier(setAccessorParameter.name)) { return undefined; } var type = inferTypeForVariableFromUsage(setAccessorDeclaration.name) || inferTypeForVariableFromUsage(setAccessorParameter.name); var typeString = type && typeToString(type, containingFunction); if (!typeString) { return undefined; } return createCodeActions(setAccessorDeclaration.name.getText(), setAccessorParameter.name.getEnd(), ": " + typeString); } function getCodeActionForGetAccessor(getAccessorDeclaration) { if (!ts.isIdentifier(getAccessorDeclaration.name)) { return undefined; } var type = inferTypeForVariableFromUsage(getAccessorDeclaration.name); var typeString = type && typeToString(type, containingFunction); if (!typeString) { return undefined; } var closeParenToken = getFirstChildOfKind(getAccessorDeclaration, sourceFile, 20 /* CloseParenToken */); return createCodeActions(getAccessorDeclaration.name.getText(), closeParenToken.getEnd(), ": " + typeString); } function createCodeActions(name, start, typeString) { return [{ description: ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Infer_type_of_0_from_usage), [name]), changes: [{ fileName: sourceFile.fileName, textChanges: [{ span: { start: start, length: 0 }, newText: typeString }] }] }]; } function getReferences(token) { var references = ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), token.getSourceFile(), token.getStart()); ts.Debug.assert(!!references, "Found no references!"); ts.Debug.assert(references.length === 1, "Found more references than expected"); return ts.map(references[0].references, function (r) { return ts.getTokenAtPosition(program.getSourceFile(r.fileName), r.textSpan.start, /*includeJsDocComment*/ false); }); } function inferTypeForVariableFromUsage(token) { return InferFromReference.inferTypeFromReferences(getReferences(token), checker, cancellationToken); } function inferTypeForParametersFromUsage(containingFunction) { switch (containingFunction.kind) { case 153 /* Constructor */: case 187 /* FunctionExpression */: case 229 /* FunctionDeclaration */: case 152 /* MethodDeclaration */: var isConstructor = containingFunction.kind === 153 /* Constructor */; var searchToken = isConstructor ? getFirstChildOfKind(containingFunction, sourceFile, 123 /* ConstructorKeyword */) : containingFunction.name; if (searchToken) { return InferFromReference.inferTypeForParametersFromReferences(getReferences(searchToken), containingFunction, checker, cancellationToken); } } } function getTypeAccessiblityWriter() { if (!writer) { var str_1 = ""; var typeIsAccessible_1 = true; var writeText = function (text) { return str_1 += text; }; writer = { string: function () { return typeIsAccessible_1 ? str_1 : undefined; }, writeKeyword: writeText, writeOperator: writeText, writePunctuation: writeText, writeSpace: writeText, writeStringLiteral: writeText, writeParameter: writeText, writeProperty: writeText, writeSymbol: writeText, writeLine: function () { return str_1 += " "; }, increaseIndent: ts.noop, decreaseIndent: ts.noop, clear: function () { str_1 = ""; typeIsAccessible_1 = true; }, trackSymbol: function (symbol, declaration, meaning) { if (checker.isSymbolAccessible(symbol, declaration, meaning, /*shouldComputeAliasToMarkVisible*/ false).accessibility !== 0 /* Accessible */) { typeIsAccessible_1 = false; } }, reportInaccessibleThisError: function () { typeIsAccessible_1 = false; }, reportPrivateInBaseOfClassExpression: function () { typeIsAccessible_1 = false; }, reportInaccessibleUniqueSymbolError: function () { typeIsAccessible_1 = false; } }; } writer.clear(); return writer; } function typeToString(type, enclosingDeclaration) { var writer = getTypeAccessiblityWriter(); checker.getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration); return writer.string(); } function getFirstChildOfKind(node, sourcefile, kind) { for (var _i = 0, _a = node.getChildren(sourcefile); _i < _a.length; _i++) { var child = _a[_i]; if (child.kind === kind) return child; } return undefined; } } var InferFromReference; (function (InferFromReference) { function inferTypeFromReferences(references, checker, cancellationToken) { var usageContext = {}; for (var _i = 0, references_1 = references; _i < references_1.length; _i++) { var reference = references_1[_i]; cancellationToken.throwIfCancellationRequested(); inferTypeFromContext(reference, checker, usageContext); } return getTypeFromUsageContext(usageContext, checker); } InferFromReference.inferTypeFromReferences = inferTypeFromReferences; function inferTypeForParametersFromReferences(references, declaration, checker, cancellationToken) { if (declaration.parameters) { var usageContext = {}; for (var _i = 0, references_2 = references; _i < references_2.length; _i++) { var reference = references_2[_i]; cancellationToken.throwIfCancellationRequested(); inferTypeFromContext(reference, checker, usageContext); } var isConstructor = declaration.kind === 153 /* Constructor */; var callContexts = isConstructor ? usageContext.constructContexts : usageContext.callContexts; if (callContexts) { var paramTypes = []; for (var parameterIndex = 0; parameterIndex < declaration.parameters.length; parameterIndex++) { var types = []; var isRestParameter_1 = ts.isRestParameter(declaration.parameters[parameterIndex]); for (var _a = 0, callContexts_1 = callContexts; _a < callContexts_1.length; _a++) { var callContext = callContexts_1[_a]; if (callContext.argumentTypes.length > parameterIndex) { if (isRestParameter_1) { types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); })); } else { types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); } } } if (types.length) { var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true)); paramTypes[parameterIndex] = isRestParameter_1 ? checker.createArrayType(type) : type; } } return paramTypes; } } return undefined; } InferFromReference.inferTypeForParametersFromReferences = inferTypeForParametersFromReferences; function inferTypeFromContext(node, checker, usageContext) { while (ts.isRightSideOfQualifiedNameOrPropertyAccess(node)) { node = node.parent; } switch (node.parent.kind) { case 194 /* PostfixUnaryExpression */: usageContext.isNumber = true; break; case 193 /* PrefixUnaryExpression */: inferTypeFromPrefixUnaryExpressionContext(node.parent, usageContext); break; case 195 /* BinaryExpression */: inferTypeFromBinaryExpressionContext(node, node.parent, checker, usageContext); break; case 261 /* CaseClause */: case 262 /* DefaultClause */: inferTypeFromSwitchStatementLabelContext(node.parent, checker, usageContext); break; case 182 /* CallExpression */: case 183 /* NewExpression */: if (node.parent.expression === node) { inferTypeFromCallExpressionContext(node.parent, checker, usageContext); } else { inferTypeFromContextualType(node, checker, usageContext); } break; case 180 /* PropertyAccessExpression */: inferTypeFromPropertyAccessExpressionContext(node.parent, checker, usageContext); break; case 181 /* ElementAccessExpression */: inferTypeFromPropertyElementExpressionContext(node.parent, node, checker, usageContext); break; default: return inferTypeFromContextualType(node, checker, usageContext); } } function inferTypeFromContextualType(node, checker, usageContext) { if (ts.isExpressionNode(node)) { addCandidateType(usageContext, checker.getContextualType(node)); } } function inferTypeFromPrefixUnaryExpressionContext(node, usageContext) { switch (node.operator) { case 43 /* PlusPlusToken */: case 44 /* MinusMinusToken */: case 38 /* MinusToken */: case 52 /* TildeToken */: usageContext.isNumber = true; break; case 37 /* PlusToken */: usageContext.isNumberOrString = true; break; } } function inferTypeFromBinaryExpressionContext(node, parent, checker, usageContext) { switch (parent.operatorToken.kind) { // ExponentiationOperator case 40 /* AsteriskAsteriskToken */: // MultiplicativeOperator case 39 /* AsteriskToken */: case 41 /* SlashToken */: case 42 /* PercentToken */: // ShiftOperator case 45 /* LessThanLessThanToken */: case 46 /* GreaterThanGreaterThanToken */: case 47 /* GreaterThanGreaterThanGreaterThanToken */: // BitwiseOperator case 48 /* AmpersandToken */: case 49 /* BarToken */: case 50 /* CaretToken */: // CompoundAssignmentOperator case 60 /* MinusEqualsToken */: case 62 /* AsteriskAsteriskEqualsToken */: case 61 /* AsteriskEqualsToken */: case 63 /* SlashEqualsToken */: case 64 /* PercentEqualsToken */: case 68 /* AmpersandEqualsToken */: case 69 /* BarEqualsToken */: case 70 /* CaretEqualsToken */: case 65 /* LessThanLessThanEqualsToken */: case 67 /* GreaterThanGreaterThanGreaterThanEqualsToken */: case 66 /* GreaterThanGreaterThanEqualsToken */: // AdditiveOperator case 38 /* MinusToken */: // RelationalOperator case 27 /* LessThanToken */: case 30 /* LessThanEqualsToken */: case 29 /* GreaterThanToken */: case 31 /* GreaterThanEqualsToken */: var operandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (operandType.flags & 272 /* EnumLike */) { addCandidateType(usageContext, operandType); } else { usageContext.isNumber = true; } break; case 59 /* PlusEqualsToken */: case 37 /* PlusToken */: var otherOperandType = checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left); if (otherOperandType.flags & 272 /* EnumLike */) { addCandidateType(usageContext, otherOperandType); } else if (otherOperandType.flags & 84 /* NumberLike */) { usageContext.isNumber = true; } else if (otherOperandType.flags & 524322 /* StringLike */) { usageContext.isString = true; } else { usageContext.isNumberOrString = true; } break; // AssignmentOperators case 58 /* EqualsToken */: case 32 /* EqualsEqualsToken */: case 34 /* EqualsEqualsEqualsToken */: case 35 /* ExclamationEqualsEqualsToken */: case 33 /* ExclamationEqualsToken */: addCandidateType(usageContext, checker.getTypeAtLocation(parent.left === node ? parent.right : parent.left)); break; case 92 /* InKeyword */: if (node === parent.left) { usageContext.isString = true; } break; // LogicalOperator case 54 /* BarBarToken */: if (node === parent.left && (node.parent.parent.kind === 227 /* VariableDeclaration */ || ts.isAssignmentExpression(node.parent.parent, /*excludeCompoundAssignment*/ true))) { // var x = x || {}; // TODO: use getFalsyflagsOfType addCandidateType(usageContext, checker.getTypeAtLocation(parent.right)); } break; case 53 /* AmpersandAmpersandToken */: case 26 /* CommaToken */: case 93 /* InstanceOfKeyword */: // nothing to infer here break; } } function inferTypeFromSwitchStatementLabelContext(parent, checker, usageContext) { addCandidateType(usageContext, checker.getTypeAtLocation(parent.parent.parent.expression)); } function inferTypeFromCallExpressionContext(parent, checker, usageContext) { var callContext = { argumentTypes: [], returnType: {} }; if (parent.arguments) { for (var _i = 0, _a = parent.arguments; _i < _a.length; _i++) { var argument = _a[_i]; callContext.argumentTypes.push(checker.getTypeAtLocation(argument)); } } inferTypeFromContext(parent, checker, callContext.returnType); if (parent.kind === 182 /* CallExpression */) { (usageContext.callContexts || (usageContext.callContexts = [])).push(callContext); } else { (usageContext.constructContexts || (usageContext.constructContexts = [])).push(callContext); } } function inferTypeFromPropertyAccessExpressionContext(parent, checker, usageContext) { var name = ts.escapeLeadingUnderscores(parent.name.text); if (!usageContext.properties) { usageContext.properties = ts.createUnderscoreEscapedMap(); } var propertyUsageContext = usageContext.properties.get(name) || {}; inferTypeFromContext(parent, checker, propertyUsageContext); usageContext.properties.set(name, propertyUsageContext); } function inferTypeFromPropertyElementExpressionContext(parent, node, checker, usageContext) { if (node === parent.argumentExpression) { usageContext.isNumberOrString = true; return; } else { var indexType = checker.getTypeAtLocation(parent); var indexUsageContext = {}; inferTypeFromContext(parent, checker, indexUsageContext); if (indexType.flags & 84 /* NumberLike */) { usageContext.numberIndexContext = indexUsageContext; } else { usageContext.stringIndexContext = indexUsageContext; } } } function getTypeFromUsageContext(usageContext, checker) { if (usageContext.isNumberOrString && !usageContext.isNumber && !usageContext.isString) { return checker.getUnionType([checker.getNumberType(), checker.getStringType()]); } else if (usageContext.isNumber) { return checker.getNumberType(); } else if (usageContext.isString) { return checker.getStringType(); } else if (usageContext.candidateTypes) { return checker.getWidenedType(checker.getUnionType(ts.map(usageContext.candidateTypes, function (t) { return checker.getBaseTypeOfLiteralType(t); }), /*subtypeReduction*/ true)); } else if (usageContext.properties && hasCallContext(usageContext.properties.get("then"))) { var paramType = getParameterTypeFromCallContexts(0, usageContext.properties.get("then").callContexts, /*isRestParameter*/ false, checker); var types = paramType.getCallSignatures().map(function (c) { return c.getReturnType(); }); return checker.createPromiseType(types.length ? checker.getUnionType(types, /*subtypeReduction*/ true) : checker.getAnyType()); } else if (usageContext.properties && hasCallContext(usageContext.properties.get("push"))) { return checker.createArrayType(getParameterTypeFromCallContexts(0, usageContext.properties.get("push").callContexts, /*isRestParameter*/ false, checker)); } else if (usageContext.properties || usageContext.callContexts || usageContext.constructContexts || usageContext.numberIndexContext || usageContext.stringIndexContext) { var members_5 = ts.createUnderscoreEscapedMap(); var callSignatures = []; var constructSignatures = []; var stringIndexInfo = void 0; var numberIndexInfo = void 0; if (usageContext.properties) { usageContext.properties.forEach(function (context, name) { var symbol = checker.createSymbol(4 /* Property */, name); symbol.type = getTypeFromUsageContext(context, checker) || checker.getAnyType(); members_5.set(name, symbol); }); } if (usageContext.callContexts) { for (var _i = 0, _a = usageContext.callContexts; _i < _a.length; _i++) { var callContext = _a[_i]; callSignatures.push(getSignatureFromCallContext(callContext, checker)); } } if (usageContext.constructContexts) { for (var _b = 0, _c = usageContext.constructContexts; _b < _c.length; _b++) { var constructContext = _c[_b]; constructSignatures.push(getSignatureFromCallContext(constructContext, checker)); } } if (usageContext.numberIndexContext) { numberIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.numberIndexContext, checker), /*isReadonly*/ false); } if (usageContext.stringIndexContext) { stringIndexInfo = checker.createIndexInfo(getTypeFromUsageContext(usageContext.stringIndexContext, checker), /*isReadonly*/ false); } return checker.createAnonymousType(/*symbol*/ undefined, members_5, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } else { return undefined; } } function getParameterTypeFromCallContexts(parameterIndex, callContexts, isRestParameter, checker) { var types = []; if (callContexts) { for (var _i = 0, callContexts_2 = callContexts; _i < callContexts_2.length; _i++) { var callContext = callContexts_2[_i]; if (callContext.argumentTypes.length > parameterIndex) { if (isRestParameter) { types = ts.concatenate(types, ts.map(callContext.argumentTypes.slice(parameterIndex), function (a) { return checker.getBaseTypeOfLiteralType(a); })); } else { types.push(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[parameterIndex])); } } } } if (types.length) { var type = checker.getWidenedType(checker.getUnionType(types, /*subtypeReduction*/ true)); return isRestParameter ? checker.createArrayType(type) : type; } return undefined; } function getSignatureFromCallContext(callContext, checker) { var parameters = []; for (var i = 0; i < callContext.argumentTypes.length; i++) { var symbol = checker.createSymbol(1 /* FunctionScopedVariable */, ts.escapeLeadingUnderscores("arg" + i)); symbol.type = checker.getWidenedType(checker.getBaseTypeOfLiteralType(callContext.argumentTypes[i])); parameters.push(symbol); } var returnType = getTypeFromUsageContext(callContext.returnType, checker) || checker.getVoidType(); return checker.createSignature(/*declaration*/ undefined, /*typeParameters*/ undefined, /*thisParameter*/ undefined, parameters, returnType, /*typePredicate*/ undefined, callContext.argumentTypes.length, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); } function addCandidateType(context, type) { if (type && !(type.flags & 1 /* Any */) && !(type.flags & 16384 /* Never */)) { (context.candidateTypes || (context.candidateTypes = [])).push(type); } } function hasCallContext(usageContext) { return usageContext && usageContext.callContexts; } })(InferFromReference || (InferFromReference = {})); })(codefix = ts.codefix || (ts.codefix = {})); })(ts || (ts = {})); /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /* @internal */ var ts; (function (ts) { var refactor; (function (refactor) { var annotateWithTypeFromJSDoc; (function (annotateWithTypeFromJSDoc) { var actionName = "annotate"; var annotateTypeFromJSDoc = { name: "Annotate with type from JSDoc", description: ts.Diagnostics.Annotate_with_type_from_JSDoc.message, getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions }; refactor.registerRefactor(annotateTypeFromJSDoc); function getAvailableActions(context) { if (ts.isInJavaScriptFile(context.file)) { return undefined; } var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); if (hasUsableJSDoc(ts.findAncestor(node, isDeclarationWithType))) { return [{ name: annotateTypeFromJSDoc.name, description: annotateTypeFromJSDoc.description, actions: [ { description: annotateTypeFromJSDoc.description, name: actionName } ] }]; } } function hasUsableJSDoc(decl) { if (!decl) { return false; } if (ts.isFunctionLikeDeclaration(decl)) { return decl.parameters.some(hasUsableJSDoc) || (!decl.type && !!ts.getJSDocReturnType(decl)); } return !decl.type && !!ts.getJSDocType(decl); } function getEditsForAction(context, action) { if (actionName !== action) { return ts.Debug.fail("actionName !== action: " + actionName + " !== " + action); } var node = ts.getTokenAtPosition(context.file, context.startPosition, /*includeJsDocComment*/ false); var decl = ts.findAncestor(node, isDeclarationWithType); if (!decl || decl.type) { return undefined; } var jsdocType = ts.getJSDocType(decl); var isFunctionWithJSDoc = ts.isFunctionLikeDeclaration(decl) && (ts.getJSDocReturnType(decl) || decl.parameters.some(function (p) { return !!ts.getJSDocType(p); })); if (isFunctionWithJSDoc || jsdocType && decl.kind === 147 /* Parameter */) { return getEditsForFunctionAnnotation(context); } else if (jsdocType) { return getEditsForAnnotation(context); } else { ts.Debug.assert(!!refactor, "No applicable refactor found."); } } function getEditsForAnnotation(context) { var sourceFile = context.file; var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); var decl = ts.findAncestor(token, isDeclarationWithType); var jsdocType = ts.getJSDocType(decl); if (!decl || !jsdocType || decl.type) { return ts.Debug.fail("!decl || !jsdocType || decl.type: !" + decl + " || !" + jsdocType + " || " + decl.type); } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); var declarationWithType = addType(decl, transformJSDocType(jsdocType)); ts.suppressLeadingAndTrailingTrivia(declarationWithType); changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, declarationWithType); return { edits: changeTracker.getChanges(), renameFilename: undefined, renameLocation: undefined }; } function getEditsForFunctionAnnotation(context) { var sourceFile = context.file; var token = ts.getTokenAtPosition(sourceFile, context.startPosition, /*includeJsDocComment*/ false); var decl = ts.findAncestor(token, ts.isFunctionLikeDeclaration); var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); var functionWithType = addTypesToFunctionLike(decl); ts.suppressLeadingAndTrailingTrivia(functionWithType); changeTracker.replaceRange(sourceFile, { pos: decl.getStart(), end: decl.end }, functionWithType); return { edits: changeTracker.getChanges(), renameFilename: undefined, renameLocation: undefined }; } function isDeclarationWithType(node) { return ts.isFunctionLikeDeclaration(node) || node.kind === 227 /* VariableDeclaration */ || node.kind === 147 /* Parameter */ || node.kind === 149 /* PropertySignature */ || node.kind === 150 /* PropertyDeclaration */; } function addTypesToFunctionLike(decl) { var typeParameters = ts.getEffectiveTypeParameterDeclarations(decl, /*checkJSDoc*/ true); var parameters = decl.parameters.map(function (p) { return ts.createParameter(p.decorators, p.modifiers, p.dotDotDotToken, p.name, p.questionToken, transformJSDocType(ts.getEffectiveTypeAnnotationNode(p, /*checkJSDoc*/ true)), p.initializer); }); var returnType = transformJSDocType(ts.getEffectiveReturnTypeNode(decl, /*checkJSDoc*/ true)); switch (decl.kind) { case 229 /* FunctionDeclaration */: return ts.createFunctionDeclaration(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body); case 153 /* Constructor */: return ts.createConstructor(decl.decorators, decl.modifiers, parameters, decl.body); case 187 /* FunctionExpression */: return ts.createFunctionExpression(decl.modifiers, decl.asteriskToken, decl.name, typeParameters, parameters, returnType, decl.body); case 188 /* ArrowFunction */: return ts.createArrowFunction(decl.modifiers, typeParameters, parameters, returnType, decl.equalsGreaterThanToken, decl.body); case 152 /* MethodDeclaration */: return ts.createMethod(decl.decorators, decl.modifiers, decl.asteriskToken, decl.name, decl.questionToken, typeParameters, parameters, returnType, decl.body); case 154 /* GetAccessor */: return ts.createGetAccessor(decl.decorators, decl.modifiers, decl.name, decl.parameters, returnType, decl.body); case 155 /* SetAccessor */: return ts.createSetAccessor(decl.decorators, decl.modifiers, decl.name, parameters, decl.body); default: return ts.Debug.assertNever(decl, "Unexpected SyntaxKind: " + decl.kind); } } function addType(decl, jsdocType) { switch (decl.kind) { case 227 /* VariableDeclaration */: return ts.createVariableDeclaration(decl.name, jsdocType, decl.initializer); case 149 /* PropertySignature */: return ts.createPropertySignature(decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); case 150 /* PropertyDeclaration */: return ts.createProperty(decl.decorators, decl.modifiers, decl.name, decl.questionToken, jsdocType, decl.initializer); default: return ts.Debug.fail("Unexpected SyntaxKind: " + decl.kind); } } function transformJSDocType(node) { if (node === undefined) { return undefined; } switch (node.kind) { case 272 /* JSDocAllType */: case 273 /* JSDocUnknownType */: return ts.createTypeReferenceNode("any", ts.emptyArray); case 276 /* JSDocOptionalType */: return transformJSDocOptionalType(node); case 275 /* JSDocNonNullableType */: return transformJSDocType(node.type); case 274 /* JSDocNullableType */: return transformJSDocNullableType(node); case 278 /* JSDocVariadicType */: return transformJSDocVariadicType(node); case 277 /* JSDocFunctionType */: return transformJSDocFunctionType(node); case 147 /* Parameter */: return transformJSDocParameter(node); case 160 /* TypeReference */: return transformJSDocTypeReference(node); default: var visited = ts.visitEachChild(node, transformJSDocType, /*context*/ undefined); ts.setEmitFlags(visited, 1 /* SingleLine */); return visited; } } function transformJSDocOptionalType(node) { return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("undefined", ts.emptyArray)]); } function transformJSDocNullableType(node) { return ts.createUnionTypeNode([ts.visitNode(node.type, transformJSDocType), ts.createTypeReferenceNode("null", ts.emptyArray)]); } function transformJSDocVariadicType(node) { return ts.createArrayTypeNode(ts.visitNode(node.type, transformJSDocType)); } function transformJSDocFunctionType(node) { var parameters = node.parameters && node.parameters.map(transformJSDocType); return ts.createFunctionTypeNode(ts.emptyArray, parameters, node.type); } function transformJSDocParameter(node) { var index = node.parent.parameters.indexOf(node); var isRest = node.type.kind === 278 /* JSDocVariadicType */ && index === node.parent.parameters.length - 1; var name = node.name || (isRest ? "rest" : "arg" + index); var dotdotdot = isRest ? ts.createToken(24 /* DotDotDotToken */) : node.dotDotDotToken; return ts.createParameter(node.decorators, node.modifiers, dotdotdot, name, node.questionToken, ts.visitNode(node.type, transformJSDocType), node.initializer); } function transformJSDocTypeReference(node) { var name = node.typeName; var args = node.typeArguments; if (ts.isIdentifier(node.typeName)) { if (ts.isJSDocIndexSignature(node)) { return transformJSDocIndexSignature(node); } var text = node.typeName.text; switch (node.typeName.text) { case "String": case "Boolean": case "Object": case "Number": text = text.toLowerCase(); break; case "array": case "date": case "promise": text = text[0].toUpperCase() + text.slice(1); break; } name = ts.createIdentifier(text); if ((text === "Array" || text === "Promise") && !node.typeArguments) { args = ts.createNodeArray([ts.createTypeReferenceNode("any", ts.emptyArray)]); } else { args = ts.visitNodes(node.typeArguments, transformJSDocType); } } return ts.createTypeReferenceNode(name, args); } function transformJSDocIndexSignature(node) { var index = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "n" : "s", /*questionToken*/ undefined, ts.createTypeReferenceNode(node.typeArguments[0].kind === 133 /* NumberKeyword */ ? "number" : "string", []), /*initializer*/ undefined); var indexSignature = ts.createTypeLiteralNode([ts.createIndexSignature(/*decorators*/ undefined, /*modifiers*/ undefined, [index], node.typeArguments[1])]); ts.setEmitFlags(indexSignature, 1 /* SingleLine */); return indexSignature; } })(annotateWithTypeFromJSDoc = refactor.annotateWithTypeFromJSDoc || (refactor.annotateWithTypeFromJSDoc = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var refactor; (function (refactor) { var convertFunctionToES6Class; (function (convertFunctionToES6Class_1) { var actionName = "convert"; var convertFunctionToES6Class = { name: "Convert to ES2015 class", description: ts.Diagnostics.Convert_function_to_an_ES2015_class.message, getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions }; refactor.registerRefactor(convertFunctionToES6Class); function getAvailableActions(context) { if (!ts.isInJavaScriptFile(context.file)) { return undefined; } var symbol = getConstructorSymbol(context); if (!symbol) { return undefined; } if (ts.isDeclarationOfFunctionOrClassExpression(symbol)) { symbol = symbol.valueDeclaration.initializer.symbol; } if ((symbol.flags & 16 /* Function */) && symbol.members && (symbol.members.size > 0)) { return [ { name: convertFunctionToES6Class.name, description: convertFunctionToES6Class.description, actions: [ { description: convertFunctionToES6Class.description, name: actionName } ] } ]; } } function getEditsForAction(context, action) { // Somehow wrong action got invoked? if (actionName !== action) { return undefined; } var sourceFile = context.file; var ctorSymbol = getConstructorSymbol(context); var newLine = context.formatContext.options.newLineCharacter; var deletedNodes = []; var deletes = []; if (!(ctorSymbol.flags & (16 /* Function */ | 3 /* Variable */))) { return undefined; } var ctorDeclaration = ctorSymbol.valueDeclaration; var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); var precedingNode; var newClassDeclaration; switch (ctorDeclaration.kind) { case 229 /* FunctionDeclaration */: precedingNode = ctorDeclaration; deleteNode(ctorDeclaration); newClassDeclaration = createClassFromFunctionDeclaration(ctorDeclaration); break; case 227 /* VariableDeclaration */: precedingNode = ctorDeclaration.parent.parent; if (ctorDeclaration.parent.declarations.length === 1) { deleteNode(precedingNode); } else { deleteNode(ctorDeclaration, /*inList*/ true); } newClassDeclaration = createClassFromVariableDeclaration(ctorDeclaration); break; } if (!newClassDeclaration) { return undefined; } // Because the preceding node could be touched, we need to insert nodes before delete nodes. changeTracker.insertNodeAfter(sourceFile, precedingNode, newClassDeclaration, { suffix: newLine }); for (var _i = 0, deletes_1 = deletes; _i < deletes_1.length; _i++) { var deleteCallback = deletes_1[_i]; deleteCallback(); } return { edits: changeTracker.getChanges(), renameFilename: undefined, renameLocation: undefined, }; function deleteNode(node, inList) { if (inList === void 0) { inList = false; } if (deletedNodes.some(function (n) { return ts.isNodeDescendantOf(node, n); })) { // Parent node has already been deleted; do nothing return; } deletedNodes.push(node); if (inList) { deletes.push(function () { return changeTracker.deleteNodeInList(sourceFile, node); }); } else { deletes.push(function () { return changeTracker.deleteNode(sourceFile, node); }); } } function createClassElementsFromSymbol(symbol) { var memberElements = []; // all instance members are stored in the "member" array of symbol if (symbol.members) { symbol.members.forEach(function (member) { var memberElement = createClassElement(member, /*modifiers*/ undefined); if (memberElement) { memberElements.push(memberElement); } }); } // all static members are stored in the "exports" array of symbol if (symbol.exports) { symbol.exports.forEach(function (member) { var memberElement = createClassElement(member, [ts.createToken(115 /* StaticKeyword */)]); if (memberElement) { memberElements.push(memberElement); } }); } return memberElements; function shouldConvertDeclaration(_target, source) { // Right now the only thing we can convert are function expressions - other values shouldn't get // transformed. We can update this once ES public class properties are available. return ts.isFunctionLike(source); } function createClassElement(symbol, modifiers) { // both properties and methods are bound as property symbols if (!(symbol.flags & 4 /* Property */)) { return; } var memberDeclaration = symbol.valueDeclaration; var assignmentBinaryExpression = memberDeclaration.parent; if (!shouldConvertDeclaration(memberDeclaration, assignmentBinaryExpression.right)) { return; } // delete the entire statement if this expression is the sole expression to take care of the semicolon at the end var nodeToDelete = assignmentBinaryExpression.parent && assignmentBinaryExpression.parent.kind === 211 /* ExpressionStatement */ ? assignmentBinaryExpression.parent : assignmentBinaryExpression; deleteNode(nodeToDelete); if (!assignmentBinaryExpression.right) { return ts.createProperty([], modifiers, symbol.name, /*questionToken*/ undefined, /*type*/ undefined, /*initializer*/ undefined); } switch (assignmentBinaryExpression.right.kind) { case 187 /* FunctionExpression */: { var functionExpression = assignmentBinaryExpression.right; var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(functionExpression, 120 /* AsyncKeyword */)); var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, /*typeParameters*/ undefined, functionExpression.parameters, /*type*/ undefined, functionExpression.body); copyComments(assignmentBinaryExpression, method); return method; } case 188 /* ArrowFunction */: { var arrowFunction = assignmentBinaryExpression.right; var arrowFunctionBody = arrowFunction.body; var bodyBlock = void 0; // case 1: () => { return [1,2,3] } if (arrowFunctionBody.kind === 208 /* Block */) { bodyBlock = arrowFunctionBody; } else { var expression = arrowFunctionBody; bodyBlock = ts.createBlock([ts.createReturn(expression)]); } var fullModifiers = ts.concatenate(modifiers, getModifierKindFromSource(arrowFunction, 120 /* AsyncKeyword */)); var method = ts.createMethod(/*decorators*/ undefined, fullModifiers, /*asteriskToken*/ undefined, memberDeclaration.name, /*questionToken*/ undefined, /*typeParameters*/ undefined, arrowFunction.parameters, /*type*/ undefined, bodyBlock); copyComments(assignmentBinaryExpression, method); return method; } default: { // Don't try to declare members in JavaScript files if (ts.isSourceFileJavaScript(sourceFile)) { return; } var prop = ts.createProperty(/*decorators*/ undefined, modifiers, memberDeclaration.name, /*questionToken*/ undefined, /*type*/ undefined, assignmentBinaryExpression.right); copyComments(assignmentBinaryExpression.parent, prop); return prop; } } } } function copyComments(sourceNode, targetNode) { ts.forEachLeadingCommentRange(sourceFile.text, sourceNode.pos, function (pos, end, kind, htnl) { if (kind === 3 /* MultiLineCommentTrivia */) { // Remove leading /* pos += 2; // Remove trailing */ end -= 2; } else { // Remove leading // pos += 2; } ts.addSyntheticLeadingComment(targetNode, kind, sourceFile.text.slice(pos, end), htnl); }); } function createClassFromVariableDeclaration(node) { var initializer = node.initializer; if (!initializer || initializer.kind !== 187 /* FunctionExpression */) { return undefined; } if (node.name.kind !== 71 /* Identifier */) { return undefined; } var memberElements = createClassElementsFromSymbol(initializer.symbol); if (initializer.body) { memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, initializer.parameters, initializer.body)); } var modifiers = getModifierKindFromSource(precedingNode, 84 /* ExportKeyword */); var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; } function createClassFromFunctionDeclaration(node) { var memberElements = createClassElementsFromSymbol(ctorSymbol); if (node.body) { memberElements.unshift(ts.createConstructor(/*decorators*/ undefined, /*modifiers*/ undefined, node.parameters, node.body)); } var modifiers = getModifierKindFromSource(node, 84 /* ExportKeyword */); var cls = ts.createClassDeclaration(/*decorators*/ undefined, modifiers, node.name, /*typeParameters*/ undefined, /*heritageClauses*/ undefined, memberElements); // Don't call copyComments here because we'll already leave them in place return cls; } function getModifierKindFromSource(source, kind) { return ts.filter(source.modifiers, function (modifier) { return modifier.kind === kind; }); } } function getConstructorSymbol(_a) { var startPosition = _a.startPosition, file = _a.file, program = _a.program; var checker = program.getTypeChecker(); var token = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); return checker.getSymbolAtLocation(token); } })(convertFunctionToES6Class = refactor.convertFunctionToES6Class || (refactor.convertFunctionToES6Class = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /// /// /* @internal */ var ts; (function (ts) { var refactor; (function (refactor) { var extractSymbol; (function (extractSymbol_1) { var extractSymbol = { name: "Extract Symbol", description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_symbol), getAvailableActions: getAvailableActions, getEditsForAction: getEditsForAction, }; refactor.registerRefactor(extractSymbol); /** * Compute the associated code actions * Exported for tests. */ function getAvailableActions(context) { var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) }); var targetRange = rangeToExtract.targetRange; if (targetRange === undefined) { return undefined; } var extractions = getPossibleExtractions(targetRange, context); if (extractions === undefined) { // No extractions possible return undefined; } var functionActions = []; var usedFunctionNames = ts.createMap(); var constantActions = []; var usedConstantNames = ts.createMap(); var i = 0; for (var _i = 0, extractions_1 = extractions; _i < extractions_1.length; _i++) { var _a = extractions_1[_i], functionExtraction = _a.functionExtraction, constantExtraction = _a.constantExtraction; // Skip these since we don't have a way to report errors yet if (functionExtraction.errors.length === 0) { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes var description = functionExtraction.description; if (!usedFunctionNames.has(description)) { usedFunctionNames.set(description, true); functionActions.push({ description: description, name: "function_scope_" + i }); } } // Skip these since we don't have a way to report errors yet if (constantExtraction.errors.length === 0) { // Don't issue refactorings with duplicated names. // Scopes come back in "innermost first" order, so extractions will // preferentially go into nearer scopes var description = constantExtraction.description; if (!usedConstantNames.has(description)) { usedConstantNames.set(description, true); constantActions.push({ description: description, name: "constant_scope_" + i }); } } // *do* increment i anyway because we'll look for the i-th scope // later when actually doing the refactoring if the user requests it i++; } var infos = []; if (functionActions.length) { infos.push({ name: extractSymbol.name, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_function), actions: functionActions }); } if (constantActions.length) { infos.push({ name: extractSymbol.name, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_constant), actions: constantActions }); } return infos.length ? infos : undefined; } extractSymbol_1.getAvailableActions = getAvailableActions; /* Exported for tests */ function getEditsForAction(context, actionName) { var rangeToExtract = getRangeToExtract(context.file, { start: context.startPosition, length: ts.getRefactorContextLength(context) }); var targetRange = rangeToExtract.targetRange; var parsedFunctionIndexMatch = /^function_scope_(\d+)$/.exec(actionName); if (parsedFunctionIndexMatch) { var index = +parsedFunctionIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the function scope index"); return getFunctionExtractionAtIndex(targetRange, context, index); } var parsedConstantIndexMatch = /^constant_scope_(\d+)$/.exec(actionName); if (parsedConstantIndexMatch) { var index = +parsedConstantIndexMatch[1]; ts.Debug.assert(isFinite(index), "Expected to parse a finite number from the constant scope index"); return getConstantExtractionAtIndex(targetRange, context, index); } ts.Debug.fail("Unrecognized action name"); } extractSymbol_1.getEditsForAction = getEditsForAction; // Move these into diagnostic messages if they become user-facing var Messages; (function (Messages) { function createMessage(message) { return { message: message, code: 0, category: ts.DiagnosticCategory.Message, key: message }; } Messages.cannotExtractRange = createMessage("Cannot extract range."); Messages.cannotExtractImport = createMessage("Cannot extract import statement."); Messages.cannotExtractSuper = createMessage("Cannot extract super call."); Messages.cannotExtractEmpty = createMessage("Cannot extract empty range."); Messages.expressionExpected = createMessage("expression expected."); Messages.uselessConstantType = createMessage("No reason to extract constant of type."); Messages.statementOrExpressionExpected = createMessage("Statement or expression expected."); Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements = createMessage("Cannot extract range containing conditional break or continue statements."); Messages.cannotExtractRangeContainingConditionalReturnStatement = createMessage("Cannot extract range containing conditional return statement."); Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange = createMessage("Cannot extract range containing labeled break or continue with target outside of the range."); Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators = createMessage("Cannot extract range containing writes to references located outside of the target range in generators."); Messages.typeWillNotBeVisibleInTheNewScope = createMessage("Type will not visible in the new scope."); Messages.functionWillNotBeVisibleInTheNewScope = createMessage("Function will not visible in the new scope."); Messages.cannotExtractIdentifier = createMessage("Select more than a single identifier."); Messages.cannotExtractExportedEntity = createMessage("Cannot extract exported declaration"); Messages.cannotWriteInExpression = createMessage("Cannot write back side-effects when extracting an expression"); Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor = createMessage("Cannot move initialization of read-only class property outside of the constructor"); Messages.cannotExtractAmbientBlock = createMessage("Cannot extract code from ambient contexts"); Messages.cannotAccessVariablesFromNestedScopes = createMessage("Cannot access variables from nested scopes"); Messages.cannotExtractToOtherFunctionLike = createMessage("Cannot extract method to a function-like scope that is not a function"); Messages.cannotExtractToJSClass = createMessage("Cannot extract constant to a class scope in JS"); Messages.cannotExtractToExpressionArrowFunction = createMessage("Cannot extract constant to an arrow function without a block"); })(Messages = extractSymbol_1.Messages || (extractSymbol_1.Messages = {})); var RangeFacts; (function (RangeFacts) { RangeFacts[RangeFacts["None"] = 0] = "None"; RangeFacts[RangeFacts["HasReturn"] = 1] = "HasReturn"; RangeFacts[RangeFacts["IsGenerator"] = 2] = "IsGenerator"; RangeFacts[RangeFacts["IsAsyncFunction"] = 4] = "IsAsyncFunction"; RangeFacts[RangeFacts["UsesThis"] = 8] = "UsesThis"; /** * The range is in a function which needs the 'static' modifier in a class */ RangeFacts[RangeFacts["InStaticRegion"] = 16] = "InStaticRegion"; })(RangeFacts || (RangeFacts = {})); /** * getRangeToExtract takes a span inside a text file and returns either an expression or an array * of statements representing the minimum set of nodes needed to extract the entire span. This * process may fail, in which case a set of errors is returned instead (these are currently * not shown to the user, but can be used by us diagnostically) */ // exported only for tests function getRangeToExtract(sourceFile, span) { var length = span.length; if (length === 0) { return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractEmpty)] }; } // Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span. // This may fail (e.g. you select two statements in the root of a source file) var start = getParentNodeInSpan(ts.getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span); // Do the same for the ending position var end = getParentNodeInSpan(ts.findTokenOnLeftOfPosition(sourceFile, ts.textSpanEnd(span)), sourceFile, span); var declarations = []; // We'll modify these flags as we walk the tree to collect data // about what things need to be done as part of the extraction. var rangeFacts = RangeFacts.None; if (!start || !end) { // cannot find either start or end node return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } if (start.parent !== end.parent) { // start and end nodes belong to different subtrees return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } if (start !== end) { // start and end should be statements and parent should be either block or a source file if (!isBlockLike(start.parent)) { return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } var statements = []; for (var _i = 0, _a = start.parent.statements; _i < _a.length; _i++) { var statement = _a[_i]; if (statement === start || statements.length) { var errors_1 = checkNode(statement); if (errors_1) { return { errors: errors_1 }; } statements.push(statement); } if (statement === end) { break; } } return { targetRange: { range: statements, facts: rangeFacts, declarations: declarations } }; } if (ts.isReturnStatement(start) && !start.expression) { // Makes no sense to extract an expression-less return statement. return { errors: [ts.createFileDiagnostic(sourceFile, span.start, length, Messages.cannotExtractRange)] }; } // We have a single node (start) var node = refineNode(start); var errors = checkRootNode(node) || checkNode(node); if (errors) { return { errors: errors }; } return { targetRange: { range: getStatementOrExpressionRange(node), facts: rangeFacts, declarations: declarations } }; /** * Attempt to refine the extraction node (generally, by shrinking it) to produce better results. * @param node The unrefined extraction node. */ function refineNode(node) { if (ts.isReturnStatement(node)) { if (node.expression) { return node.expression; } } else if (ts.isVariableStatement(node)) { var numInitializers = 0; var lastInitializer = undefined; for (var _i = 0, _a = node.declarationList.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (declaration.initializer) { numInitializers++; lastInitializer = declaration.initializer; } } if (numInitializers === 1) { return lastInitializer; } // No special handling if there are multiple initializers. } else if (ts.isVariableDeclaration(node)) { if (node.initializer) { return node.initializer; } } return node; } function checkRootNode(node) { if (ts.isIdentifier(ts.isExpressionStatement(node) ? node.expression : node)) { return [ts.createDiagnosticForNode(node, Messages.cannotExtractIdentifier)]; } return undefined; } function checkForStaticContext(nodeToCheck, containingClass) { var current = nodeToCheck; while (current !== containingClass) { if (current.kind === 150 /* PropertyDeclaration */) { if (ts.hasModifier(current, 32 /* Static */)) { rangeFacts |= RangeFacts.InStaticRegion; } break; } else if (current.kind === 147 /* Parameter */) { var ctorOrMethod = ts.getContainingFunction(current); if (ctorOrMethod.kind === 153 /* Constructor */) { rangeFacts |= RangeFacts.InStaticRegion; } break; } else if (current.kind === 152 /* MethodDeclaration */) { if (ts.hasModifier(current, 32 /* Static */)) { rangeFacts |= RangeFacts.InStaticRegion; } } current = current.parent; } } // Verifies whether we can actually extract this node or not. function checkNode(nodeToCheck) { var PermittedJumps; (function (PermittedJumps) { PermittedJumps[PermittedJumps["None"] = 0] = "None"; PermittedJumps[PermittedJumps["Break"] = 1] = "Break"; PermittedJumps[PermittedJumps["Continue"] = 2] = "Continue"; PermittedJumps[PermittedJumps["Return"] = 4] = "Return"; })(PermittedJumps || (PermittedJumps = {})); if (!ts.isStatement(nodeToCheck) && !(ts.isExpressionNode(nodeToCheck) && isExtractableExpression(nodeToCheck))) { return [ts.createDiagnosticForNode(nodeToCheck, Messages.statementOrExpressionExpected)]; } if (nodeToCheck.flags & 2097152 /* Ambient */) { return [ts.createDiagnosticForNode(nodeToCheck, Messages.cannotExtractAmbientBlock)]; } // If we're in a class, see whether we're in a static region (static property initializer, static method, class constructor parameter default) var containingClass = ts.getContainingClass(nodeToCheck); if (containingClass) { checkForStaticContext(nodeToCheck, containingClass); } var errors; var permittedJumps = 4 /* Return */; var seenLabels; visit(nodeToCheck); return errors; function visit(node) { if (errors) { // already found an error - can stop now return true; } if (ts.isDeclaration(node)) { var declaringNode = (node.kind === 227 /* VariableDeclaration */) ? node.parent.parent : node; if (ts.hasModifier(declaringNode, 1 /* Export */)) { (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractExportedEntity)); return true; } declarations.push(node.symbol); } // Some things can't be extracted in certain situations switch (node.kind) { case 239 /* ImportDeclaration */: (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractImport)); return true; case 97 /* SuperKeyword */: // For a super *constructor call*, we have to be extracting the entire class, // but a super *method call* simply implies a 'this' reference if (node.parent.kind === 182 /* CallExpression */) { // Super constructor call var containingClass_1 = ts.getContainingClass(node); if (containingClass_1.pos < span.start || containingClass_1.end >= (span.start + span.length)) { (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractSuper)); return true; } } else { rangeFacts |= RangeFacts.UsesThis; } break; } if (!node || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node)) { switch (node.kind) { case 229 /* FunctionDeclaration */: case 230 /* ClassDeclaration */: if (node.parent.kind === 269 /* SourceFile */ && node.parent.externalModuleIndicator === undefined) { // You cannot extract global declarations (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.functionWillNotBeVisibleInTheNewScope)); } break; } // do not dive into functions or classes return false; } var savedPermittedJumps = permittedJumps; switch (node.kind) { case 212 /* IfStatement */: permittedJumps = 0 /* None */; break; case 225 /* TryStatement */: // forbid all jumps inside try blocks permittedJumps = 0 /* None */; break; case 208 /* Block */: if (node.parent && node.parent.kind === 225 /* TryStatement */ && node.parent.finallyBlock === node) { // allow unconditional returns from finally blocks permittedJumps = 4 /* Return */; } break; case 261 /* CaseClause */: // allow unlabeled break inside case clauses permittedJumps |= 1 /* Break */; break; default: if (ts.isIterationStatement(node, /*lookInLabeledStatements*/ false)) { // allow unlabeled break/continue inside loops permittedJumps |= 1 /* Break */ | 2 /* Continue */; } break; } switch (node.kind) { case 170 /* ThisType */: case 99 /* ThisKeyword */: rangeFacts |= RangeFacts.UsesThis; break; case 223 /* LabeledStatement */: { var label = node.label; (seenLabels || (seenLabels = [])).push(label.escapedText); ts.forEachChild(node, visit); seenLabels.pop(); break; } case 219 /* BreakStatement */: case 218 /* ContinueStatement */: { var label = node.label; if (label) { if (!ts.contains(seenLabels, label.escapedText)) { // attempts to jump to label that is not in range to be extracted (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingLabeledBreakOrContinueStatementWithTargetOutsideOfTheRange)); } } else { if (!(permittedJumps & (node.kind === 219 /* BreakStatement */ ? 1 /* Break */ : 2 /* Continue */))) { // attempt to break or continue in a forbidden context (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalBreakOrContinueStatements)); } } break; } case 192 /* AwaitExpression */: rangeFacts |= RangeFacts.IsAsyncFunction; break; case 198 /* YieldExpression */: rangeFacts |= RangeFacts.IsGenerator; break; case 220 /* ReturnStatement */: if (permittedJumps & 4 /* Return */) { rangeFacts |= RangeFacts.HasReturn; } else { (errors || (errors = [])).push(ts.createDiagnosticForNode(node, Messages.cannotExtractRangeContainingConditionalReturnStatement)); } break; default: ts.forEachChild(node, visit); break; } permittedJumps = savedPermittedJumps; } } } extractSymbol_1.getRangeToExtract = getRangeToExtract; function getStatementOrExpressionRange(node) { if (ts.isStatement(node)) { return [node]; } else if (ts.isExpressionNode(node)) { // If our selection is the expression in an ExpressionStatement, expand // the selection to include the enclosing Statement (this stops us // from trying to care about the return value of the extracted function // and eliminates double semicolon insertion in certain scenarios) return ts.isExpressionStatement(node.parent) ? [node.parent] : node; } return undefined; } function isScope(node) { return ts.isFunctionLikeDeclaration(node) || ts.isSourceFile(node) || ts.isModuleBlock(node) || ts.isClassLike(node); } /** * Computes possible places we could extract the function into. For example, * you may be able to extract into a class method *or* local closure *or* namespace function, * depending on what's in the extracted body. */ function collectEnclosingScopes(range) { var current = isReadonlyArray(range.range) ? ts.first(range.range) : range.range; if (range.facts & RangeFacts.UsesThis) { // if range uses this as keyword or as type inside the class then it can only be extracted to a method of the containing class var containingClass = ts.getContainingClass(current); if (containingClass) { var containingFunction = ts.findAncestor(current, ts.isFunctionLikeDeclaration); return containingFunction ? [containingFunction, containingClass] : [containingClass]; } } var scopes = []; while (true) { current = current.parent; // A function parameter's initializer is actually in the outer scope, not the function declaration if (current.kind === 147 /* Parameter */) { // Skip all the way to the outer scope of the function that declared this parameter current = ts.findAncestor(current, function (parent) { return ts.isFunctionLikeDeclaration(parent); }).parent; } // We want to find the nearest parent where we can place an "equivalent" sibling to the node we're extracting out of. // Walk up to the closest parent of a place where we can logically put a sibling: // * Function declaration // * Class declaration or expression // * Module/namespace or source file if (isScope(current)) { scopes.push(current); if (current.kind === 269 /* SourceFile */) { return scopes; } } } } function getFunctionExtractionAtIndex(targetRange, context, requestedChangesIndex) { var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, functionErrorsPerScope = _b.functionErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations; ts.Debug.assert(!functionErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); context.cancellationToken.throwIfCancellationRequested(); return extractFunctionInScope(target, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], exposedVariableDeclarations, targetRange, context); } function getConstantExtractionAtIndex(targetRange, context, requestedChangesIndex) { var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, target = _b.target, usagesPerScope = _b.usagesPerScope, constantErrorsPerScope = _b.constantErrorsPerScope, exposedVariableDeclarations = _b.exposedVariableDeclarations; ts.Debug.assert(!constantErrorsPerScope[requestedChangesIndex].length, "The extraction went missing? How?"); ts.Debug.assert(exposedVariableDeclarations.length === 0, "Extract constant accepted a range containing a variable declaration?"); context.cancellationToken.throwIfCancellationRequested(); var expression = ts.isExpression(target) ? target : target.statements[0].expression; return extractConstantInScope(expression, scopes[requestedChangesIndex], usagesPerScope[requestedChangesIndex], targetRange.facts, context); } /** * Given a piece of text to extract ('targetRange'), computes a list of possible extractions. * Each returned ExtractResultForScope corresponds to a possible target scope and is either a set of changes * or an error explaining why we can't extract into that scope. */ function getPossibleExtractions(targetRange, context) { var _a = getPossibleExtractionsWorker(targetRange, context), scopes = _a.scopes, _b = _a.readsAndWrites, functionErrorsPerScope = _b.functionErrorsPerScope, constantErrorsPerScope = _b.constantErrorsPerScope; // Need the inner type annotation to avoid https://github.com/Microsoft/TypeScript/issues/7547 var extractions = scopes.map(function (scope, i) { var functionDescriptionPart = getDescriptionForFunctionInScope(scope); var constantDescriptionPart = getDescriptionForConstantInScope(scope); var scopeDescription = ts.isFunctionLikeDeclaration(scope) ? getDescriptionForFunctionLikeDeclaration(scope) : ts.isClassLike(scope) ? getDescriptionForClassLikeDeclaration(scope) : getDescriptionForModuleLikeDeclaration(scope); var functionDescription; var constantDescription; if (scopeDescription === 1 /* Global */) { functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "global"]); constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "global"]); } else if (scopeDescription === 0 /* Module */) { functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [functionDescriptionPart, "module"]); constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1_scope), [constantDescriptionPart, "module"]); } else { functionDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [functionDescriptionPart, scopeDescription]); constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_1), [constantDescriptionPart, scopeDescription]); } // Customize the phrasing for the innermost scope to increase clarity. if (i === 0 && !ts.isClassLike(scope)) { constantDescription = ts.formatStringFromArgs(ts.getLocaleSpecificMessage(ts.Diagnostics.Extract_to_0_in_enclosing_scope), [constantDescriptionPart]); } return { functionExtraction: { description: functionDescription, errors: functionErrorsPerScope[i], }, constantExtraction: { description: constantDescription, errors: constantErrorsPerScope[i], }, }; }); return extractions; } function getPossibleExtractionsWorker(targetRange, context) { var sourceFile = context.file; var scopes = collectEnclosingScopes(targetRange); var enclosingTextRange = getEnclosingTextRange(targetRange, sourceFile); var readsAndWrites = collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, context.program.getTypeChecker(), context.cancellationToken); return { scopes: scopes, readsAndWrites: readsAndWrites }; } function getDescriptionForFunctionInScope(scope) { return ts.isFunctionLikeDeclaration(scope) ? "inner function" : ts.isClassLike(scope) ? "method" : "function"; } function getDescriptionForConstantInScope(scope) { return ts.isClassLike(scope) ? "readonly field" : "constant"; } function getDescriptionForFunctionLikeDeclaration(scope) { switch (scope.kind) { case 153 /* Constructor */: return "constructor"; case 187 /* FunctionExpression */: return scope.name ? "function expression '" + scope.name.text + "'" : "anonymous function expression"; case 229 /* FunctionDeclaration */: return "function '" + scope.name.text + "'"; case 188 /* ArrowFunction */: return "arrow function"; case 152 /* MethodDeclaration */: return "method '" + scope.name.getText(); case 154 /* GetAccessor */: return "'get " + scope.name.getText() + "'"; case 155 /* SetAccessor */: return "'set " + scope.name.getText() + "'"; default: ts.Debug.assertNever(scope); } } function getDescriptionForClassLikeDeclaration(scope) { return scope.kind === 230 /* ClassDeclaration */ ? "class '" + scope.name.text + "'" : scope.name ? "class expression '" + scope.name.text + "'" : "anonymous class expression"; } function getDescriptionForModuleLikeDeclaration(scope) { return scope.kind === 235 /* ModuleBlock */ ? "namespace '" + scope.parent.name.getText() + "'" : scope.externalModuleIndicator ? 0 /* Module */ : 1 /* Global */; } var SpecialScope; (function (SpecialScope) { SpecialScope[SpecialScope["Module"] = 0] = "Module"; SpecialScope[SpecialScope["Global"] = 1] = "Global"; })(SpecialScope || (SpecialScope = {})); function getUniqueName(baseName, fileText) { var nameText = baseName; for (var i = 1; ts.stringContains(fileText, nameText); i++) { nameText = baseName + "_" + i; } return nameText; } /** * Result of 'extractRange' operation for a specific scope. * Stores either a list of changes that should be applied to extract a range or a list of errors */ function extractFunctionInScope(node, scope, _a, exposedVariableDeclarations, range, context) { var usagesInScope = _a.usages, typeParameterUsages = _a.typeParameterUsages, substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); // Make a unique name for the extracted function var file = scope.getSourceFile(); var functionNameText = getUniqueName(ts.isClassLike(scope) ? "newMethod" : "newFunction", file.text); var isJS = ts.isInJavaScriptFile(scope); var functionName = ts.createIdentifier(functionNameText); var returnType = undefined; var parameters = []; var callArguments = []; var writes; usagesInScope.forEach(function (usage, name) { var typeNode = undefined; if (!isJS) { var type = checker.getTypeOfSymbolAtLocation(usage.symbol, usage.node); // Widen the type so we don't emit nonsense annotations like "function fn(x: 3) {" type = checker.getBaseTypeOfLiteralType(type); typeNode = checker.typeToTypeNode(type, scope, ts.NodeBuilderFlags.NoTruncation); } var paramDecl = ts.createParameter( /*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, /*name*/ name, /*questionToken*/ undefined, typeNode); parameters.push(paramDecl); if (usage.usage === 2 /* Write */) { (writes || (writes = [])).push(usage); } callArguments.push(ts.createIdentifier(name)); }); var typeParametersAndDeclarations = ts.arrayFrom(typeParameterUsages.values()).map(function (type) { return ({ type: type, declaration: getFirstDeclaration(type) }); }); var sortedTypeParametersAndDeclarations = typeParametersAndDeclarations.sort(compareTypesByDeclarationOrder); var typeParameters = sortedTypeParametersAndDeclarations.length === 0 ? undefined : sortedTypeParametersAndDeclarations.map(function (t) { return t.declaration; }); // Strictly speaking, we should check whether each name actually binds to the appropriate type // parameter. In cases of shadowing, they may not. var callTypeArguments = typeParameters !== undefined ? typeParameters.map(function (decl) { return ts.createTypeReferenceNode(decl.name, /*typeArguments*/ undefined); }) : undefined; // Provide explicit return types for contextually-typed functions // to avoid problems when there are literal types present if (ts.isExpression(node) && !isJS) { var contextualType = checker.getContextualType(node); returnType = checker.typeToTypeNode(contextualType, scope, ts.NodeBuilderFlags.NoTruncation); } var _b = transformFunctionBody(node, exposedVariableDeclarations, writes, substitutions, !!(range.facts & RangeFacts.HasReturn)), body = _b.body, returnValueProperty = _b.returnValueProperty; ts.suppressLeadingAndTrailingTrivia(body); var newFunction; if (ts.isClassLike(scope)) { // always create private method in TypeScript files var modifiers = isJS ? [] : [ts.createToken(112 /* PrivateKeyword */)]; if (range.facts & RangeFacts.InStaticRegion) { modifiers.push(ts.createToken(115 /* StaticKeyword */)); } if (range.facts & RangeFacts.IsAsyncFunction) { modifiers.push(ts.createToken(120 /* AsyncKeyword */)); } newFunction = ts.createMethod( /*decorators*/ undefined, modifiers.length ? modifiers : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, /*questionToken*/ undefined, typeParameters, parameters, returnType, body); } else { newFunction = ts.createFunctionDeclaration( /*decorators*/ undefined, range.facts & RangeFacts.IsAsyncFunction ? [ts.createToken(120 /* AsyncKeyword */)] : undefined, range.facts & RangeFacts.IsGenerator ? ts.createToken(39 /* AsteriskToken */) : undefined, functionName, typeParameters, parameters, returnType, body); } var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); var minInsertionPos = (isReadonlyArray(range.range) ? ts.last(range.range) : range.range).end; var nodeToInsertBefore = getNodeToInsertFunctionBefore(minInsertionPos, scope); if (nodeToInsertBefore) { changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newFunction, { suffix: context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeBefore(context.file, scope.getLastToken(), newFunction, { prefix: ts.isLineBreak(file.text.charCodeAt(scope.getLastToken().pos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter, suffix: context.newLineCharacter }); } var newNodes = []; // replace range with function call var called = getCalledExpression(scope, range, functionNameText); var call = ts.createCall(called, callTypeArguments, // Note that no attempt is made to take advantage of type argument inference callArguments); if (range.facts & RangeFacts.IsGenerator) { call = ts.createYield(ts.createToken(39 /* AsteriskToken */), call); } if (range.facts & RangeFacts.IsAsyncFunction) { call = ts.createAwait(call); } if (exposedVariableDeclarations.length && !writes) { // No need to mix declarations and writes. // How could any variables be exposed if there's a return statement? ts.Debug.assert(!returnValueProperty); ts.Debug.assert(!(range.facts & RangeFacts.HasReturn)); if (exposedVariableDeclarations.length === 1) { // Declaring exactly one variable: let x = newFunction(); var variableDeclaration = exposedVariableDeclarations[0]; newNodes.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.getSynthesizedDeepClone(variableDeclaration.name), /*type*/ ts.getSynthesizedDeepClone(variableDeclaration.type), /*initializer*/ call)], // TODO (acasey): test binding patterns variableDeclaration.parent.flags))); } else { // Declaring multiple variables / return properties: // let {x, y} = newFunction(); var bindingElements = []; var typeElements = []; var commonNodeFlags = exposedVariableDeclarations[0].parent.flags; var sawExplicitType = false; for (var _i = 0, exposedVariableDeclarations_1 = exposedVariableDeclarations; _i < exposedVariableDeclarations_1.length; _i++) { var variableDeclaration = exposedVariableDeclarations_1[_i]; bindingElements.push(ts.createBindingElement( /*dotDotDotToken*/ undefined, /*propertyName*/ undefined, /*name*/ ts.getSynthesizedDeepClone(variableDeclaration.name))); // Being returned through an object literal will have widened the type. var variableType = checker.typeToTypeNode(checker.getBaseTypeOfLiteralType(checker.getTypeAtLocation(variableDeclaration)), scope, ts.NodeBuilderFlags.NoTruncation); typeElements.push(ts.createPropertySignature( /*modifiers*/ undefined, /*name*/ variableDeclaration.symbol.name, /*questionToken*/ undefined, /*type*/ variableType, /*initializer*/ undefined)); sawExplicitType = sawExplicitType || variableDeclaration.type !== undefined; commonNodeFlags = commonNodeFlags & variableDeclaration.parent.flags; } var typeLiteral = sawExplicitType ? ts.createTypeLiteralNode(typeElements) : undefined; if (typeLiteral) { ts.setEmitFlags(typeLiteral, 1 /* SingleLine */); } newNodes.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(ts.createObjectBindingPattern(bindingElements), /*type*/ typeLiteral, /*initializer*/ call)], commonNodeFlags))); } } else if (exposedVariableDeclarations.length || writes) { if (exposedVariableDeclarations.length) { // CONSIDER: we're going to create one statement per variable, but we could actually preserve their original grouping. for (var _c = 0, exposedVariableDeclarations_2 = exposedVariableDeclarations; _c < exposedVariableDeclarations_2.length; _c++) { var variableDeclaration = exposedVariableDeclarations_2[_c]; var flags = variableDeclaration.parent.flags; if (flags & 2 /* Const */) { flags = (flags & ~2 /* Const */) | 1 /* Let */; } newNodes.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(variableDeclaration.symbol.name, getTypeDeepCloneUnionUndefined(variableDeclaration.type))], flags))); } } if (returnValueProperty) { // has both writes and return, need to create variable declaration to hold return value; newNodes.push(ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([ts.createVariableDeclaration(returnValueProperty, getTypeDeepCloneUnionUndefined(returnType))], 1 /* Let */))); } var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (returnValueProperty) { assignments.unshift(ts.createShorthandPropertyAssignment(returnValueProperty)); } // propagate writes back if (assignments.length === 1) { // We would only have introduced a return value property if there had been // other assignments to make. ts.Debug.assert(!returnValueProperty); newNodes.push(ts.createStatement(ts.createAssignment(assignments[0].name, call))); if (range.facts & RangeFacts.HasReturn) { newNodes.push(ts.createReturn()); } } else { // emit e.g. // { a, b, __return } = newFunction(a, b); // return __return; newNodes.push(ts.createStatement(ts.createAssignment(ts.createObjectLiteral(assignments), call))); if (returnValueProperty) { newNodes.push(ts.createReturn(ts.createIdentifier(returnValueProperty))); } } } else { if (range.facts & RangeFacts.HasReturn) { newNodes.push(ts.createReturn(call)); } else if (isReadonlyArray(range.range)) { newNodes.push(ts.createStatement(call)); } else { newNodes.push(call); } } var replacementRange = isReadonlyArray(range.range) ? { pos: ts.first(range.range).getStart(), end: ts.last(range.range).end } : { pos: range.range.getStart(), end: range.range.end }; changeTracker.replaceRangeWithNodes(context.file, replacementRange, newNodes, { nodeSeparator: context.newLineCharacter }); var edits = changeTracker.getChanges(); var renameRange = isReadonlyArray(range.range) ? ts.first(range.range) : range.range; var renameFilename = renameRange.getSourceFile().fileName; var renameLocation = getRenameLocation(edits, renameFilename, functionNameText, /*isDeclaredBeforeUse*/ false); return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; function getTypeDeepCloneUnionUndefined(typeNode) { if (typeNode === undefined) { return undefined; } var clone = ts.getSynthesizedDeepClone(typeNode); var withoutParens = clone; while (ts.isParenthesizedTypeNode(withoutParens)) { withoutParens = withoutParens.type; } return ts.isUnionTypeNode(withoutParens) && ts.find(withoutParens.types, function (t) { return t.kind === 139 /* UndefinedKeyword */; }) ? clone : ts.createUnionTypeNode([clone, ts.createKeywordTypeNode(139 /* UndefinedKeyword */)]); } } /** * Result of 'extractRange' operation for a specific scope. * Stores either a list of changes that should be applied to extract a range or a list of errors */ function extractConstantInScope(node, scope, _a, rangeFacts, context) { var substitutions = _a.substitutions; var checker = context.program.getTypeChecker(); // Make a unique name for the extracted variable var file = scope.getSourceFile(); var localNameText = getUniqueName(ts.isClassLike(scope) ? "newProperty" : "newLocal", file.text); var isJS = ts.isInJavaScriptFile(scope); var variableType = isJS ? undefined : checker.typeToTypeNode(checker.getContextualType(node), scope, ts.NodeBuilderFlags.NoTruncation); var initializer = transformConstantInitializer(node, substitutions); ts.suppressLeadingAndTrailingTrivia(initializer); var changeTracker = ts.textChanges.ChangeTracker.fromContext(context); if (ts.isClassLike(scope)) { ts.Debug.assert(!isJS); // See CannotExtractToJSClass var modifiers = []; modifiers.push(ts.createToken(112 /* PrivateKeyword */)); if (rangeFacts & RangeFacts.InStaticRegion) { modifiers.push(ts.createToken(115 /* StaticKeyword */)); } modifiers.push(ts.createToken(131 /* ReadonlyKeyword */)); var newVariable = ts.createProperty( /*decorators*/ undefined, modifiers, localNameText, /*questionToken*/ undefined, variableType, initializer); var localReference = ts.createPropertyAccess(rangeFacts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.getText()) : ts.createThis(), ts.createIdentifier(localNameText)); // Declare var maxInsertionPos = node.pos; var nodeToInsertBefore = getNodeToInsertPropertyBefore(maxInsertionPos, scope); changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariable, { suffix: context.newLineCharacter + context.newLineCharacter }); // Consume changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); } else { var newVariableDeclaration = ts.createVariableDeclaration(localNameText, variableType, initializer); // If the node is part of an initializer in a list of variable declarations, insert a new // variable declaration into the list (in case it depends on earlier ones). // CONSIDER: If the declaration list isn't const, we might want to split it into multiple // lists so that the newly extracted one can be const. var oldVariableDeclaration = getContainingVariableDeclarationIfInList(node, scope); if (oldVariableDeclaration) { // Declare // CONSIDER: could detect that each is on a separate line changeTracker.insertNodeAt(context.file, oldVariableDeclaration.getStart(), newVariableDeclaration, { suffix: ", " }); // Consume var localReference = ts.createIdentifier(localNameText); changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); } else if (node.parent.kind === 211 /* ExpressionStatement */ && scope === ts.findAncestor(node, isScope)) { // If the parent is an expression statement and the target scope is the immediately enclosing one, // replace the statement with the declaration. var newVariableStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */)); changeTracker.replaceRange(context.file, { pos: node.parent.getStart(), end: node.parent.end }, newVariableStatement); } else { var newVariableStatement = ts.createVariableStatement( /*modifiers*/ undefined, ts.createVariableDeclarationList([newVariableDeclaration], 2 /* Const */)); // Declare var nodeToInsertBefore = getNodeToInsertConstantBefore(node, scope); if (nodeToInsertBefore.pos === 0) { // If we're at the beginning of the file, we need to take care not to insert before header comments // (e.g. copyright, triple-slash references). Fortunately, this problem has already been solved // for imports. var insertionPos = ts.getSourceFileImportLocation(file); changeTracker.insertNodeAt(context.file, insertionPos, newVariableStatement, { prefix: insertionPos === 0 ? undefined : context.newLineCharacter, suffix: ts.isLineBreak(file.text.charCodeAt(insertionPos)) ? context.newLineCharacter : context.newLineCharacter + context.newLineCharacter }); } else { changeTracker.insertNodeBefore(context.file, nodeToInsertBefore, newVariableStatement, { suffix: context.newLineCharacter + context.newLineCharacter }); } // Consume if (node.parent.kind === 211 /* ExpressionStatement */) { // If the parent is an expression statement, delete it. changeTracker.deleteRange(context.file, { pos: node.parent.getStart(), end: node.parent.end }); } else { var localReference = ts.createIdentifier(localNameText); changeTracker.replaceRange(context.file, { pos: node.getStart(), end: node.end }, localReference); } } } var edits = changeTracker.getChanges(); var renameFilename = node.getSourceFile().fileName; var renameLocation = getRenameLocation(edits, renameFilename, localNameText, /*isDeclaredBeforeUse*/ true); return { renameFilename: renameFilename, renameLocation: renameLocation, edits: edits }; } function getContainingVariableDeclarationIfInList(node, scope) { var prevNode = undefined; while (node !== undefined && node !== scope) { if (ts.isVariableDeclaration(node) && node.initializer === prevNode && ts.isVariableDeclarationList(node.parent) && node.parent.declarations.length > 1) { return node; } prevNode = node; node = node.parent; } } /** * @return The index of the (only) reference to the extracted symbol. We want the cursor * to be on the reference, rather than the declaration, because it's closer to where the * user was before extracting it. */ function getRenameLocation(edits, renameFilename, functionNameText, isDeclaredBeforeUse) { var delta = 0; var lastPos = -1; for (var _i = 0, edits_1 = edits; _i < edits_1.length; _i++) { var _a = edits_1[_i], fileName = _a.fileName, textChanges_1 = _a.textChanges; ts.Debug.assert(fileName === renameFilename); for (var _b = 0, textChanges_2 = textChanges_1; _b < textChanges_2.length; _b++) { var change = textChanges_2[_b]; var span_15 = change.span, newText = change.newText; var index = newText.indexOf(functionNameText); if (index !== -1) { lastPos = span_15.start + delta + index; // If the reference comes first, return immediately. if (!isDeclaredBeforeUse) { return lastPos; } } delta += newText.length - span_15.length; } } // If the declaration comes first, return the position of the last occurrence. ts.Debug.assert(isDeclaredBeforeUse); ts.Debug.assert(lastPos >= 0); return lastPos; } function getFirstDeclaration(type) { var firstDeclaration = undefined; var symbol = type.symbol; if (symbol && symbol.declarations) { for (var _i = 0, _a = symbol.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; if (firstDeclaration === undefined || declaration.pos < firstDeclaration.pos) { firstDeclaration = declaration; } } } return firstDeclaration; } function compareTypesByDeclarationOrder(_a, _b) { var type1 = _a.type, declaration1 = _a.declaration; var type2 = _b.type, declaration2 = _b.declaration; return ts.compareProperties(declaration1, declaration2, "pos", ts.compareValues) || ts.compareStringsCaseSensitive(type1.symbol ? type1.symbol.getName() : "", type2.symbol ? type2.symbol.getName() : "") || ts.compareValues(type1.id, type2.id); } function getCalledExpression(scope, range, functionNameText) { var functionReference = ts.createIdentifier(functionNameText); if (ts.isClassLike(scope)) { var lhs = range.facts & RangeFacts.InStaticRegion ? ts.createIdentifier(scope.name.text) : ts.createThis(); return ts.createPropertyAccess(lhs, functionReference); } else { return functionReference; } } function transformFunctionBody(body, exposedVariableDeclarations, writes, substitutions, hasReturn) { var hasWritesOrVariableDeclarations = writes !== undefined || exposedVariableDeclarations.length > 0; if (ts.isBlock(body) && !hasWritesOrVariableDeclarations && substitutions.size === 0) { // already block, no declarations or writes to propagate back, no substitutions - can use node as is return { body: ts.createBlock(body.statements, /*multLine*/ true), returnValueProperty: undefined }; } var returnValueProperty; var ignoreReturns = false; var statements = ts.createNodeArray(ts.isBlock(body) ? body.statements.slice(0) : [ts.isStatement(body) ? body : ts.createReturn(body)]); // rewrite body if either there are writes that should be propagated back via return statements or there are substitutions if (hasWritesOrVariableDeclarations || substitutions.size) { var rewrittenStatements = ts.visitNodes(statements, visitor).slice(); if (hasWritesOrVariableDeclarations && !hasReturn && ts.isStatement(body)) { // add return at the end to propagate writes back in case if control flow falls out of the function body // it is ok to know that range has at least one return since it we only allow unconditional returns var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (assignments.length === 1) { rewrittenStatements.push(ts.createReturn(assignments[0].name)); } else { rewrittenStatements.push(ts.createReturn(ts.createObjectLiteral(assignments))); } } return { body: ts.createBlock(rewrittenStatements, /*multiLine*/ true), returnValueProperty: returnValueProperty }; } else { return { body: ts.createBlock(statements, /*multiLine*/ true), returnValueProperty: undefined }; } function visitor(node) { if (!ignoreReturns && node.kind === 220 /* ReturnStatement */ && hasWritesOrVariableDeclarations) { var assignments = getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes); if (node.expression) { if (!returnValueProperty) { returnValueProperty = "__return"; } assignments.unshift(ts.createPropertyAssignment(returnValueProperty, ts.visitNode(node.expression, visitor))); } if (assignments.length === 1) { return ts.createReturn(assignments[0].name); } else { return ts.createReturn(ts.createObjectLiteral(assignments)); } } else { var oldIgnoreReturns = ignoreReturns; ignoreReturns = ignoreReturns || ts.isFunctionLikeDeclaration(node) || ts.isClassLike(node); var substitution = substitutions.get(ts.getNodeId(node).toString()); var result = substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext); ignoreReturns = oldIgnoreReturns; return result; } } } function transformConstantInitializer(initializer, substitutions) { return substitutions.size ? visitor(initializer) : initializer; function visitor(node) { var substitution = substitutions.get(ts.getNodeId(node).toString()); return substitution ? ts.getSynthesizedDeepClone(substitution) : ts.visitEachChild(node, visitor, ts.nullTransformationContext); } } function getStatementsOrClassElements(scope) { if (ts.isFunctionLikeDeclaration(scope)) { var body = scope.body; if (ts.isBlock(body)) { return body.statements; } } else if (ts.isModuleBlock(scope) || ts.isSourceFile(scope)) { return scope.statements; } else if (ts.isClassLike(scope)) { return scope.members; } else { ts.assertTypeIsNever(scope); } return ts.emptyArray; } /** * If `scope` contains a function after `minPos`, then return the first such function. * Otherwise, return `undefined`. */ function getNodeToInsertFunctionBefore(minPos, scope) { return ts.find(getStatementsOrClassElements(scope), function (child) { return child.pos >= minPos && ts.isFunctionLikeDeclaration(child) && !ts.isConstructorDeclaration(child); }); } function getNodeToInsertPropertyBefore(maxPos, scope) { var members = scope.members; ts.Debug.assert(members.length > 0); // There must be at least one child, since we extracted from one. var prevMember = undefined; var allProperties = true; for (var _i = 0, members_6 = members; _i < members_6.length; _i++) { var member = members_6[_i]; if (member.pos > maxPos) { return prevMember || members[0]; } if (allProperties && !ts.isPropertyDeclaration(member)) { // If it is non-vacuously true that all preceding members are properties, // insert before the current member (i.e. at the end of the list of properties). if (prevMember !== undefined) { return member; } allProperties = false; } prevMember = member; } ts.Debug.assert(prevMember !== undefined); // If the loop didn't return, then it did set prevMember. return prevMember; } function getNodeToInsertConstantBefore(node, scope) { ts.Debug.assert(!ts.isClassLike(scope)); var prevScope = undefined; for (var curr = node; curr !== scope; curr = curr.parent) { if (isScope(curr)) { prevScope = curr; } } for (var curr = (prevScope || node).parent;; curr = curr.parent) { if (isBlockLike(curr)) { var prevStatement = undefined; for (var _i = 0, _a = curr.statements; _i < _a.length; _i++) { var statement = _a[_i]; if (statement.pos > node.pos) { break; } prevStatement = statement; } // There must be at least one statement since we started in one. ts.Debug.assert(prevStatement !== undefined); return prevStatement; } if (curr === scope) { ts.Debug.fail("Didn't encounter a block-like before encountering scope"); break; } } } function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) { var variableAssignments = ts.map(exposedVariableDeclarations, function (v) { return ts.createShorthandPropertyAssignment(v.symbol.name); }); var writeAssignments = ts.map(writes, function (w) { return ts.createShorthandPropertyAssignment(w.symbol.name); }); return variableAssignments === undefined ? writeAssignments : writeAssignments === undefined ? variableAssignments : variableAssignments.concat(writeAssignments); } function isReadonlyArray(v) { return ts.isArray(v); } /** * Produces a range that spans the entirety of nodes, given a selection * that might start/end in the middle of nodes. * * For example, when the user makes a selection like this * v---v * var someThing = foo + bar; * this returns ^-------^ */ function getEnclosingTextRange(targetRange, sourceFile) { return isReadonlyArray(targetRange.range) ? { pos: ts.first(targetRange.range).getStart(sourceFile), end: ts.last(targetRange.range).getEnd() } : targetRange.range; } var Usage; (function (Usage) { // value should be passed to extracted method Usage[Usage["Read"] = 1] = "Read"; // value should be passed to extracted method and propagated back Usage[Usage["Write"] = 2] = "Write"; })(Usage || (Usage = {})); function collectReadsAndWrites(targetRange, scopes, enclosingTextRange, sourceFile, checker, cancellationToken) { var allTypeParameterUsages = ts.createMap(); // Key is type ID var usagesPerScope = []; var substitutionsPerScope = []; var functionErrorsPerScope = []; var constantErrorsPerScope = []; var visibleDeclarationsInExtractedRange = []; var exposedVariableSymbolSet = ts.createMap(); // Key is symbol ID var exposedVariableDeclarations = []; var firstExposedNonVariableDeclaration = undefined; var expression = !isReadonlyArray(targetRange.range) ? targetRange.range : targetRange.range.length === 1 && ts.isExpressionStatement(targetRange.range[0]) ? targetRange.range[0].expression : undefined; var expressionDiagnostic = undefined; if (expression === undefined) { var statements = targetRange.range; var start = ts.first(statements).getStart(); var end = ts.last(statements).end; expressionDiagnostic = ts.createFileDiagnostic(sourceFile, start, end - start, Messages.expressionExpected); } else if (checker.getTypeAtLocation(expression).flags & (2048 /* Void */ | 16384 /* Never */)) { expressionDiagnostic = ts.createDiagnosticForNode(expression, Messages.uselessConstantType); } // initialize results for (var _i = 0, scopes_1 = scopes; _i < scopes_1.length; _i++) { var scope = scopes_1[_i]; usagesPerScope.push({ usages: ts.createMap(), typeParameterUsages: ts.createMap(), substitutions: ts.createMap() }); substitutionsPerScope.push(ts.createMap()); functionErrorsPerScope.push(ts.isFunctionLikeDeclaration(scope) && scope.kind !== 229 /* FunctionDeclaration */ ? [ts.createDiagnosticForNode(scope, Messages.cannotExtractToOtherFunctionLike)] : []); var constantErrors = []; if (expressionDiagnostic) { constantErrors.push(expressionDiagnostic); } if (ts.isClassLike(scope) && ts.isInJavaScriptFile(scope)) { constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToJSClass)); } if (ts.isArrowFunction(scope) && !ts.isBlock(scope.body)) { // TODO (https://github.com/Microsoft/TypeScript/issues/18924): allow this constantErrors.push(ts.createDiagnosticForNode(scope, Messages.cannotExtractToExpressionArrowFunction)); } constantErrorsPerScope.push(constantErrors); } var seenUsages = ts.createMap(); var target = isReadonlyArray(targetRange.range) ? ts.createBlock(targetRange.range) : targetRange.range; var unmodifiedNode = isReadonlyArray(targetRange.range) ? ts.first(targetRange.range) : targetRange.range; var inGenericContext = isInGenericContext(unmodifiedNode); collectUsages(target); // Unfortunately, this code takes advantage of the knowledge that the generated method // will use the contextual type of an expression as the return type of the extracted // method (and will therefore "use" all the types involved). if (inGenericContext && !isReadonlyArray(targetRange.range)) { var contextualType = checker.getContextualType(targetRange.range); recordTypeParameterUsages(contextualType); } if (allTypeParameterUsages.size > 0) { var seenTypeParameterUsages = ts.createMap(); // Key is type ID var i_1 = 0; for (var curr = unmodifiedNode; curr !== undefined && i_1 < scopes.length; curr = curr.parent) { if (curr === scopes[i_1]) { // Copy current contents of seenTypeParameterUsages into scope. seenTypeParameterUsages.forEach(function (typeParameter, id) { usagesPerScope[i_1].typeParameterUsages.set(id, typeParameter); }); i_1++; } // Note that we add the current node's type parameters *after* updating the corresponding scope. if (ts.isDeclarationWithTypeParameters(curr) && curr.typeParameters) { for (var _a = 0, _b = curr.typeParameters; _a < _b.length; _a++) { var typeParameterDecl = _b[_a]; var typeParameter = checker.getTypeAtLocation(typeParameterDecl); if (allTypeParameterUsages.has(typeParameter.id.toString())) { seenTypeParameterUsages.set(typeParameter.id.toString(), typeParameter); } } } } // If we didn't get through all the scopes, then there were some that weren't in our // parent chain (impossible at time of writing). A conservative solution would be to // copy allTypeParameterUsages into all remaining scopes. ts.Debug.assert(i_1 === scopes.length); } // If there are any declarations in the extracted block that are used in the same enclosing // lexical scope, we can't move the extraction "up" as those declarations will become unreachable if (visibleDeclarationsInExtractedRange.length) { var containingLexicalScopeOfExtraction = ts.isBlockScope(scopes[0], scopes[0].parent) ? scopes[0] : ts.getEnclosingBlockScopeContainer(scopes[0]); ts.forEachChild(containingLexicalScopeOfExtraction, checkForUsedDeclarations); } var _loop_10 = function (i) { var scopeUsages = usagesPerScope[i]; // Special case: in the innermost scope, all usages are available. // (The computed value reflects the value at the top-level of the scope, but the // local will actually be declared at the same level as the extracted expression). if (i > 0 && (scopeUsages.usages.size > 0 || scopeUsages.typeParameterUsages.size > 0)) { var errorNode = isReadonlyArray(targetRange.range) ? targetRange.range[0] : targetRange.range; constantErrorsPerScope[i].push(ts.createDiagnosticForNode(errorNode, Messages.cannotAccessVariablesFromNestedScopes)); } var hasWrite = false; var readonlyClassPropertyWrite = undefined; usagesPerScope[i].usages.forEach(function (value) { if (value.usage === 2 /* Write */) { hasWrite = true; if (value.symbol.flags & 106500 /* ClassMember */ && value.symbol.valueDeclaration && ts.hasModifier(value.symbol.valueDeclaration, 64 /* Readonly */)) { readonlyClassPropertyWrite = value.symbol.valueDeclaration; } } }); // If an expression was extracted, then there shouldn't have been any variable declarations. ts.Debug.assert(isReadonlyArray(targetRange.range) || exposedVariableDeclarations.length === 0); if (hasWrite && !isReadonlyArray(targetRange.range)) { var diag = ts.createDiagnosticForNode(targetRange.range, Messages.cannotWriteInExpression); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (readonlyClassPropertyWrite && i > 0) { var diag = ts.createDiagnosticForNode(readonlyClassPropertyWrite, Messages.cannotExtractReadonlyPropertyInitializerOutsideConstructor); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } else if (firstExposedNonVariableDeclaration) { var diag = ts.createDiagnosticForNode(firstExposedNonVariableDeclaration, Messages.cannotExtractExportedEntity); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } }; for (var i = 0; i < scopes.length; i++) { _loop_10(i); } return { target: target, usagesPerScope: usagesPerScope, functionErrorsPerScope: functionErrorsPerScope, constantErrorsPerScope: constantErrorsPerScope, exposedVariableDeclarations: exposedVariableDeclarations }; function hasTypeParameters(node) { return ts.isDeclarationWithTypeParameters(node) && node.typeParameters !== undefined && node.typeParameters.length > 0; } function isInGenericContext(node) { for (; node; node = node.parent) { if (hasTypeParameters(node)) { return true; } } return false; } function recordTypeParameterUsages(type) { // PERF: This is potentially very expensive. `type` could be a library type with // a lot of properties, each of which the walker will visit. Unfortunately, the // solution isn't as trivial as filtering to user types because of (e.g.) Array. var symbolWalker = checker.getSymbolWalker(function () { return (cancellationToken.throwIfCancellationRequested(), true); }); var visitedTypes = symbolWalker.walkType(type).visitedTypes; for (var _i = 0, visitedTypes_1 = visitedTypes; _i < visitedTypes_1.length; _i++) { var visitedType = visitedTypes_1[_i]; if (visitedType.flags & 32768 /* TypeParameter */) { allTypeParameterUsages.set(visitedType.id.toString(), visitedType); } } } function collectUsages(node, valueUsage) { if (valueUsage === void 0) { valueUsage = 1 /* Read */; } if (inGenericContext) { var type = checker.getTypeAtLocation(node); recordTypeParameterUsages(type); } if (ts.isDeclaration(node) && node.symbol) { visibleDeclarationsInExtractedRange.push(node); } if (ts.isAssignmentExpression(node)) { // use 'write' as default usage for values collectUsages(node.left, 2 /* Write */); collectUsages(node.right); } else if (ts.isUnaryExpressionWithWrite(node)) { collectUsages(node.operand, 2 /* Write */); } else if (ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)) { // use 'write' as default usage for values ts.forEachChild(node, collectUsages); } else if (ts.isIdentifier(node)) { if (!node.parent) { return; } if (ts.isQualifiedName(node.parent) && node !== node.parent.left) { return; } if (ts.isPropertyAccessExpression(node.parent) && node !== node.parent.expression) { return; } recordUsage(node, valueUsage, /*isTypeNode*/ ts.isPartOfTypeNode(node)); } else { ts.forEachChild(node, collectUsages); } } function recordUsage(n, usage, isTypeNode) { var symbolId = recordUsagebySymbol(n, usage, isTypeNode); if (symbolId) { for (var i = 0; i < scopes.length; i++) { // push substitution from map to map to simplify rewriting var substitution = substitutionsPerScope[i].get(symbolId); if (substitution) { usagesPerScope[i].substitutions.set(ts.getNodeId(n).toString(), substitution); } } } } function recordUsagebySymbol(identifier, usage, isTypeName) { var symbol = getSymbolReferencedByIdentifier(identifier); if (!symbol) { // cannot find symbol - do nothing return undefined; } var symbolId = ts.getSymbolId(symbol).toString(); var lastUsage = seenUsages.get(symbolId); // there are two kinds of value usages // - reads - if range contains a read from the value located outside of the range then value should be passed as a parameter // - writes - if range contains a write to a value located outside the range the value should be passed as a parameter and // returned as a return value // 'write' case is a superset of 'read' so if we already have processed 'write' of some symbol there is not need to handle 'read' // since all information is already recorded if (lastUsage && lastUsage >= usage) { return symbolId; } seenUsages.set(symbolId, usage); if (lastUsage) { // if we get here this means that we are trying to handle 'write' and 'read' was already processed // walk scopes and update existing records. for (var _i = 0, usagesPerScope_1 = usagesPerScope; _i < usagesPerScope_1.length; _i++) { var perScope = usagesPerScope_1[_i]; var prevEntry = perScope.usages.get(identifier.text); if (prevEntry) { perScope.usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } } return symbolId; } // find first declaration in this file var declInFile = ts.find(symbol.getDeclarations(), function (d) { return d.getSourceFile() === sourceFile; }); if (!declInFile) { return undefined; } if (ts.rangeContainsStartEnd(enclosingTextRange, declInFile.getStart(), declInFile.end)) { // declaration is located in range to be extracted - do nothing return undefined; } if (targetRange.facts & RangeFacts.IsGenerator && usage === 2 /* Write */) { // this is write to a reference located outside of the target scope and range is extracted into generator // currently this is unsupported scenario var diag = ts.createDiagnosticForNode(identifier, Messages.cannotExtractRangeThatContainsWritesToReferencesLocatedOutsideOfTheTargetRangeInGenerators); for (var _a = 0, functionErrorsPerScope_1 = functionErrorsPerScope; _a < functionErrorsPerScope_1.length; _a++) { var errors = functionErrorsPerScope_1[_a]; errors.push(diag); } for (var _b = 0, constantErrorsPerScope_1 = constantErrorsPerScope; _b < constantErrorsPerScope_1.length; _b++) { var errors = constantErrorsPerScope_1[_b]; errors.push(diag); } } for (var i = 0; i < scopes.length; i++) { var scope = scopes[i]; var resolvedSymbol = checker.resolveName(symbol.name, scope, symbol.flags); if (resolvedSymbol === symbol) { continue; } if (!substitutionsPerScope[i].has(symbolId)) { var substitution = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.exportSymbol || symbol, scope, isTypeName); if (substitution) { substitutionsPerScope[i].set(symbolId, substitution); } else if (isTypeName) { // If the symbol is a type parameter that won't be in scope, we'll pass it as a type argument // so there's no problem. if (!(symbol.flags & 262144 /* TypeParameter */)) { var diag = ts.createDiagnosticForNode(identifier, Messages.typeWillNotBeVisibleInTheNewScope); functionErrorsPerScope[i].push(diag); constantErrorsPerScope[i].push(diag); } } else { usagesPerScope[i].usages.set(identifier.text, { usage: usage, symbol: symbol, node: identifier }); } } } return symbolId; } function checkForUsedDeclarations(node) { // If this node is entirely within the original extraction range, we don't need to do anything. if (node === targetRange.range || (isReadonlyArray(targetRange.range) && targetRange.range.indexOf(node) >= 0)) { return; } // Otherwise check and recurse. var sym = ts.isIdentifier(node) ? getSymbolReferencedByIdentifier(node) : checker.getSymbolAtLocation(node); if (sym) { var decl = ts.find(visibleDeclarationsInExtractedRange, function (d) { return d.symbol === sym; }); if (decl) { if (ts.isVariableDeclaration(decl)) { var idString = decl.symbol.id.toString(); if (!exposedVariableSymbolSet.has(idString)) { exposedVariableDeclarations.push(decl); exposedVariableSymbolSet.set(idString, true); } } else { // CONSIDER: this includes binding elements, which we could // expose in the same way as variables. firstExposedNonVariableDeclaration = firstExposedNonVariableDeclaration || decl; } } } ts.forEachChild(node, checkForUsedDeclarations); } /** * Return the symbol referenced by an identifier (even if it declares a different symbol). */ function getSymbolReferencedByIdentifier(identifier) { // If the identifier is both a property name and its value, we're only interested in its value // (since the name is a declaration and will be included in the extracted range). return identifier.parent && ts.isShorthandPropertyAssignment(identifier.parent) && identifier.parent.name === identifier ? checker.getShorthandAssignmentValueSymbol(identifier.parent) : checker.getSymbolAtLocation(identifier); } function tryReplaceWithQualifiedNameOrPropertyAccess(symbol, scopeDecl, isTypeNode) { if (!symbol) { return undefined; } if (symbol.getDeclarations().some(function (d) { return d.parent === scopeDecl; })) { return ts.createIdentifier(symbol.name); } var prefix = tryReplaceWithQualifiedNameOrPropertyAccess(symbol.parent, scopeDecl, isTypeNode); if (prefix === undefined) { return undefined; } return isTypeNode ? ts.createQualifiedName(prefix, ts.createIdentifier(symbol.name)) : ts.createPropertyAccess(prefix, symbol.name); } } function getParentNodeInSpan(node, file, span) { if (!node) return undefined; while (node.parent) { if (ts.isSourceFile(node.parent) || !spanContainsNode(span, node.parent, file)) { return node; } node = node.parent; } } function spanContainsNode(span, node, file) { return ts.textSpanContainsPosition(span, node.getStart(file)) && node.getEnd() <= ts.textSpanEnd(span); } /** * Computes whether or not a node represents an expression in a position where it could * be extracted. * The isExpression() in utilities.ts returns some false positives we need to handle, * such as `import x from 'y'` -- the 'y' is a StringLiteral but is *not* an expression * in the sense of something that you could extract on */ function isExtractableExpression(node) { switch (node.parent.kind) { case 268 /* EnumMember */: return false; } switch (node.kind) { case 9 /* StringLiteral */: return node.parent.kind !== 239 /* ImportDeclaration */ && node.parent.kind !== 243 /* ImportSpecifier */; case 199 /* SpreadElement */: case 175 /* ObjectBindingPattern */: case 177 /* BindingElement */: return false; case 71 /* Identifier */: return node.parent.kind !== 177 /* BindingElement */ && node.parent.kind !== 243 /* ImportSpecifier */ && node.parent.kind !== 247 /* ExportSpecifier */; } return true; } function isBlockLike(node) { switch (node.kind) { case 208 /* Block */: case 269 /* SourceFile */: case 235 /* ModuleBlock */: case 261 /* CaseClause */: return true; default: return false; } } })(extractSymbol = refactor.extractSymbol || (refactor.extractSymbol = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var refactor; (function (refactor) { var installTypesForPackage; (function (installTypesForPackage_1) { var actionName = "install"; var installTypesForPackage = { name: "Install missing types package", description: "Install missing types package", getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions, }; refactor.registerRefactor(installTypesForPackage); function getAvailableActions(context) { if (ts.getStrictOptionValue(context.program.getCompilerOptions(), "noImplicitAny")) { // Then it will be available via `fixCannotFindModule`. return undefined; } var action = getAction(context); return action && [ { name: installTypesForPackage.name, description: installTypesForPackage.description, actions: [ { description: action.description, name: actionName, }, ], }, ]; } function getEditsForAction(context, _actionName) { ts.Debug.assertEqual(actionName, _actionName); var action = getAction(context); // Should be defined if we said there was an action available. return { edits: [], renameFilename: undefined, renameLocation: undefined, commands: action.commands, }; } function getAction(context) { var file = context.file, startPosition = context.startPosition; var node = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); if (!ts.isStringLiteral(node) || !isModuleIdentifier(node)) { return undefined; } var resolvedTo = ts.getResolvedModule(file, node.text); // Still offer to install types if it resolved to e.g. a ".js" file. // `tryGetCodeActionForInstallPackageTypes` will verify that we're looking for a valid package name, // so the fix won't trigger for imports of ".js" files that couldn't be better replaced by typings. if (resolvedTo && ts.extensionIsTypeScript(resolvedTo.extension)) { return undefined; } return ts.codefix.tryGetCodeActionForInstallPackageTypes(context.host, file.fileName, node.text); } function isModuleIdentifier(node) { switch (node.parent.kind) { case 239 /* ImportDeclaration */: case 249 /* ExternalModuleReference */: return true; default: return false; } } })(installTypesForPackage = refactor.installTypesForPackage || (refactor.installTypesForPackage = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /* @internal */ var ts; (function (ts) { var refactor; (function (refactor) { var installTypesForPackage; (function (installTypesForPackage) { var actionName = "Convert to default import"; var useDefaultImport = { name: actionName, description: ts.getLocaleSpecificMessage(ts.Diagnostics.Convert_to_default_import), getEditsForAction: getEditsForAction, getAvailableActions: getAvailableActions, }; refactor.registerRefactor(useDefaultImport); function getAvailableActions(context) { var file = context.file, startPosition = context.startPosition, program = context.program; if (!program.getCompilerOptions().allowSyntheticDefaultImports) { return undefined; } var importInfo = getConvertibleImportAtPosition(file, startPosition); if (!importInfo) { return undefined; } var module = ts.getResolvedModule(file, importInfo.moduleSpecifier.text); var resolvedFile = program.getSourceFile(module.resolvedFileName); if (!(resolvedFile.externalModuleIndicator && ts.isExportAssignment(resolvedFile.externalModuleIndicator) && resolvedFile.externalModuleIndicator.isExportEquals)) { return undefined; } return [ { name: useDefaultImport.name, description: useDefaultImport.description, actions: [ { description: useDefaultImport.description, name: actionName, }, ], }, ]; } function getEditsForAction(context, _actionName) { var file = context.file, startPosition = context.startPosition; ts.Debug.assertEqual(actionName, _actionName); var importInfo = getConvertibleImportAtPosition(file, startPosition); if (!importInfo) { return undefined; } var importStatement = importInfo.importStatement, name = importInfo.name, moduleSpecifier = importInfo.moduleSpecifier; var newImportClause = ts.createImportClause(name, /*namedBindings*/ undefined); var newImportStatement = ts.createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, newImportClause, moduleSpecifier); return { edits: ts.textChanges.ChangeTracker.with(context, function (t) { return t.replaceNode(file, importStatement, newImportStatement); }), renameFilename: undefined, renameLocation: undefined, }; } function getConvertibleImportAtPosition(file, startPosition) { var node = ts.getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false); while (true) { switch (node.kind) { case 238 /* ImportEqualsDeclaration */: var eq = node; var moduleReference = eq.moduleReference; return moduleReference.kind === 249 /* ExternalModuleReference */ && ts.isStringLiteral(moduleReference.expression) ? { importStatement: eq, name: eq.name, moduleSpecifier: moduleReference.expression } : undefined; case 239 /* ImportDeclaration */: var d = node; var importClause = d.importClause; return !importClause.name && importClause.namedBindings.kind === 241 /* NamespaceImport */ && ts.isStringLiteral(d.moduleSpecifier) ? { importStatement: d, name: importClause.namedBindings.name, moduleSpecifier: d.moduleSpecifier } : undefined; // For known child node kinds of convertible imports, try again with parent node. case 241 /* NamespaceImport */: case 249 /* ExternalModuleReference */: case 91 /* ImportKeyword */: case 71 /* Identifier */: case 9 /* StringLiteral */: case 39 /* AsteriskToken */: break; default: return undefined; } node = node.parent; } } })(installTypesForPackage = refactor.installTypesForPackage || (refactor.installTypesForPackage = {})); })(refactor = ts.refactor || (ts.refactor = {})); })(ts || (ts = {})); /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// var ts; (function (ts) { /** The version of the language service API */ ts.servicesVersion = "0.7"; function createNode(kind, pos, end, parent) { var node = ts.isNodeKind(kind) ? new NodeObject(kind, pos, end) : kind === 71 /* Identifier */ ? new IdentifierObject(71 /* Identifier */, pos, end) : new TokenObject(kind, pos, end); node.parent = parent; node.flags = parent.flags & 6387712 /* ContextFlags */; return node; } var NodeObject = /** @class */ (function () { function NodeObject(kind, pos, end) { this.pos = pos; this.end = end; this.flags = 0 /* None */; this.transformFlags = undefined; this.parent = undefined; this.kind = kind; } NodeObject.prototype.assertHasRealPosition = function (message) { // tslint:disable-next-line:debug-assert ts.Debug.assert(!ts.positionIsSynthesized(this.pos) && !ts.positionIsSynthesized(this.end), message || "Node must have a real position for this operation"); }; NodeObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); }; NodeObject.prototype.getStart = function (sourceFile, includeJsDocComment) { this.assertHasRealPosition(); return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); }; NodeObject.prototype.getFullStart = function () { this.assertHasRealPosition(); return this.pos; }; NodeObject.prototype.getEnd = function () { this.assertHasRealPosition(); return this.end; }; NodeObject.prototype.getWidth = function (sourceFile) { this.assertHasRealPosition(); return this.getEnd() - this.getStart(sourceFile); }; NodeObject.prototype.getFullWidth = function () { this.assertHasRealPosition(); return this.end - this.pos; }; NodeObject.prototype.getLeadingTriviaWidth = function (sourceFile) { this.assertHasRealPosition(); return this.getStart(sourceFile) - this.pos; }; NodeObject.prototype.getFullText = function (sourceFile) { this.assertHasRealPosition(); return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); }; NodeObject.prototype.getText = function (sourceFile) { this.assertHasRealPosition(); if (!sourceFile) { sourceFile = this.getSourceFile(); } return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); }; NodeObject.prototype.addSyntheticNodes = function (nodes, pos, end) { ts.scanner.setTextPos(pos); while (pos < end) { var token = ts.scanner.scan(); var textPos = ts.scanner.getTextPos(); if (textPos <= end) { nodes.push(createNode(token, pos, textPos, this)); } pos = textPos; if (token === 1 /* EndOfFileToken */) { break; } } return pos; }; NodeObject.prototype.createSyntaxList = function (nodes) { var list = createNode(290 /* SyntaxList */, nodes.pos, nodes.end, this); list._children = []; var pos = nodes.pos; for (var _i = 0, nodes_9 = nodes; _i < nodes_9.length; _i++) { var node = nodes_9[_i]; if (pos < node.pos) { pos = this.addSyntheticNodes(list._children, pos, node.pos); } list._children.push(node); pos = node.end; } if (pos < nodes.end) { this.addSyntheticNodes(list._children, pos, nodes.end); } return list; }; NodeObject.prototype.createChildren = function (sourceFile) { var _this = this; if (!ts.isNodeKind(this.kind)) { this._children = ts.emptyArray; return; } if (ts.isJSDocCommentContainingNode(this)) { /** Don't add trivia for "tokens" since this is in a comment. */ var children_4 = []; this.forEachChild(function (child) { children_4.push(child); }); this._children = children_4; return; } var children = []; ts.scanner.setText((sourceFile || this.getSourceFile()).text); var pos = this.pos; var processNode = function (node) { pos = _this.addSyntheticNodes(children, pos, node.pos); children.push(node); pos = node.end; }; var processNodes = function (nodes) { if (pos < nodes.pos) { pos = _this.addSyntheticNodes(children, pos, nodes.pos); } children.push(_this.createSyntaxList(nodes)); pos = nodes.end; }; // jsDocComments need to be the first children if (this.jsDoc) { for (var _i = 0, _a = this.jsDoc; _i < _a.length; _i++) { var jsDocComment = _a[_i]; processNode(jsDocComment); } } // For syntactic classifications, all trivia are classcified together, including jsdoc comments. // For that to work, the jsdoc comments should still be the leading trivia of the first child. // Restoring the scanner position ensures that. pos = this.pos; ts.forEachChild(this, processNode, processNodes); if (pos < this.end) { this.addSyntheticNodes(children, pos, this.end); } ts.scanner.setText(undefined); this._children = children; }; NodeObject.prototype.getChildCount = function (sourceFile) { this.assertHasRealPosition(); if (!this._children) this.createChildren(sourceFile); return this._children.length; }; NodeObject.prototype.getChildAt = function (index, sourceFile) { this.assertHasRealPosition(); if (!this._children) this.createChildren(sourceFile); return this._children[index]; }; NodeObject.prototype.getChildren = function (sourceFile) { this.assertHasRealPosition("Node without a real position cannot be scanned and thus has no token nodes - use forEachChild and collect the result if that's fine"); if (!this._children) this.createChildren(sourceFile); return this._children; }; NodeObject.prototype.getFirstToken = function (sourceFile) { this.assertHasRealPosition(); var children = this.getChildren(sourceFile); if (!children.length) { return undefined; } var child = ts.find(children, function (kid) { return kid.kind < 271 /* FirstJSDocNode */ || kid.kind > 289 /* LastJSDocNode */; }); return child.kind < 144 /* FirstNode */ ? child : child.getFirstToken(sourceFile); }; NodeObject.prototype.getLastToken = function (sourceFile) { this.assertHasRealPosition(); var children = this.getChildren(sourceFile); var child = ts.lastOrUndefined(children); if (!child) { return undefined; } return child.kind < 144 /* FirstNode */ ? child : child.getLastToken(sourceFile); }; NodeObject.prototype.forEachChild = function (cbNode, cbNodeArray) { return ts.forEachChild(this, cbNode, cbNodeArray); }; return NodeObject; }()); var TokenOrIdentifierObject = /** @class */ (function () { function TokenOrIdentifierObject(pos, end) { // Set properties in same order as NodeObject this.pos = pos; this.end = end; this.flags = 0 /* None */; this.parent = undefined; } TokenOrIdentifierObject.prototype.getSourceFile = function () { return ts.getSourceFileOfNode(this); }; TokenOrIdentifierObject.prototype.getStart = function (sourceFile, includeJsDocComment) { return ts.getTokenPosOfNode(this, sourceFile, includeJsDocComment); }; TokenOrIdentifierObject.prototype.getFullStart = function () { return this.pos; }; TokenOrIdentifierObject.prototype.getEnd = function () { return this.end; }; TokenOrIdentifierObject.prototype.getWidth = function (sourceFile) { return this.getEnd() - this.getStart(sourceFile); }; TokenOrIdentifierObject.prototype.getFullWidth = function () { return this.end - this.pos; }; TokenOrIdentifierObject.prototype.getLeadingTriviaWidth = function (sourceFile) { return this.getStart(sourceFile) - this.pos; }; TokenOrIdentifierObject.prototype.getFullText = function (sourceFile) { return (sourceFile || this.getSourceFile()).text.substring(this.pos, this.end); }; TokenOrIdentifierObject.prototype.getText = function (sourceFile) { if (!sourceFile) { sourceFile = this.getSourceFile(); } return sourceFile.text.substring(this.getStart(sourceFile), this.getEnd()); }; TokenOrIdentifierObject.prototype.getChildCount = function () { return 0; }; TokenOrIdentifierObject.prototype.getChildAt = function () { return undefined; }; TokenOrIdentifierObject.prototype.getChildren = function () { return ts.emptyArray; }; TokenOrIdentifierObject.prototype.getFirstToken = function () { return undefined; }; TokenOrIdentifierObject.prototype.getLastToken = function () { return undefined; }; TokenOrIdentifierObject.prototype.forEachChild = function () { return undefined; }; return TokenOrIdentifierObject; }()); var SymbolObject = /** @class */ (function () { function SymbolObject(flags, name) { this.flags = flags; this.escapedName = name; } SymbolObject.prototype.getFlags = function () { return this.flags; }; Object.defineProperty(SymbolObject.prototype, "name", { get: function () { return ts.symbolName(this); }, enumerable: true, configurable: true }); SymbolObject.prototype.getEscapedName = function () { return this.escapedName; }; SymbolObject.prototype.getName = function () { return this.name; }; SymbolObject.prototype.getDeclarations = function () { return this.declarations; }; SymbolObject.prototype.getDocumentationComment = function (checker) { if (this.documentationComment === undefined) { if (this.declarations) { this.documentationComment = ts.JsDoc.getJsDocCommentsFromDeclarations(this.declarations); if (this.documentationComment.length === 0 || this.declarations.some(hasJSDocInheritDocTag)) { if (checker) { for (var _i = 0, _a = this.declarations; _i < _a.length; _i++) { var declaration = _a[_i]; var inheritedDocs = findInheritedJSDocComments(declaration, this.getName(), checker); if (inheritedDocs.length > 0) { if (this.documentationComment.length > 0) { inheritedDocs.push(ts.lineBreakPart()); } this.documentationComment = ts.concatenate(inheritedDocs, this.documentationComment); break; } } } } } else { this.documentationComment = []; } } return this.documentationComment; }; SymbolObject.prototype.getJsDocTags = function () { if (this.tags === undefined) { this.tags = ts.JsDoc.getJsDocTagsFromDeclarations(this.declarations); } return this.tags; }; return SymbolObject; }()); var TokenObject = /** @class */ (function (_super) { __extends(TokenObject, _super); function TokenObject(kind, pos, end) { var _this = _super.call(this, pos, end) || this; _this.kind = kind; return _this; } return TokenObject; }(TokenOrIdentifierObject)); var IdentifierObject = /** @class */ (function (_super) { __extends(IdentifierObject, _super); function IdentifierObject(_kind, pos, end) { return _super.call(this, pos, end) || this; } Object.defineProperty(IdentifierObject.prototype, "text", { get: function () { return ts.idText(this); }, enumerable: true, configurable: true }); return IdentifierObject; }(TokenOrIdentifierObject)); IdentifierObject.prototype.kind = 71 /* Identifier */; var TypeObject = /** @class */ (function () { function TypeObject(checker, flags) { this.checker = checker; this.flags = flags; } TypeObject.prototype.getFlags = function () { return this.flags; }; TypeObject.prototype.getSymbol = function () { return this.symbol; }; TypeObject.prototype.getProperties = function () { return this.checker.getPropertiesOfType(this); }; TypeObject.prototype.getProperty = function (propertyName) { return this.checker.getPropertyOfType(this, propertyName); }; TypeObject.prototype.getApparentProperties = function () { return this.checker.getAugmentedPropertiesOfType(this); }; TypeObject.prototype.getCallSignatures = function () { return this.checker.getSignaturesOfType(this, 0 /* Call */); }; TypeObject.prototype.getConstructSignatures = function () { return this.checker.getSignaturesOfType(this, 1 /* Construct */); }; TypeObject.prototype.getStringIndexType = function () { return this.checker.getIndexTypeOfType(this, 0 /* String */); }; TypeObject.prototype.getNumberIndexType = function () { return this.checker.getIndexTypeOfType(this, 1 /* Number */); }; TypeObject.prototype.getBaseTypes = function () { return this.flags & 65536 /* Object */ && this.objectFlags & (1 /* Class */ | 2 /* Interface */) ? this.checker.getBaseTypes(this) : undefined; }; TypeObject.prototype.getNonNullableType = function () { return this.checker.getNonNullableType(this); }; TypeObject.prototype.getConstraint = function () { return this.checker.getBaseConstraintOfType(this); }; TypeObject.prototype.getDefault = function () { return this.checker.getDefaultFromTypeParameter(this); }; return TypeObject; }()); var SignatureObject = /** @class */ (function () { function SignatureObject(checker) { this.checker = checker; } SignatureObject.prototype.getDeclaration = function () { return this.declaration; }; SignatureObject.prototype.getTypeParameters = function () { return this.typeParameters; }; SignatureObject.prototype.getParameters = function () { return this.parameters; }; SignatureObject.prototype.getReturnType = function () { return this.checker.getReturnTypeOfSignature(this); }; SignatureObject.prototype.getDocumentationComment = function () { if (this.documentationComment === undefined) { if (this.declaration) { this.documentationComment = ts.JsDoc.getJsDocCommentsFromDeclarations([this.declaration]); if (this.documentationComment.length === 0 || hasJSDocInheritDocTag(this.declaration)) { var inheritedDocs = findInheritedJSDocComments(this.declaration, this.declaration.symbol.getName(), this.checker); if (this.documentationComment.length > 0) { inheritedDocs.push(ts.lineBreakPart()); } this.documentationComment = ts.concatenate(inheritedDocs, this.documentationComment); } } else { this.documentationComment = []; } } return this.documentationComment; }; SignatureObject.prototype.getJsDocTags = function () { if (this.jsDocTags === undefined) { this.jsDocTags = this.declaration ? ts.JsDoc.getJsDocTagsFromDeclarations([this.declaration]) : []; } return this.jsDocTags; }; return SignatureObject; }()); /** * Returns whether or not the given node has a JSDoc "inheritDoc" tag on it. * @param node the Node in question. * @returns `true` if `node` has a JSDoc "inheritDoc" tag on it, otherwise `false`. */ function hasJSDocInheritDocTag(node) { return ts.getJSDocTags(node).some(function (tag) { return tag.tagName.text === "inheritDoc"; }); } /** * Attempts to find JSDoc comments for possibly-inherited properties. Checks superclasses then traverses * implemented interfaces until a symbol is found with the same name and with documentation. * @param declaration The possibly-inherited declaration to find comments for. * @param propertyName The name of the possibly-inherited property. * @param typeChecker A TypeChecker, used to find inherited properties. * @returns A filled array of documentation comments if any were found, otherwise an empty array. */ function findInheritedJSDocComments(declaration, propertyName, typeChecker) { var foundDocs = false; return ts.flatMap(getAllSuperTypeNodes(declaration), function (superTypeNode) { if (foundDocs) { return ts.emptyArray; } var superType = typeChecker.getTypeAtLocation(superTypeNode); if (!superType) { return ts.emptyArray; } var baseProperty = typeChecker.getPropertyOfType(superType, propertyName); if (!baseProperty) { return ts.emptyArray; } var inheritedDocs = baseProperty.getDocumentationComment(typeChecker); foundDocs = inheritedDocs.length > 0; return inheritedDocs; }); } /** * Finds and returns the `TypeNode` for all super classes and implemented interfaces given a declaration. * @param declaration The possibly-inherited declaration. * @returns A filled array of `TypeNode`s containing all super classes and implemented interfaces if any exist, otherwise an empty array. */ function getAllSuperTypeNodes(declaration) { var container = declaration.parent; if (!container || (!ts.isClassDeclaration(container) && !ts.isInterfaceDeclaration(container))) { return ts.emptyArray; } var extended = ts.getClassExtendsHeritageClauseElement(container); var types = extended ? [extended] : ts.emptyArray; return ts.isClassLike(container) ? ts.concatenate(types, ts.getClassImplementsHeritageClauseElements(container)) : types; } var SourceFileObject = /** @class */ (function (_super) { __extends(SourceFileObject, _super); function SourceFileObject(kind, pos, end) { return _super.call(this, kind, pos, end) || this; } SourceFileObject.prototype.update = function (newText, textChangeRange) { return ts.updateSourceFile(this, newText, textChangeRange); }; SourceFileObject.prototype.getLineAndCharacterOfPosition = function (position) { return ts.getLineAndCharacterOfPosition(this, position); }; SourceFileObject.prototype.getLineStarts = function () { return ts.getLineStarts(this); }; SourceFileObject.prototype.getPositionOfLineAndCharacter = function (line, character) { return ts.getPositionOfLineAndCharacter(this, line, character); }; SourceFileObject.prototype.getLineEndOfPosition = function (pos) { var line = this.getLineAndCharacterOfPosition(pos).line; var lineStarts = this.getLineStarts(); var lastCharPos; if (line + 1 >= lineStarts.length) { lastCharPos = this.getEnd(); } if (!lastCharPos) { lastCharPos = lineStarts[line + 1] - 1; } var fullText = this.getFullText(); // if the new line is "\r\n", we should return the last non-new-line-character position return fullText[lastCharPos] === "\n" && fullText[lastCharPos - 1] === "\r" ? lastCharPos - 1 : lastCharPos; }; SourceFileObject.prototype.getNamedDeclarations = function () { if (!this.namedDeclarations) { this.namedDeclarations = this.computeNamedDeclarations(); } return this.namedDeclarations; }; SourceFileObject.prototype.computeNamedDeclarations = function () { var result = ts.createMultiMap(); ts.forEachChild(this, visit); return result; function addDeclaration(declaration) { var name = getDeclarationName(declaration); if (name) { result.add(name, declaration); } } function getDeclarations(name) { var declarations = result.get(name); if (!declarations) { result.set(name, declarations = []); } return declarations; } function getDeclarationName(declaration) { var name = ts.getNameOfDeclaration(declaration); if (name) { var result_8 = ts.getTextOfIdentifierOrLiteral(name); if (result_8 !== undefined) { return result_8; } if (name.kind === 145 /* ComputedPropertyName */) { var expr = name.expression; if (expr.kind === 180 /* PropertyAccessExpression */) { return expr.name.text; } return ts.getTextOfIdentifierOrLiteral(expr); } } return undefined; } function visit(node) { switch (node.kind) { case 229 /* FunctionDeclaration */: case 187 /* FunctionExpression */: case 152 /* MethodDeclaration */: case 151 /* 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 230 /* ClassDeclaration */: case 200 /* ClassExpression */: case 231 /* InterfaceDeclaration */: case 232 /* TypeAliasDeclaration */: case 233 /* EnumDeclaration */: case 234 /* ModuleDeclaration */: case 238 /* ImportEqualsDeclaration */: case 247 /* ExportSpecifier */: case 243 /* ImportSpecifier */: case 240 /* ImportClause */: case 241 /* NamespaceImport */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: case 164 /* TypeLiteral */: addDeclaration(node); ts.forEachChild(node, visit); break; case 147 /* Parameter */: // Only consider parameter properties if (!ts.hasModifier(node, 92 /* ParameterPropertyModifier */)) { break; } // falls through case 227 /* VariableDeclaration */: case 177 /* BindingElement */: { var decl = node; if (ts.isBindingPattern(decl.name)) { ts.forEachChild(decl.name, visit); break; } if (decl.initializer) { visit(decl.initializer); } } // falls through case 268 /* EnumMember */: case 150 /* PropertyDeclaration */: case 149 /* PropertySignature */: addDeclaration(node); break; case 245 /* 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 239 /* 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 === 241 /* NamespaceImport */) { addDeclaration(importClause.namedBindings); } else { ts.forEach(importClause.namedBindings.elements, visit); } } } break; case 195 /* BinaryExpression */: if (ts.getSpecialPropertyAssignmentKind(node) !== 0 /* None */) { addDeclaration(node); } // falls through default: ts.forEachChild(node, visit); } } }; return SourceFileObject; }(NodeObject)); var SourceMapSourceObject = /** @class */ (function () { function SourceMapSourceObject(fileName, text, skipTrivia) { this.fileName = fileName; this.text = text; this.skipTrivia = skipTrivia; } SourceMapSourceObject.prototype.getLineAndCharacterOfPosition = function (pos) { return ts.getLineAndCharacterOfPosition(this, pos); }; return SourceMapSourceObject; }()); function getServicesObjectAllocator() { return { getNodeConstructor: function () { return NodeObject; }, getTokenConstructor: function () { return TokenObject; }, getIdentifierConstructor: function () { return IdentifierObject; }, getSourceFileConstructor: function () { return SourceFileObject; }, getSymbolConstructor: function () { return SymbolObject; }, getTypeConstructor: function () { return TypeObject; }, getSignatureConstructor: function () { return SignatureObject; }, getSourceMapSourceConstructor: function () { return SourceMapSourceObject; }, }; } function toEditorSettings(optionsAsMap) { var allPropertiesAreCamelCased = true; for (var key in optionsAsMap) { if (ts.hasProperty(optionsAsMap, key) && !isCamelCase(key)) { allPropertiesAreCamelCased = false; break; } } if (allPropertiesAreCamelCased) { return optionsAsMap; } var settings = {}; for (var key in optionsAsMap) { if (ts.hasProperty(optionsAsMap, key)) { var newKey = isCamelCase(key) ? key : key.charAt(0).toLowerCase() + key.substr(1); settings[newKey] = optionsAsMap[key]; } } return settings; } ts.toEditorSettings = toEditorSettings; function isCamelCase(s) { return !s.length || s.charAt(0) === s.charAt(0).toLowerCase(); } function displayPartsToString(displayParts) { if (displayParts) { return ts.map(displayParts, function (displayPart) { return displayPart.text; }).join(""); } return ""; } ts.displayPartsToString = displayPartsToString; function getDefaultCompilerOptions() { // Always default to "ScriptTarget.ES5" for the language service return { target: 1 /* ES5 */, jsx: 1 /* Preserve */ }; } ts.getDefaultCompilerOptions = getDefaultCompilerOptions; function getSupportedCodeFixes() { return ts.codefix.getSupportedErrorCodes(); } ts.getSupportedCodeFixes = getSupportedCodeFixes; // Cache host information about script Should be refreshed // at each language service public entry point, since we don't know when // the set of scripts handled by the host changes. var HostCache = /** @class */ (function () { function HostCache(host, getCanonicalFileName) { this.host = host; // script id => script index this.currentDirectory = host.getCurrentDirectory(); this.fileNameToEntry = ts.createMap(); // Initialize the list with the root file names var rootFileNames = host.getScriptFileNames(); for (var _i = 0, rootFileNames_1 = rootFileNames; _i < rootFileNames_1.length; _i++) { var fileName = rootFileNames_1[_i]; this.createEntry(fileName, ts.toPath(fileName, this.currentDirectory, getCanonicalFileName)); } // store the compilation settings this._compilationSettings = host.getCompilationSettings() || getDefaultCompilerOptions(); } HostCache.prototype.compilationSettings = function () { return this._compilationSettings; }; HostCache.prototype.createEntry = function (fileName, path) { var entry; var scriptSnapshot = this.host.getScriptSnapshot(fileName); if (scriptSnapshot) { entry = { hostFileName: fileName, version: this.host.getScriptVersion(fileName), scriptSnapshot: scriptSnapshot, scriptKind: ts.getScriptKind(fileName, this.host) }; } else { entry = fileName; } this.fileNameToEntry.set(path, entry); return entry; }; HostCache.prototype.getEntryByPath = function (path) { return this.fileNameToEntry.get(path); }; HostCache.prototype.getHostFileInformation = function (path) { var entry = this.fileNameToEntry.get(path); return !ts.isString(entry) ? entry : undefined; }; HostCache.prototype.getOrCreateEntryByPath = function (fileName, path) { var info = this.getEntryByPath(path) || this.createEntry(fileName, path); return ts.isString(info) ? undefined : info; }; HostCache.prototype.getRootFileNames = function () { return ts.arrayFrom(this.fileNameToEntry.values(), function (entry) { return ts.isString(entry) ? entry : entry.hostFileName; }); }; HostCache.prototype.getVersion = function (path) { var file = this.getHostFileInformation(path); return file && file.version; }; HostCache.prototype.getScriptSnapshot = function (path) { var file = this.getHostFileInformation(path); return file && file.scriptSnapshot; }; return HostCache; }()); var SyntaxTreeCache = /** @class */ (function () { function SyntaxTreeCache(host) { this.host = host; } SyntaxTreeCache.prototype.getCurrentSourceFile = function (fileName) { var scriptSnapshot = this.host.getScriptSnapshot(fileName); if (!scriptSnapshot) { // The host does not know about this file. throw new Error("Could not find file: '" + fileName + "'."); } var scriptKind = ts.getScriptKind(fileName, this.host); var version = this.host.getScriptVersion(fileName); var sourceFile; if (this.currentFileName !== fileName) { // This is a new file, just parse it sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, 6 /* Latest */, version, /*setNodeParents*/ true, scriptKind); } else if (this.currentFileVersion !== version) { // This is the same file, just a newer version. Incrementally parse the file. var editRange = scriptSnapshot.getChangeRange(this.currentFileScriptSnapshot); sourceFile = updateLanguageServiceSourceFile(this.currentSourceFile, scriptSnapshot, version, editRange); } if (sourceFile) { // All done, ensure state is up to date this.currentFileVersion = version; this.currentFileName = fileName; this.currentFileScriptSnapshot = scriptSnapshot; this.currentSourceFile = sourceFile; } return this.currentSourceFile; }; return SyntaxTreeCache; }()); function setSourceFileFields(sourceFile, scriptSnapshot, version) { sourceFile.version = version; sourceFile.scriptSnapshot = scriptSnapshot; } function createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, setNodeParents, scriptKind) { var text = scriptSnapshot.getText(0, scriptSnapshot.getLength()); var sourceFile = ts.createSourceFile(fileName, text, scriptTarget, setNodeParents, scriptKind); setSourceFileFields(sourceFile, scriptSnapshot, version); return sourceFile; } ts.createLanguageServiceSourceFile = createLanguageServiceSourceFile; ts.disableIncrementalParsing = false; function updateLanguageServiceSourceFile(sourceFile, scriptSnapshot, version, textChangeRange, aggressiveChecks) { // If we were given a text change range, and our version or open-ness changed, then // incrementally parse this file. if (textChangeRange) { if (version !== sourceFile.version) { // Once incremental parsing is ready, then just call into this function. if (!ts.disableIncrementalParsing) { var newText = void 0; // grab the fragment from the beginning of the original text to the beginning of the span var prefix = textChangeRange.span.start !== 0 ? sourceFile.text.substr(0, textChangeRange.span.start) : ""; // grab the fragment from the end of the span till the end of the original text var suffix = ts.textSpanEnd(textChangeRange.span) !== sourceFile.text.length ? sourceFile.text.substr(ts.textSpanEnd(textChangeRange.span)) : ""; if (textChangeRange.newLength === 0) { // edit was a deletion - just combine prefix and suffix newText = prefix && suffix ? prefix + suffix : prefix || suffix; } else { // it was actual edit, fetch the fragment of new text that correspond to new span var changedText = scriptSnapshot.getText(textChangeRange.span.start, textChangeRange.span.start + textChangeRange.newLength); // combine prefix, changed text and suffix newText = prefix && suffix ? prefix + changedText + suffix : prefix ? (prefix + changedText) : (changedText + suffix); } var newSourceFile = ts.updateSourceFile(sourceFile, newText, textChangeRange, aggressiveChecks); setSourceFileFields(newSourceFile, scriptSnapshot, version); // after incremental parsing nameTable might not be up-to-date // drop it so it can be lazily recreated later newSourceFile.nameTable = undefined; // dispose all resources held by old script snapshot if (sourceFile !== newSourceFile && sourceFile.scriptSnapshot) { if (sourceFile.scriptSnapshot.dispose) { sourceFile.scriptSnapshot.dispose(); } sourceFile.scriptSnapshot = undefined; } return newSourceFile; } } } // Otherwise, just create a new source file. return createLanguageServiceSourceFile(sourceFile.fileName, scriptSnapshot, sourceFile.languageVersion, version, /*setNodeParents*/ true, sourceFile.scriptKind); } ts.updateLanguageServiceSourceFile = updateLanguageServiceSourceFile; var CancellationTokenObject = /** @class */ (function () { function CancellationTokenObject(cancellationToken) { this.cancellationToken = cancellationToken; } CancellationTokenObject.prototype.isCancellationRequested = function () { return this.cancellationToken && this.cancellationToken.isCancellationRequested(); }; CancellationTokenObject.prototype.throwIfCancellationRequested = function () { if (this.isCancellationRequested()) { throw new ts.OperationCanceledException(); } }; return CancellationTokenObject; }()); /* @internal */ /** A cancellation that throttles calls to the host */ var ThrottledCancellationToken = /** @class */ (function () { function ThrottledCancellationToken(hostCancellationToken, throttleWaitMilliseconds) { if (throttleWaitMilliseconds === void 0) { throttleWaitMilliseconds = 20; } this.hostCancellationToken = hostCancellationToken; this.throttleWaitMilliseconds = throttleWaitMilliseconds; // Store when we last tried to cancel. Checking cancellation can be expensive (as we have // to marshall over to the host layer). So we only bother actually checking once enough // time has passed. this.lastCancellationCheckTime = 0; } ThrottledCancellationToken.prototype.isCancellationRequested = function () { var time = ts.timestamp(); var duration = Math.abs(time - this.lastCancellationCheckTime); if (duration >= this.throttleWaitMilliseconds) { // Check no more than once every throttle wait milliseconds this.lastCancellationCheckTime = time; return this.hostCancellationToken.isCancellationRequested(); } return false; }; ThrottledCancellationToken.prototype.throwIfCancellationRequested = function () { if (this.isCancellationRequested()) { throw new ts.OperationCanceledException(); } }; return ThrottledCancellationToken; }()); ts.ThrottledCancellationToken = ThrottledCancellationToken; function createLanguageService(host, documentRegistry) { if (documentRegistry === void 0) { documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); } var syntaxTreeCache = new SyntaxTreeCache(host); var program; var lastProjectVersion; var lastTypesRootVersion = 0; var useCaseSensitivefileNames = host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(); var cancellationToken = new CancellationTokenObject(host.getCancellationToken && host.getCancellationToken()); var currentDirectory = host.getCurrentDirectory(); // Check if the localized messages json is set, otherwise query the host for it if (!ts.localizedDiagnosticMessages && host.getLocalizedDiagnosticMessages) { ts.localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); } function log(message) { if (host.log) { host.log(message); } } var getCanonicalFileName = ts.createGetCanonicalFileName(useCaseSensitivefileNames); function getValidSourceFile(fileName) { var sourceFile = program.getSourceFile(fileName); if (!sourceFile) { throw new Error("Could not find file: '" + fileName + "'."); } return sourceFile; } function synchronizeHostData() { // perform fast check if host supports it if (host.getProjectVersion) { var hostProjectVersion = host.getProjectVersion(); if (hostProjectVersion) { if (lastProjectVersion === hostProjectVersion && !host.hasChangedAutomaticTypeDirectiveNames) { return; } lastProjectVersion = hostProjectVersion; } } var typeRootsVersion = host.getTypeRootsVersion ? host.getTypeRootsVersion() : 0; if (lastTypesRootVersion !== typeRootsVersion) { log("TypeRoots version has changed; provide new program"); program = undefined; lastTypesRootVersion = typeRootsVersion; } // Get a fresh cache of the host information var hostCache = new HostCache(host, getCanonicalFileName); var rootFileNames = hostCache.getRootFileNames(); var hasInvalidatedResolution = host.hasInvalidatedResolution || ts.returnFalse; // If the program is already up-to-date, we can reuse it if (ts.isProgramUptoDate(program, rootFileNames, hostCache.compilationSettings(), function (path) { return hostCache.getVersion(path); }, fileExists, hasInvalidatedResolution, host.hasChangedAutomaticTypeDirectiveNames)) { return; } // IMPORTANT - It is critical from this moment onward that we do not check // cancellation tokens. We are about to mutate source files from a previous program // instance. If we cancel midway through, we may end up in an inconsistent state where // the program points to old source files that have been invalidated because of // incremental parsing. var newSettings = hostCache.compilationSettings(); // Now create a new compiler var compilerHost = { getSourceFile: getOrCreateSourceFile, getSourceFileByPath: getOrCreateSourceFileByPath, getCancellationToken: function () { return cancellationToken; }, getCanonicalFileName: getCanonicalFileName, useCaseSensitiveFileNames: function () { return useCaseSensitivefileNames; }, getNewLine: function () { return ts.getNewLineCharacter(newSettings, { newLine: ts.getNewLineOrDefaultFromHost(host) }); }, getDefaultLibFileName: function (options) { return host.getDefaultLibFileName(options); }, writeFile: ts.noop, getCurrentDirectory: function () { return currentDirectory; }, fileExists: fileExists, readFile: function (fileName) { // stub missing host functionality var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); var entry = hostCache.getEntryByPath(path); if (entry) { return ts.isString(entry) ? undefined : entry.scriptSnapshot.getText(0, entry.scriptSnapshot.getLength()); } return host.readFile && host.readFile(fileName); }, directoryExists: function (directoryName) { return ts.directoryProbablyExists(directoryName, host); }, getDirectories: function (path) { return host.getDirectories ? host.getDirectories(path) : []; }, onReleaseOldSourceFile: onReleaseOldSourceFile, hasInvalidatedResolution: hasInvalidatedResolution, hasChangedAutomaticTypeDirectiveNames: host.hasChangedAutomaticTypeDirectiveNames }; if (host.trace) { compilerHost.trace = function (message) { return host.trace(message); }; } if (host.resolveModuleNames) { compilerHost.resolveModuleNames = function (moduleNames, containingFile, reusedNames) { return host.resolveModuleNames(moduleNames, containingFile, reusedNames); }; } if (host.resolveTypeReferenceDirectives) { compilerHost.resolveTypeReferenceDirectives = function (typeReferenceDirectiveNames, containingFile) { return host.resolveTypeReferenceDirectives(typeReferenceDirectiveNames, containingFile); }; } var documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings); program = ts.createProgram(rootFileNames, newSettings, compilerHost, program); // hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point. // It needs to be cleared to allow all collected snapshots to be released hostCache = undefined; // Make sure all the nodes in the program are both bound, and have their parent // pointers set property. program.getTypeChecker(); return; function fileExists(fileName) { var path = ts.toPath(fileName, currentDirectory, getCanonicalFileName); var entry = hostCache.getEntryByPath(path); return entry ? !ts.isString(entry) : (host.fileExists && host.fileExists(fileName)); } // Release any files we have acquired in the old program but are // not part of the new program. function onReleaseOldSourceFile(oldSourceFile, oldOptions) { var oldSettingsKey = documentRegistry.getKeyForCompilationSettings(oldOptions); documentRegistry.releaseDocumentWithKey(oldSourceFile.path, oldSettingsKey); } function getOrCreateSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) { return getOrCreateSourceFileByPath(fileName, ts.toPath(fileName, currentDirectory, getCanonicalFileName), languageVersion, onError, shouldCreateNewSourceFile); } function getOrCreateSourceFileByPath(fileName, path, _languageVersion, _onError, shouldCreateNewSourceFile) { ts.Debug.assert(hostCache !== undefined); // The program is asking for this file, check first if the host can locate it. // If the host can not locate the file, then it does not exist. return undefined // to the program to allow reporting of errors for missing files. var hostFileInformation = hostCache.getOrCreateEntryByPath(fileName, path); if (!hostFileInformation) { return undefined; } // Check if the language version has changed since we last created a program; if they are the same, // it is safe to reuse the sourceFiles; if not, then the shape of the AST can change, and the oldSourceFile // can not be reused. we have to dump all syntax trees and create new ones. if (!shouldCreateNewSourceFile) { // Check if the old program had this file already var oldSourceFile = program && program.getSourceFileByPath(path); if (oldSourceFile) { // We already had a source file for this file name. Go to the registry to // ensure that we get the right up to date version of it. We need this to // address the following race-condition. Specifically, say we have the following: // // LS1 // \ // DocumentRegistry // / // LS2 // // Each LS has a reference to file 'foo.ts' at version 1. LS2 then updates // it's version of 'foo.ts' to version 2. This will cause LS2 and the // DocumentRegistry to have version 2 of the document. HOwever, LS1 will // have version 1. And *importantly* this source file will be *corrupt*. // The act of creating version 2 of the file irrevocably damages the version // 1 file. // // So, later when we call into LS1, we need to make sure that it doesn't use // it's source file any more, and instead defers to DocumentRegistry to get // either version 1, version 2 (or some other version) depending on what the // host says should be used. // We do not support the scenario where a host can modify a registered // file's script kind, i.e. in one project some file is treated as ".ts" // and in another as ".js" ts.Debug.assertEqual(hostFileInformation.scriptKind, oldSourceFile.scriptKind, "Registered script kind should match new script kind.", path); return documentRegistry.updateDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } // We didn't already have the file. Fall through and acquire it from the registry. } // Could not find this file in the old program, create a new SourceFile for it. return documentRegistry.acquireDocumentWithKey(fileName, path, newSettings, documentRegistryBucketKey, hostFileInformation.scriptSnapshot, hostFileInformation.version, hostFileInformation.scriptKind); } } function getProgram() { synchronizeHostData(); return program; } function cleanupSemanticCache() { program = undefined; } function dispose() { if (program) { ts.forEach(program.getSourceFiles(), function (f) { return documentRegistry.releaseDocument(f.fileName, program.getCompilerOptions()); }); program = undefined; } host = undefined; } /// Diagnostics function getSyntacticDiagnostics(fileName) { synchronizeHostData(); return program.getSyntacticDiagnostics(getValidSourceFile(fileName), cancellationToken).slice(); } /** * getSemanticDiagnostics return array of Diagnostics. If '-d' is not enabled, only report semantic errors * If '-d' enabled, report both semantic and emitter errors */ function getSemanticDiagnostics(fileName) { synchronizeHostData(); var targetSourceFile = getValidSourceFile(fileName); // Only perform the action per file regardless of '-out' flag as LanguageServiceHost is expected to call this function per file. // Therefore only get diagnostics for given file. var semanticDiagnostics = program.getSemanticDiagnostics(targetSourceFile, cancellationToken); if (!program.getCompilerOptions().declaration) { return semanticDiagnostics.slice(); } // If '-d' is enabled, check for emitter error. One example of emitter error is export class implements non-export interface var declarationDiagnostics = program.getDeclarationDiagnostics(targetSourceFile, cancellationToken); return semanticDiagnostics.concat(declarationDiagnostics); } function getCompilerOptionsDiagnostics() { synchronizeHostData(); return program.getOptionsDiagnostics(cancellationToken).concat(program.getGlobalDiagnostics(cancellationToken)); } function getCompletionsAtPosition(fileName, position, options) { if (options === void 0) { options = { includeExternalModuleExports: false }; } synchronizeHostData(); return ts.Completions.getCompletionsAtPosition(host, program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, program.getSourceFiles(), options); } function getCompletionEntryDetails(fileName, position, name, formattingOptions, source) { synchronizeHostData(); return ts.Completions.getCompletionEntryDetails(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles(), host, formattingOptions && ts.formatting.getFormatContext(formattingOptions), getCanonicalFileName); } function getCompletionEntrySymbol(fileName, position, name, source) { synchronizeHostData(); return ts.Completions.getCompletionEntrySymbol(program.getTypeChecker(), log, program.getCompilerOptions(), getValidSourceFile(fileName), position, { name: name, source: source }, program.getSourceFiles()); } function getQuickInfoAtPosition(fileName, position) { synchronizeHostData(); var sourceFile = getValidSourceFile(fileName); var node = ts.getTouchingPropertyName(sourceFile, position, /*includeJsDocComment*/ true); if (node === sourceFile) { return undefined; } if (ts.isLabelName(node)) { return undefined; } var typeChecker = program.getTypeChecker(); var symbol = getSymbolAtLocationForQuickInfo(node, typeChecker); if (!symbol || typeChecker.isUnknownSymbol(symbol)) { // Try getting just type at this position and show switch (node.kind) { case 71 /* Identifier */: case 180 /* PropertyAccessExpression */: case 144 /* QualifiedName */: case 99 /* ThisKeyword */: case 170 /* ThisType */: case 97 /* SuperKeyword */: // For the identifiers/this/super etc get the type at position var type = typeChecker.getTypeAtLocation(node); if (type) { return { kind: "" /* unknown */, kindModifiers: "" /* none */, textSpan: ts.createTextSpan(node.getStart(), node.getWidth()), displayParts: ts.typeToDisplayParts(typeChecker, type, ts.getContainerNode(node)), documentation: type.symbol ? type.symbol.getDocumentationComment(typeChecker) : undefined, tags: type.symbol ? type.symbol.getJsDocTags() : undefined }; } } return undefined; } var displayPartsDocumentationsAndKind = ts.SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(typeChecker, symbol, sourceFile, ts.getContainerNode(node), node); return { kind: displayPartsDocumentationsAndKind.symbolKind, kindModifiers: ts.SymbolDisplay.getSymbolModifiers(symbol), textSpan: ts.createTextSpan(node.getStart(), node.getWidth()), displayParts: displayPartsDocumentationsAndKind.displayParts, documentation: displayPartsDocumentationsAndKind.documentation, tags: displayPartsDocumentationsAndKind.tags }; } function getSymbolAtLocationForQuickInfo(node, checker) { if ((ts.isIdentifier(node) || ts.isStringLiteral(node)) && ts.isPropertyAssignment(node.parent) && node.parent.name === node) { var type = checker.getContextualType(node.parent.parent); if (type) { var property = checker.getPropertyOfType(type, ts.getTextOfIdentifierOrLiteral(node)); if (property) { return property; } } } return checker.getSymbolAtLocation(node); } /// Goto definition function getDefinitionAtPosition(fileName, position) { synchronizeHostData(); return ts.GoToDefinition.getDefinitionAtPosition(program, getValidSourceFile(fileName), position); } function getDefinitionAndBoundSpan(fileName, position) { synchronizeHostData(); return ts.GoToDefinition.getDefinitionAndBoundSpan(program, getValidSourceFile(fileName), position); } function getTypeDefinitionAtPosition(fileName, position) { synchronizeHostData(); return ts.GoToDefinition.getTypeDefinitionAtPosition(program.getTypeChecker(), getValidSourceFile(fileName), position); } /// Goto implementation function getImplementationAtPosition(fileName, position) { synchronizeHostData(); return ts.FindAllReferences.getImplementationsAtPosition(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); } /// References and Occurrences function getOccurrencesAtPosition(fileName, position) { var results = getOccurrencesAtPositionCore(fileName, position); if (results) { var sourceFile_1 = getCanonicalFileName(ts.normalizeSlashes(fileName)); // Get occurrences only supports reporting occurrences for the file queried. So // filter down to that list. results = ts.filter(results, function (r) { return getCanonicalFileName(ts.normalizeSlashes(r.fileName)) === sourceFile_1; }); } return results; } function getDocumentHighlights(fileName, position, filesToSearch) { synchronizeHostData(); var sourceFilesToSearch = ts.map(filesToSearch, function (f) { return program.getSourceFile(f); }); var sourceFile = getValidSourceFile(fileName); return ts.DocumentHighlights.getDocumentHighlights(program, cancellationToken, sourceFile, position, sourceFilesToSearch); } function getOccurrencesAtPositionCore(fileName, position) { return convertDocumentHighlights(getDocumentHighlights(fileName, position, [fileName])); function convertDocumentHighlights(documentHighlights) { if (!documentHighlights) { return undefined; } var result = []; for (var _i = 0, documentHighlights_1 = documentHighlights; _i < documentHighlights_1.length; _i++) { var entry = documentHighlights_1[_i]; for (var _a = 0, _b = entry.highlightSpans; _a < _b.length; _a++) { var highlightSpan = _b[_a]; result.push({ fileName: entry.fileName, textSpan: highlightSpan.textSpan, isWriteAccess: highlightSpan.kind === "writtenReference" /* writtenReference */, isDefinition: false, isInString: highlightSpan.isInString, }); } } return result; } } function findRenameLocations(fileName, position, findInStrings, findInComments) { return getReferences(fileName, position, { findInStrings: findInStrings, findInComments: findInComments, isForRename: true }); } function getReferencesAtPosition(fileName, position) { return getReferences(fileName, position); } function getReferences(fileName, position, options) { synchronizeHostData(); // Exclude default library when renaming as commonly user don't want to change that file. var sourceFiles = []; if (options && options.isForRename) { for (var _i = 0, _a = program.getSourceFiles(); _i < _a.length; _i++) { var sourceFile = _a[_i]; if (!program.isSourceFileDefaultLibrary(sourceFile)) { sourceFiles.push(sourceFile); } } } else { sourceFiles = program.getSourceFiles().slice(); } return ts.FindAllReferences.findReferencedEntries(program, cancellationToken, sourceFiles, getValidSourceFile(fileName), position, options); } function findReferences(fileName, position) { synchronizeHostData(); return ts.FindAllReferences.findReferencedSymbols(program, cancellationToken, program.getSourceFiles(), getValidSourceFile(fileName), position); } /// NavigateTo function getNavigateToItems(searchValue, maxResultCount, fileName, excludeDtsFiles) { synchronizeHostData(); var sourceFiles = fileName ? [getValidSourceFile(fileName)] : program.getSourceFiles(); return ts.NavigateTo.getNavigateToItems(sourceFiles, program.getTypeChecker(), cancellationToken, searchValue, maxResultCount, excludeDtsFiles); } function getEmitOutput(fileName, emitOnlyDtsFiles) { synchronizeHostData(); var sourceFile = getValidSourceFile(fileName); var customTransformers = host.getCustomTransformers && host.getCustomTransformers(); return ts.getFileEmitOutput(program, sourceFile, emitOnlyDtsFiles, cancellationToken, customTransformers); } // Signature help /** * This is a semantic operation. */ function getSignatureHelpItems(fileName, position) { synchronizeHostData(); var sourceFile = getValidSourceFile(fileName); return ts.SignatureHelp.getSignatureHelpItems(program, sourceFile, position, cancellationToken); } /// Syntactic features function getNonBoundSourceFile(fileName) { return syntaxTreeCache.getCurrentSourceFile(fileName); } function getSourceFile(fileName) { return getNonBoundSourceFile(fileName); } function getNameOrDottedNameSpan(fileName, startPos, _endPos) { var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Get node at the location var node = ts.getTouchingPropertyName(sourceFile, startPos, /*includeJsDocComment*/ false); if (node === sourceFile) { return; } switch (node.kind) { case 180 /* PropertyAccessExpression */: case 144 /* QualifiedName */: case 9 /* StringLiteral */: case 86 /* FalseKeyword */: case 101 /* TrueKeyword */: case 95 /* NullKeyword */: case 97 /* SuperKeyword */: case 99 /* ThisKeyword */: case 170 /* ThisType */: case 71 /* Identifier */: break; // Cant create the text span default: return; } var nodeForStartPos = node; while (true) { if (ts.isRightSideOfPropertyAccess(nodeForStartPos) || ts.isRightSideOfQualifiedName(nodeForStartPos)) { // If on the span is in right side of the the property or qualified name, return the span from the qualified name pos to end of this node nodeForStartPos = nodeForStartPos.parent; } else if (ts.isNameOfModuleDeclaration(nodeForStartPos)) { // If this is name of a module declarations, check if this is right side of dotted module name // If parent of the module declaration which is parent of this node is module declaration and its body is the module declaration that this node is name of // Then this name is name from dotted module if (nodeForStartPos.parent.parent.kind === 234 /* ModuleDeclaration */ && nodeForStartPos.parent.parent.body === nodeForStartPos.parent) { // Use parent module declarations name for start pos nodeForStartPos = nodeForStartPos.parent.parent.name; } else { // We have to use this name for start pos break; } } else { // Is not a member expression so we have found the node for start pos break; } } return ts.createTextSpanFromBounds(nodeForStartPos.getStart(), node.getEnd()); } function getBreakpointStatementAtPosition(fileName, position) { // doesn't use compiler - no need to synchronize with host var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return ts.BreakpointResolver.spanInSourceFileAtLocation(sourceFile, position); } function getNavigationBarItems(fileName) { return ts.NavigationBar.getNavigationBarItems(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function getNavigationTree(fileName) { return ts.NavigationBar.getNavigationTree(syntaxTreeCache.getCurrentSourceFile(fileName), cancellationToken); } function isTsOrTsxFile(fileName) { var kind = ts.getScriptKind(fileName, host); return kind === 3 /* TS */ || kind === 4 /* TSX */; } function getSemanticClassifications(fileName, span) { if (!isTsOrTsxFile(fileName)) { // do not run semantic classification on non-ts-or-tsx files return []; } synchronizeHostData(); return ts.getSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } function getEncodedSemanticClassifications(fileName, span) { if (!isTsOrTsxFile(fileName)) { // do not run semantic classification on non-ts-or-tsx files return { spans: [], endOfLineState: 0 /* None */ }; } synchronizeHostData(); return ts.getEncodedSemanticClassifications(program.getTypeChecker(), cancellationToken, getValidSourceFile(fileName), program.getClassifiableNames(), span); } function getSyntacticClassifications(fileName, span) { // doesn't use compiler - no need to synchronize with host return ts.getSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } function getEncodedSyntacticClassifications(fileName, span) { // doesn't use compiler - no need to synchronize with host return ts.getEncodedSyntacticClassifications(cancellationToken, syntaxTreeCache.getCurrentSourceFile(fileName), span); } function getOutliningSpans(fileName) { // doesn't use compiler - no need to synchronize with host var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return ts.OutliningElementsCollector.collectElements(sourceFile, cancellationToken); } function getBraceMatchingAtPosition(fileName, position) { var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); var result = []; var token = ts.getTouchingToken(sourceFile, position, /*includeJsDocComment*/ false); if (token.getStart(sourceFile) === position) { var matchKind = getMatchingTokenKind(token); // Ensure that there is a corresponding token to match ours. if (matchKind) { var parentElement = token.parent; var childNodes = parentElement.getChildren(sourceFile); for (var _i = 0, childNodes_1 = childNodes; _i < childNodes_1.length; _i++) { var current = childNodes_1[_i]; if (current.kind === matchKind) { var range1 = ts.createTextSpan(token.getStart(sourceFile), token.getWidth(sourceFile)); var range2 = ts.createTextSpan(current.getStart(sourceFile), current.getWidth(sourceFile)); // We want to order the braces when we return the result. if (range1.start < range2.start) { result.push(range1, range2); } else { result.push(range2, range1); } break; } } } } return result; function getMatchingTokenKind(token) { switch (token.kind) { case 17 /* OpenBraceToken */: return 18 /* CloseBraceToken */; case 19 /* OpenParenToken */: return 20 /* CloseParenToken */; case 21 /* OpenBracketToken */: return 22 /* CloseBracketToken */; case 27 /* LessThanToken */: return 29 /* GreaterThanToken */; case 18 /* CloseBraceToken */: return 17 /* OpenBraceToken */; case 20 /* CloseParenToken */: return 19 /* OpenParenToken */; case 22 /* CloseBracketToken */: return 21 /* OpenBracketToken */; case 29 /* GreaterThanToken */: return 27 /* LessThanToken */; } return undefined; } } function getIndentationAtPosition(fileName, position, editorOptions) { var start = ts.timestamp(); var settings = toEditorSettings(editorOptions); var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); log("getIndentationAtPosition: getCurrentSourceFile: " + (ts.timestamp() - start)); start = ts.timestamp(); var result = ts.formatting.SmartIndenter.getIndentation(position, sourceFile, settings); log("getIndentationAtPosition: computeIndentation : " + (ts.timestamp() - start)); return result; } function getFormattingEditsForRange(fileName, start, end, options) { var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); return ts.formatting.formatSelection(start, end, sourceFile, ts.formatting.getFormatContext(toEditorSettings(options))); } function getFormattingEditsForDocument(fileName, options) { return ts.formatting.formatDocument(syntaxTreeCache.getCurrentSourceFile(fileName), ts.formatting.getFormatContext(toEditorSettings(options))); } function getFormattingEditsAfterKeystroke(fileName, position, key, options) { var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); var formatContext = ts.formatting.getFormatContext(toEditorSettings(options)); if (!ts.isInComment(sourceFile, position)) { switch (key) { case "{": return ts.formatting.formatOnOpeningCurly(position, sourceFile, formatContext); case "}": return ts.formatting.formatOnClosingCurly(position, sourceFile, formatContext); case ";": return ts.formatting.formatOnSemicolon(position, sourceFile, formatContext); case "\n": return ts.formatting.formatOnEnter(position, sourceFile, formatContext); } } return []; } function getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions) { synchronizeHostData(); var sourceFile = getValidSourceFile(fileName); var span = ts.createTextSpanFromBounds(start, end); var newLineCharacter = ts.getNewLineOrDefaultFromHost(host); var formatContext = ts.formatting.getFormatContext(formatOptions); return ts.flatMap(ts.deduplicate(errorCodes, ts.equateValues, ts.compareValues), function (errorCode) { cancellationToken.throwIfCancellationRequested(); return ts.codefix.getFixes({ errorCode: errorCode, sourceFile: sourceFile, span: span, program: program, newLineCharacter: newLineCharacter, host: host, cancellationToken: cancellationToken, formatContext: formatContext }); }); } function applyCodeActionCommand(fileName, actionOrUndefined) { var action = typeof fileName === "string" ? actionOrUndefined : fileName; return ts.isArray(action) ? Promise.all(action.map(applySingleCodeActionCommand)) : applySingleCodeActionCommand(action); } function applySingleCodeActionCommand(action) { switch (action.type) { case "install package": return host.installPackage ? host.installPackage({ fileName: ts.toPath(action.file, currentDirectory, getCanonicalFileName), packageName: action.packageName }) : Promise.reject("Host does not implement `installPackage`"); default: ts.Debug.fail(); } } function getDocCommentTemplateAtPosition(fileName, position) { return ts.JsDoc.getDocCommentTemplateAtPosition(ts.getNewLineOrDefaultFromHost(host), syntaxTreeCache.getCurrentSourceFile(fileName), position); } function isValidBraceCompletionAtPosition(fileName, position, openingBrace) { // '<' is currently not supported, figuring out if we're in a Generic Type vs. a comparison is too // expensive to do during typing scenarios // i.e. whether we're dealing with: // var x = new foo<| ( with class foo{} ) // or // var y = 3 <| if (openingBrace === 60 /* lessThan */) { return false; } var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); // Check if in a context where we don't want to perform any insertion if (ts.isInString(sourceFile, position)) { return false; } if (ts.isInsideJsxElementOrAttribute(sourceFile, position)) { return openingBrace === 123 /* openBrace */; } if (ts.isInTemplateString(sourceFile, position)) { return false; } switch (openingBrace) { case 39 /* singleQuote */: case 34 /* doubleQuote */: case 96 /* backtick */: return !ts.isInComment(sourceFile, position); } return true; } function getSpanOfEnclosingComment(fileName, position, onlyMultiLine) { var sourceFile = syntaxTreeCache.getCurrentSourceFile(fileName); var range = ts.formatting.getRangeOfEnclosingComment(sourceFile, position, onlyMultiLine); return range && ts.createTextSpanFromRange(range); } function getTodoComments(fileName, descriptors) { // Note: while getting todo comments seems like a syntactic operation, we actually // treat it as a semantic operation here. This is because we expect our host to call // this on every single file. If we treat this syntactically, then that will cause // us to populate and throw away the tree in our syntax tree cache for each file. By // treating this as a semantic operation, we can access any tree without throwing // anything away. synchronizeHostData(); var sourceFile = getValidSourceFile(fileName); cancellationToken.throwIfCancellationRequested(); var fileContents = sourceFile.text; var result = []; // Exclude node_modules files as we don't want to show the todos of external libraries. if (descriptors.length > 0 && !isNodeModulesFile(sourceFile.fileName)) { var regExp = getTodoCommentsRegExp(); var matchArray = void 0; while (matchArray = regExp.exec(fileContents)) { cancellationToken.throwIfCancellationRequested(); // If we got a match, here is what the match array will look like. Say the source text is: // // " // hack 1" // // The result array with the regexp: will be: // // ["// hack 1", "// ", "hack 1", undefined, "hack"] // // Here are the relevant capture groups: // 0) The full match for the entire regexp. // 1) The preamble to the message portion. // 2) The message portion. // 3...N) The descriptor that was matched - by index. 'undefined' for each // descriptor that didn't match. an actual value if it did match. // // i.e. 'undefined' in position 3 above means TODO(jason) didn't match. // "hack" in position 4 means HACK did match. var firstDescriptorCaptureIndex = 3; ts.Debug.assert(matchArray.length === descriptors.length + firstDescriptorCaptureIndex); var preamble = matchArray[1]; var matchPosition = matchArray.index + preamble.length; // OK, we have found a match in the file. This is only an acceptable match if // it is contained within a comment. if (!ts.isInComment(sourceFile, matchPosition)) { continue; } var descriptor = undefined; for (var i = 0; i < descriptors.length; i++) { if (matchArray[i + firstDescriptorCaptureIndex]) { descriptor = descriptors[i]; } } ts.Debug.assert(descriptor !== undefined); // We don't want to match something like 'TODOBY', so we make sure a non // letter/digit follows the match. if (isLetterOrDigit(fileContents.charCodeAt(matchPosition + descriptor.text.length))) { continue; } var message = matchArray[2]; result.push({ descriptor: descriptor, message: message, position: matchPosition }); } } return result; function escapeRegExp(str) { return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); } function getTodoCommentsRegExp() { // NOTE: ?: means 'non-capture group'. It allows us to have groups without having to // filter them out later in the final result array. // TODO comments can appear in one of the following forms: // // 1) // TODO or /////////// TODO // // 2) /* TODO or /********** TODO // // 3) /* // * TODO // */ // // The following three regexps are used to match the start of the text up to the TODO // comment portion. var singleLineCommentStart = /(?:\/\/+\s*)/.source; var multiLineCommentStart = /(?:\/\*+\s*)/.source; var anyNumberOfSpacesAndAsterisksAtStartOfLine = /(?:^(?:\s|\*)*)/.source; // Match any of the above three TODO comment start regexps. // Note that the outermost group *is* a capture group. We want to capture the preamble // so that we can determine the starting position of the TODO comment match. var preamble = "(" + anyNumberOfSpacesAndAsterisksAtStartOfLine + "|" + singleLineCommentStart + "|" + multiLineCommentStart + ")"; // Takes the descriptors and forms a regexp that matches them as if they were literals. // For example, if the descriptors are "TODO(jason)" and "HACK", then this will be: // // (?:(TODO\(jason\))|(HACK)) // // Note that the outermost group is *not* a capture group, but the innermost groups // *are* capture groups. By capturing the inner literals we can determine after // matching which descriptor we are dealing with. var literals = "(?:" + ts.map(descriptors, function (d) { return "(" + escapeRegExp(d.text) + ")"; }).join("|") + ")"; // After matching a descriptor literal, the following regexp matches the rest of the // text up to the end of the line (or */). var endOfLineOrEndOfComment = /(?:$|\*\/)/.source; var messageRemainder = /(?:.*?)/.source; // This is the portion of the match we'll return as part of the TODO comment result. We // match the literal portion up to the end of the line or end of comment. var messagePortion = "(" + literals + messageRemainder + ")"; var regExpString = preamble + messagePortion + endOfLineOrEndOfComment; // The final regexp will look like this: // /((?:\/\/+\s*)|(?:\/\*+\s*)|(?:^(?:\s|\*)*))((?:(TODO\(jason\))|(HACK))(?:.*?))(?:$|\*\/)/gim // The flags of the regexp are important here. // 'g' is so that we are doing a global search and can find matches several times // in the input. // // 'i' is for case insensitivity (We do this to match C# TODO comment code). // // 'm' is so we can find matches in a multi-line input. return new RegExp(regExpString, "gim"); } function isLetterOrDigit(char) { return (char >= 97 /* a */ && char <= 122 /* z */) || (char >= 65 /* A */ && char <= 90 /* Z */) || (char >= 48 /* _0 */ && char <= 57 /* _9 */); } function isNodeModulesFile(path) { return ts.stringContains(path, "/node_modules/"); } } function getRenameInfo(fileName, position) { synchronizeHostData(); var defaultLibFileName = host.getDefaultLibFileName(host.getCompilationSettings()); return ts.Rename.getRenameInfo(program.getTypeChecker(), defaultLibFileName, getCanonicalFileName, getValidSourceFile(fileName), position); } function getRefactorContext(file, positionOrRange, formatOptions) { var _a = typeof positionOrRange === "number" ? [positionOrRange, undefined] : [positionOrRange.pos, positionOrRange.end], startPosition = _a[0], endPosition = _a[1]; return { file: file, startPosition: startPosition, endPosition: endPosition, program: getProgram(), newLineCharacter: formatOptions ? formatOptions.newLineCharacter : host.getNewLine(), host: host, formatContext: ts.formatting.getFormatContext(formatOptions), cancellationToken: cancellationToken, }; } function getApplicableRefactors(fileName, positionOrRange) { synchronizeHostData(); var file = getValidSourceFile(fileName); return ts.refactor.getApplicableRefactors(getRefactorContext(file, positionOrRange)); } function getEditsForRefactor(fileName, formatOptions, positionOrRange, refactorName, actionName) { synchronizeHostData(); var file = getValidSourceFile(fileName); return ts.refactor.getEditsForRefactor(getRefactorContext(file, positionOrRange, formatOptions), refactorName, actionName); } return { dispose: dispose, cleanupSemanticCache: cleanupSemanticCache, getSyntacticDiagnostics: getSyntacticDiagnostics, getSemanticDiagnostics: getSemanticDiagnostics, getCompilerOptionsDiagnostics: getCompilerOptionsDiagnostics, getSyntacticClassifications: getSyntacticClassifications, getSemanticClassifications: getSemanticClassifications, getEncodedSyntacticClassifications: getEncodedSyntacticClassifications, getEncodedSemanticClassifications: getEncodedSemanticClassifications, getCompletionsAtPosition: getCompletionsAtPosition, getCompletionEntryDetails: getCompletionEntryDetails, getCompletionEntrySymbol: getCompletionEntrySymbol, getSignatureHelpItems: getSignatureHelpItems, getQuickInfoAtPosition: getQuickInfoAtPosition, getDefinitionAtPosition: getDefinitionAtPosition, getDefinitionAndBoundSpan: getDefinitionAndBoundSpan, getImplementationAtPosition: getImplementationAtPosition, getTypeDefinitionAtPosition: getTypeDefinitionAtPosition, getReferencesAtPosition: getReferencesAtPosition, findReferences: findReferences, getOccurrencesAtPosition: getOccurrencesAtPosition, getDocumentHighlights: getDocumentHighlights, getNameOrDottedNameSpan: getNameOrDottedNameSpan, getBreakpointStatementAtPosition: getBreakpointStatementAtPosition, getNavigateToItems: getNavigateToItems, getRenameInfo: getRenameInfo, findRenameLocations: findRenameLocations, getNavigationBarItems: getNavigationBarItems, getNavigationTree: getNavigationTree, getOutliningSpans: getOutliningSpans, getTodoComments: getTodoComments, getBraceMatchingAtPosition: getBraceMatchingAtPosition, getIndentationAtPosition: getIndentationAtPosition, getFormattingEditsForRange: getFormattingEditsForRange, getFormattingEditsForDocument: getFormattingEditsForDocument, getFormattingEditsAfterKeystroke: getFormattingEditsAfterKeystroke, getDocCommentTemplateAtPosition: getDocCommentTemplateAtPosition, isValidBraceCompletionAtPosition: isValidBraceCompletionAtPosition, getSpanOfEnclosingComment: getSpanOfEnclosingComment, getCodeFixesAtPosition: getCodeFixesAtPosition, applyCodeActionCommand: applyCodeActionCommand, getEmitOutput: getEmitOutput, getNonBoundSourceFile: getNonBoundSourceFile, getSourceFile: getSourceFile, getProgram: getProgram, getApplicableRefactors: getApplicableRefactors, getEditsForRefactor: getEditsForRefactor, }; } ts.createLanguageService = createLanguageService; /* @internal */ /** Names in the name table are escaped, so an identifier `__foo` will have a name table entry `___foo`. */ function getNameTable(sourceFile) { if (!sourceFile.nameTable) { initializeNameTable(sourceFile); } return sourceFile.nameTable; } ts.getNameTable = getNameTable; function initializeNameTable(sourceFile) { var nameTable = sourceFile.nameTable = ts.createUnderscoreEscapedMap(); sourceFile.forEachChild(function walk(node) { if (ts.isIdentifier(node) && node.escapedText || ts.isStringOrNumericLiteral(node) && literalIsName(node)) { var text = ts.getEscapedTextOfIdentifierOrLiteral(node); nameTable.set(text, nameTable.get(text) === undefined ? node.pos : -1); } ts.forEachChild(node, walk); if (ts.hasJSDocNodes(node)) { for (var _i = 0, _a = node.jsDoc; _i < _a.length; _i++) { var jsDoc = _a[_i]; ts.forEachChild(jsDoc, walk); } } }); } /** * We want to store any numbers/strings if they were a name that could be * related to a declaration. So, if we have 'import x = require("something")' * then we want 'something' to be in the name table. Similarly, if we have * "a['propname']" then we want to store "propname" in the name table. */ function literalIsName(node) { return ts.isDeclarationName(node) || node.parent.kind === 249 /* ExternalModuleReference */ || isArgumentOfElementAccessExpression(node) || ts.isLiteralComputedPropertyDeclarationName(node); } function isObjectLiteralElement(node) { switch (node.kind) { case 257 /* JsxAttribute */: case 259 /* JsxSpreadAttribute */: case 265 /* PropertyAssignment */: case 266 /* ShorthandPropertyAssignment */: case 152 /* MethodDeclaration */: case 154 /* GetAccessor */: case 155 /* SetAccessor */: return true; } return false; } /** * Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 } */ /* @internal */ function getContainingObjectLiteralElement(node) { switch (node.kind) { case 9 /* StringLiteral */: case 8 /* NumericLiteral */: if (node.parent.kind === 145 /* ComputedPropertyName */) { return isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined; } // falls through case 71 /* Identifier */: return isObjectLiteralElement(node.parent) && (node.parent.parent.kind === 179 /* ObjectLiteralExpression */ || node.parent.parent.kind === 258 /* JsxAttributes */) && node.parent.name === node ? node.parent : undefined; } return undefined; } ts.getContainingObjectLiteralElement = getContainingObjectLiteralElement; /* @internal */ function getPropertySymbolsFromContextualType(typeChecker, node) { var objectLiteral = node.parent; var contextualType = typeChecker.getContextualType(objectLiteral); return getPropertySymbolsFromType(contextualType, node.name); } ts.getPropertySymbolsFromContextualType = getPropertySymbolsFromContextualType; /* @internal */ function getPropertySymbolsFromType(type, propName) { var name = ts.unescapeLeadingUnderscores(ts.getTextOfPropertyName(propName)); if (name && type) { var result_9 = []; var symbol = type.getProperty(name); if (type.flags & 131072 /* Union */) { ts.forEach(type.types, function (t) { var symbol = t.getProperty(name); if (symbol) { result_9.push(symbol); } }); return result_9; } if (symbol) { result_9.push(symbol); return result_9; } } return undefined; } ts.getPropertySymbolsFromType = getPropertySymbolsFromType; function isArgumentOfElementAccessExpression(node) { return node && node.parent && node.parent.kind === 181 /* ElementAccessExpression */ && node.parent.argumentExpression === node; } /** * Get the path of the default library files (lib.d.ts) as distributed with the typescript * node package. * The functionality is not supported if the ts module is consumed outside of a node module. */ function getDefaultLibFilePath(options) { // Check __dirname is defined and that we are on a node.js system. if (typeof __dirname !== "undefined") { return __dirname + ts.directorySeparator + ts.getDefaultLibFileName(options); } throw new Error("getDefaultLibFilePath is only supported when consumed as a node module. "); } ts.getDefaultLibFilePath = getDefaultLibFilePath; ts.objectAllocator = getServicesObjectAllocator(); })(ts || (ts = {})); /// /// /// /// var ts; (function (ts) { var server; (function (server) { // tslint:disable variable-name server.ActionSet = "action::set"; server.ActionInvalidate = "action::invalidate"; server.ActionPackageInstalled = "action::packageInstalled"; server.EventTypesRegistry = "event::typesRegistry"; server.EventBeginInstallTypes = "event::beginInstallTypes"; server.EventEndInstallTypes = "event::endInstallTypes"; server.EventInitializationFailed = "event::initializationFailed"; var Arguments; (function (Arguments) { Arguments.GlobalCacheLocation = "--globalTypingsCacheLocation"; Arguments.LogFile = "--logFile"; Arguments.EnableTelemetry = "--enableTelemetry"; Arguments.TypingSafeListLocation = "--typingSafeListLocation"; Arguments.TypesMapLocation = "--typesMapLocation"; /** * This argument specifies the location of the NPM executable. * typingsInstaller will run the command with `${npmLocation} install ...`. */ Arguments.NpmLocation = "--npmLocation"; })(Arguments = server.Arguments || (server.Arguments = {})); function hasArgument(argumentName) { return ts.sys.args.indexOf(argumentName) >= 0; } server.hasArgument = hasArgument; function findArgument(argumentName) { var index = ts.sys.args.indexOf(argumentName); return index >= 0 && index < ts.sys.args.length - 1 ? ts.sys.args[index + 1] : undefined; } server.findArgument = findArgument; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /// var ts; (function (ts) { var server; (function (server) { var LogLevel; (function (LogLevel) { LogLevel[LogLevel["terse"] = 0] = "terse"; LogLevel[LogLevel["normal"] = 1] = "normal"; LogLevel[LogLevel["requestTime"] = 2] = "requestTime"; LogLevel[LogLevel["verbose"] = 3] = "verbose"; })(LogLevel = server.LogLevel || (server.LogLevel = {})); server.emptyArray = createSortedArray(); // TODO: Use a const enum (https://github.com/Microsoft/TypeScript/issues/16804) var Msg; (function (Msg) { Msg["Err"] = "Err"; Msg["Info"] = "Info"; Msg["Perf"] = "Perf"; })(Msg = server.Msg || (server.Msg = {})); function getProjectRootPath(project) { switch (project.projectKind) { case server.ProjectKind.Configured: return ts.getDirectoryPath(project.getProjectName()); case server.ProjectKind.Inferred: // TODO: fixme return ""; case server.ProjectKind.External: var projectName = ts.normalizeSlashes(project.getProjectName()); return ts.getDirectoryPath(projectName); } } function createInstallTypingsRequest(project, typeAcquisition, unresolvedImports, cachePath) { return { projectName: project.getProjectName(), fileNames: project.getFileNames(/*excludeFilesFromExternalLibraries*/ true, /*excludeConfigFiles*/ true).concat(project.getExcludedFiles()), compilerOptions: project.getCompilationSettings(), typeAcquisition: typeAcquisition, unresolvedImports: unresolvedImports, projectRootPath: getProjectRootPath(project), cachePath: cachePath, kind: "discover" }; } server.createInstallTypingsRequest = createInstallTypingsRequest; var Errors; (function (Errors) { function ThrowNoProject() { throw new Error("No Project."); } Errors.ThrowNoProject = ThrowNoProject; function ThrowProjectLanguageServiceDisabled() { throw new Error("The project's language service is disabled."); } Errors.ThrowProjectLanguageServiceDisabled = ThrowProjectLanguageServiceDisabled; function ThrowProjectDoesNotContainDocument(fileName, project) { throw new Error("Project '" + project.getProjectName() + "' does not contain document '" + fileName + "'"); } Errors.ThrowProjectDoesNotContainDocument = ThrowProjectDoesNotContainDocument; })(Errors = server.Errors || (server.Errors = {})); function getDefaultFormatCodeSettings(host) { return { indentSize: 4, tabSize: 4, newLineCharacter: host.newLine || "\n", convertTabsToSpaces: true, indentStyle: ts.IndentStyle.Smart, insertSpaceAfterConstructor: false, insertSpaceAfterCommaDelimiter: true, insertSpaceAfterSemicolonInForStatements: true, insertSpaceBeforeAndAfterBinaryOperators: true, insertSpaceAfterKeywordsInControlFlowStatements: true, insertSpaceAfterFunctionKeywordForAnonymousFunctions: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets: false, insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces: true, insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces: false, insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces: false, insertSpaceBeforeFunctionParenthesis: false, placeOpenBraceOnNewLineForFunctions: false, placeOpenBraceOnNewLineForControlBlocks: false, }; } server.getDefaultFormatCodeSettings = getDefaultFormatCodeSettings; function mergeMapLikes(target, source) { for (var key in source) { if (ts.hasProperty(source, key)) { target[key] = source[key]; } } } server.mergeMapLikes = mergeMapLikes; function toNormalizedPath(fileName) { return ts.normalizePath(fileName); } server.toNormalizedPath = toNormalizedPath; function normalizedPathToPath(normalizedPath, currentDirectory, getCanonicalFileName) { var f = ts.isRootedDiskPath(normalizedPath) ? normalizedPath : ts.getNormalizedAbsolutePath(normalizedPath, currentDirectory); return getCanonicalFileName(f); } server.normalizedPathToPath = normalizedPathToPath; function asNormalizedPath(fileName) { return fileName; } server.asNormalizedPath = asNormalizedPath; function createNormalizedPathMap() { var map = ts.createMap(); return { get: function (path) { return map.get(path); }, set: function (path, value) { map.set(path, value); }, contains: function (path) { return map.has(path); }, remove: function (path) { map.delete(path); } }; } server.createNormalizedPathMap = createNormalizedPathMap; function isInferredProjectName(name) { // POSIX defines /dev/null as a device - there should be no file with this prefix return /dev\/null\/inferredProject\d+\*/.test(name); } server.isInferredProjectName = isInferredProjectName; function makeInferredProjectName(counter) { return "/dev/null/inferredProject" + counter + "*"; } server.makeInferredProjectName = makeInferredProjectName; function createSortedArray() { return []; } server.createSortedArray = createSortedArray; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /* @internal */ (function (ts) { var server; (function (server) { var ThrottledOperations = /** @class */ (function () { function ThrottledOperations(host, logger) { this.host = host; this.pendingTimeouts = ts.createMap(); this.logger = logger.hasLevel(server.LogLevel.verbose) && logger; } /** * Wait `number` milliseconds and then invoke `cb`. If, while waiting, schedule * is called again with the same `operationId`, cancel this operation in favor * of the new one. (Note that the amount of time the canceled operation had been * waiting does not affect the amount of time that the new operation waits.) */ ThrottledOperations.prototype.schedule = function (operationId, delay, cb) { var pendingTimeout = this.pendingTimeouts.get(operationId); if (pendingTimeout) { // another operation was already scheduled for this id - cancel it this.host.clearTimeout(pendingTimeout); } // schedule new operation, pass arguments this.pendingTimeouts.set(operationId, this.host.setTimeout(ThrottledOperations.run, delay, this, operationId, cb)); if (this.logger) { this.logger.info("Scheduled: " + operationId + (pendingTimeout ? ", Cancelled earlier one" : "")); } }; ThrottledOperations.run = function (self, operationId, cb) { self.pendingTimeouts.delete(operationId); if (self.logger) { self.logger.info("Running: " + operationId); } cb(); }; return ThrottledOperations; }()); server.ThrottledOperations = ThrottledOperations; var GcTimer = /** @class */ (function () { function GcTimer(host, delay, logger) { this.host = host; this.delay = delay; this.logger = logger; } GcTimer.prototype.scheduleCollect = function () { if (!this.host.gc || this.timerId !== undefined) { // no global.gc or collection was already scheduled - skip this request return; } this.timerId = this.host.setTimeout(GcTimer.run, this.delay, this); }; GcTimer.run = function (self) { self.timerId = undefined; var log = self.logger.hasLevel(server.LogLevel.requestTime); var before = log && self.host.getMemoryUsage(); self.host.gc(); if (log) { var after = self.host.getMemoryUsage(); self.logger.perftrc("GC::before " + before + ", after " + after); } }; return GcTimer; }()); server.GcTimer = GcTimer; function getBaseConfigFileName(configFilePath) { var base = ts.getBaseFileName(configFilePath); return base === "tsconfig.json" || base === "jsconfig.json" ? base : undefined; } server.getBaseConfigFileName = getBaseConfigFileName; function insertSorted(array, insert, compare) { if (array.length === 0) { array.push(insert); return; } var insertIndex = ts.binarySearch(array, insert, ts.identity, compare); if (insertIndex < 0) { array.splice(~insertIndex, 0, insert); } } server.insertSorted = insertSorted; function removeSorted(array, remove, compare) { if (!array || array.length === 0) { return; } if (array[0] === remove) { array.splice(0, 1); return; } var removeIndex = ts.binarySearch(array, remove, ts.identity, compare); if (removeIndex >= 0) { array.splice(removeIndex, 1); } } server.removeSorted = removeSorted; function toSortedArray(arr, comparer) { arr.sort(comparer); return arr; } server.toSortedArray = toSortedArray; function toDeduplicatedSortedArray(arr) { arr.sort(); ts.filterMutate(arr, isNonDuplicateInSortedArray); return arr; } server.toDeduplicatedSortedArray = toDeduplicatedSortedArray; function isNonDuplicateInSortedArray(value, index, array) { return index === 0 || value !== array[index - 1]; } function enumerateInsertsAndDeletes(newItems, oldItems, inserted, deleted, comparer) { var newIndex = 0; var oldIndex = 0; var newLen = newItems.length; var oldLen = oldItems.length; while (newIndex < newLen && oldIndex < oldLen) { var newItem = newItems[newIndex]; var oldItem = oldItems[oldIndex]; var compareResult = comparer(newItem, oldItem); if (compareResult === -1 /* LessThan */) { inserted(newItem); newIndex++; } else if (compareResult === 1 /* GreaterThan */) { deleted(oldItem); oldIndex++; } else { newIndex++; oldIndex++; } } while (newIndex < newLen) { inserted(newItems[newIndex++]); } while (oldIndex < oldLen) { deleted(oldItems[oldIndex++]); } } server.enumerateInsertsAndDeletes = enumerateInsertsAndDeletes; /* @internal */ function indent(str) { return "\n " + str; } server.indent = indent; /** Put stringified JSON on the next line, indented. */ /* @internal */ function stringifyIndented(json) { return "\n " + JSON.stringify(json); } server.stringifyIndented = stringifyIndented; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /** * Declaration module describing the TypeScript Server protocol */ var ts; (function (ts) { var server; (function (server) { var protocol; (function (protocol) { // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. var CommandTypes; (function (CommandTypes) { CommandTypes["Brace"] = "brace"; /* @internal */ CommandTypes["BraceFull"] = "brace-full"; CommandTypes["BraceCompletion"] = "braceCompletion"; CommandTypes["GetSpanOfEnclosingComment"] = "getSpanOfEnclosingComment"; CommandTypes["Change"] = "change"; CommandTypes["Close"] = "close"; CommandTypes["Completions"] = "completions"; /* @internal */ CommandTypes["CompletionsFull"] = "completions-full"; CommandTypes["CompletionDetails"] = "completionEntryDetails"; /* @internal */ CommandTypes["CompletionDetailsFull"] = "completionEntryDetails-full"; CommandTypes["CompileOnSaveAffectedFileList"] = "compileOnSaveAffectedFileList"; CommandTypes["CompileOnSaveEmitFile"] = "compileOnSaveEmitFile"; CommandTypes["Configure"] = "configure"; CommandTypes["Definition"] = "definition"; /* @internal */ CommandTypes["DefinitionFull"] = "definition-full"; CommandTypes["DefinitionAndBoundSpan"] = "definitionAndBoundSpan"; /* @internal */ CommandTypes["DefinitionAndBoundSpanFull"] = "definitionAndBoundSpan-full"; CommandTypes["Implementation"] = "implementation"; /* @internal */ CommandTypes["ImplementationFull"] = "implementation-full"; CommandTypes["Exit"] = "exit"; CommandTypes["Format"] = "format"; CommandTypes["Formatonkey"] = "formatonkey"; /* @internal */ CommandTypes["FormatFull"] = "format-full"; /* @internal */ CommandTypes["FormatonkeyFull"] = "formatonkey-full"; /* @internal */ CommandTypes["FormatRangeFull"] = "formatRange-full"; CommandTypes["Geterr"] = "geterr"; CommandTypes["GeterrForProject"] = "geterrForProject"; CommandTypes["SemanticDiagnosticsSync"] = "semanticDiagnosticsSync"; CommandTypes["SyntacticDiagnosticsSync"] = "syntacticDiagnosticsSync"; CommandTypes["NavBar"] = "navbar"; /* @internal */ CommandTypes["NavBarFull"] = "navbar-full"; CommandTypes["Navto"] = "navto"; /* @internal */ CommandTypes["NavtoFull"] = "navto-full"; CommandTypes["NavTree"] = "navtree"; CommandTypes["NavTreeFull"] = "navtree-full"; CommandTypes["Occurrences"] = "occurrences"; CommandTypes["DocumentHighlights"] = "documentHighlights"; /* @internal */ CommandTypes["DocumentHighlightsFull"] = "documentHighlights-full"; CommandTypes["Open"] = "open"; CommandTypes["Quickinfo"] = "quickinfo"; /* @internal */ CommandTypes["QuickinfoFull"] = "quickinfo-full"; CommandTypes["References"] = "references"; /* @internal */ CommandTypes["ReferencesFull"] = "references-full"; CommandTypes["Reload"] = "reload"; CommandTypes["Rename"] = "rename"; /* @internal */ CommandTypes["RenameInfoFull"] = "rename-full"; /* @internal */ CommandTypes["RenameLocationsFull"] = "renameLocations-full"; CommandTypes["Saveto"] = "saveto"; CommandTypes["SignatureHelp"] = "signatureHelp"; /* @internal */ CommandTypes["SignatureHelpFull"] = "signatureHelp-full"; CommandTypes["TypeDefinition"] = "typeDefinition"; CommandTypes["ProjectInfo"] = "projectInfo"; CommandTypes["ReloadProjects"] = "reloadProjects"; CommandTypes["Unknown"] = "unknown"; CommandTypes["OpenExternalProject"] = "openExternalProject"; CommandTypes["OpenExternalProjects"] = "openExternalProjects"; CommandTypes["CloseExternalProject"] = "closeExternalProject"; /* @internal */ CommandTypes["SynchronizeProjectList"] = "synchronizeProjectList"; /* @internal */ CommandTypes["ApplyChangedToOpenFiles"] = "applyChangedToOpenFiles"; /* @internal */ CommandTypes["EncodedSemanticClassificationsFull"] = "encodedSemanticClassifications-full"; /* @internal */ CommandTypes["Cleanup"] = "cleanup"; /* @internal */ CommandTypes["OutliningSpans"] = "outliningSpans"; CommandTypes["TodoComments"] = "todoComments"; CommandTypes["Indentation"] = "indentation"; CommandTypes["DocCommentTemplate"] = "docCommentTemplate"; /* @internal */ CommandTypes["CompilerOptionsDiagnosticsFull"] = "compilerOptionsDiagnostics-full"; /* @internal */ CommandTypes["NameOrDottedNameSpan"] = "nameOrDottedNameSpan"; /* @internal */ CommandTypes["BreakpointStatement"] = "breakpointStatement"; CommandTypes["CompilerOptionsForInferredProjects"] = "compilerOptionsForInferredProjects"; CommandTypes["GetCodeFixes"] = "getCodeFixes"; CommandTypes["ApplyCodeActionCommand"] = "applyCodeActionCommand"; /* @internal */ CommandTypes["GetCodeFixesFull"] = "getCodeFixes-full"; CommandTypes["GetSupportedCodeFixes"] = "getSupportedCodeFixes"; CommandTypes["GetApplicableRefactors"] = "getApplicableRefactors"; CommandTypes["GetEditsForRefactor"] = "getEditsForRefactor"; /* @internal */ CommandTypes["GetEditsForRefactorFull"] = "getEditsForRefactor-full"; // NOTE: If updating this, be sure to also update `allCommandNames` in `harness/unittests/session.ts`. })(CommandTypes = protocol.CommandTypes || (protocol.CommandTypes = {})); var IndentStyle; (function (IndentStyle) { IndentStyle["None"] = "None"; IndentStyle["Block"] = "Block"; IndentStyle["Smart"] = "Smart"; })(IndentStyle = protocol.IndentStyle || (protocol.IndentStyle = {})); var JsxEmit; (function (JsxEmit) { JsxEmit["None"] = "None"; JsxEmit["Preserve"] = "Preserve"; JsxEmit["ReactNative"] = "ReactNative"; JsxEmit["React"] = "React"; })(JsxEmit = protocol.JsxEmit || (protocol.JsxEmit = {})); var ModuleKind; (function (ModuleKind) { ModuleKind["None"] = "None"; ModuleKind["CommonJS"] = "CommonJS"; ModuleKind["AMD"] = "AMD"; ModuleKind["UMD"] = "UMD"; ModuleKind["System"] = "System"; ModuleKind["ES6"] = "ES6"; ModuleKind["ES2015"] = "ES2015"; ModuleKind["ESNext"] = "ESNext"; })(ModuleKind = protocol.ModuleKind || (protocol.ModuleKind = {})); var ModuleResolutionKind; (function (ModuleResolutionKind) { ModuleResolutionKind["Classic"] = "Classic"; ModuleResolutionKind["Node"] = "Node"; })(ModuleResolutionKind = protocol.ModuleResolutionKind || (protocol.ModuleResolutionKind = {})); var NewLineKind; (function (NewLineKind) { NewLineKind["Crlf"] = "Crlf"; NewLineKind["Lf"] = "Lf"; })(NewLineKind = protocol.NewLineKind || (protocol.NewLineKind = {})); var ScriptTarget; (function (ScriptTarget) { ScriptTarget["ES3"] = "ES3"; ScriptTarget["ES5"] = "ES5"; ScriptTarget["ES6"] = "ES6"; ScriptTarget["ES2015"] = "ES2015"; ScriptTarget["ES2016"] = "ES2016"; ScriptTarget["ES2017"] = "ES2017"; ScriptTarget["ESNext"] = "ESNext"; })(ScriptTarget = protocol.ScriptTarget || (protocol.ScriptTarget = {})); })(protocol = server.protocol || (server.protocol = {})); })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /// /// /// var ts; (function (ts) { var server; (function (server) { server.nullCancellationToken = { isCancellationRequested: function () { return false; }, setRequest: function () { return void 0; }, resetRequest: function () { return void 0; } }; function hrTimeToMilliseconds(time) { var seconds = time[0]; var nanoseconds = time[1]; return ((1e9 * seconds) + nanoseconds) / 1000000.0; } function isDeclarationFileInJSOnlyNonConfiguredProject(project, file) { // Checking for semantic diagnostics is an expensive process. We want to avoid it if we // know for sure it is not needed. // For instance, .d.ts files injected by ATA automatically do not produce any relevant // errors to a JS- only project. // // Note that configured projects can set skipLibCheck (on by default in jsconfig.json) to // disable checking for declaration files. We only need to verify for inferred projects (e.g. // miscellaneous context in VS) and external projects(e.g.VS.csproj project) with only JS // files. // // We still want to check .js files in a JS-only inferred or external project (e.g. if the // file has '// @ts-check'). if ((project.projectKind === server.ProjectKind.Inferred || project.projectKind === server.ProjectKind.External) && project.isJsOnlyProject()) { var scriptInfo = project.getScriptInfoForNormalizedPath(file); return scriptInfo && !scriptInfo.isJavaScript(); } return false; } function compareNumber(a, b) { return a - b; } function compareFileStart(a, b) { if (a.file < b.file) { return -1; } else if (a.file === b.file) { var n = compareNumber(a.start.line, b.start.line); if (n === 0) { return compareNumber(a.start.offset, b.start.offset); } else return n; } else { return 1; } } function formatDiag(fileName, project, diag) { var scriptInfo = project.getScriptInfoForNormalizedPath(fileName); return { start: scriptInfo.positionToLineOffset(diag.start), end: scriptInfo.positionToLineOffset(diag.start + diag.length), text: ts.flattenDiagnosticMessageText(diag.messageText, "\n"), code: diag.code, category: ts.DiagnosticCategory[diag.category].toLowerCase(), source: diag.source }; } function convertToLocation(lineAndCharacter) { return { line: lineAndCharacter.line + 1, offset: lineAndCharacter.character + 1 }; } function formatConfigFileDiag(diag, includeFileName) { var start = diag.file && convertToLocation(ts.getLineAndCharacterOfPosition(diag.file, diag.start)); var end = diag.file && convertToLocation(ts.getLineAndCharacterOfPosition(diag.file, diag.start + diag.length)); var text = ts.flattenDiagnosticMessageText(diag.messageText, "\n"); var code = diag.code, source = diag.source; var category = ts.DiagnosticCategory[diag.category].toLowerCase(); return includeFileName ? { start: start, end: end, text: text, code: code, category: category, source: source, fileName: diag.file && diag.file.fileName } : { start: start, end: end, text: text, code: code, category: category, source: source }; } function allEditsBeforePos(edits, pos) { for (var _i = 0, edits_2 = edits; _i < edits_2.length; _i++) { var edit = edits_2[_i]; if (ts.textSpanEnd(edit.span) >= pos) { return false; } } return true; } server.CommandNames = server.protocol.CommandTypes; // tslint:disable-line variable-name function formatMessage(msg, logger, byteLength, newLine) { var verboseLogging = logger.hasLevel(server.LogLevel.verbose); var json = JSON.stringify(msg); if (verboseLogging) { logger.info(msg.type + ":" + server.indent(json)); } var len = byteLength(json, "utf8"); return "Content-Length: " + (1 + len) + "\r\n\r\n" + json + newLine; } server.formatMessage = formatMessage; /** * Represents operation that can schedule its next step to be executed later. * Scheduling is done via instance of NextStep. If on current step subsequent step was not scheduled - operation is assumed to be completed. */ var MultistepOperation = /** @class */ (function () { function MultistepOperation(operationHost) { this.operationHost = operationHost; } MultistepOperation.prototype.startNew = function (action) { this.complete(); this.requestId = this.operationHost.getCurrentRequestId(); this.executeAction(action); }; MultistepOperation.prototype.complete = function () { if (this.requestId !== undefined) { this.operationHost.sendRequestCompletedEvent(this.requestId); this.requestId = undefined; } this.setTimerHandle(undefined); this.setImmediateId(undefined); }; MultistepOperation.prototype.immediate = function (action) { var _this = this; var requestId = this.requestId; ts.Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "immediate: incorrect request id"); this.setImmediateId(this.operationHost.getServerHost().setImmediate(function () { _this.immediateId = undefined; _this.operationHost.executeWithRequestId(requestId, function () { return _this.executeAction(action); }); })); }; MultistepOperation.prototype.delay = function (ms, action) { var _this = this; var requestId = this.requestId; ts.Debug.assert(requestId === this.operationHost.getCurrentRequestId(), "delay: incorrect request id"); this.setTimerHandle(this.operationHost.getServerHost().setTimeout(function () { _this.timerHandle = undefined; _this.operationHost.executeWithRequestId(requestId, function () { return _this.executeAction(action); }); }, ms)); }; MultistepOperation.prototype.executeAction = function (action) { var stop = false; try { if (this.operationHost.isCancellationRequested()) { stop = true; } else { action(this); } } catch (e) { stop = true; // ignore cancellation request if (!(e instanceof ts.OperationCanceledException)) { this.operationHost.logError(e, "delayed processing of request " + this.requestId); } } if (stop || !this.hasPendingWork()) { this.complete(); } }; MultistepOperation.prototype.setTimerHandle = function (timerHandle) { if (this.timerHandle !== undefined) { this.operationHost.getServerHost().clearTimeout(this.timerHandle); } this.timerHandle = timerHandle; }; MultistepOperation.prototype.setImmediateId = function (immediateId) { if (this.immediateId !== undefined) { this.operationHost.getServerHost().clearImmediate(this.immediateId); } this.immediateId = immediateId; }; MultistepOperation.prototype.hasPendingWork = function () { return !!this.timerHandle || !!this.immediateId; }; return MultistepOperation; }()); /** @internal */ function toEvent(eventName, body) { return { seq: 0, type: "event", event: eventName, body: body }; } server.toEvent = toEvent; var Session = /** @class */ (function () { function Session(opts) { var _this = this; this.changeSeq = 0; this.handlers = ts.createMapFromTemplate((_a = {}, _a[server.CommandNames.OpenExternalProject] = function (request) { _this.projectService.openExternalProject(request.arguments, /*suppressRefreshOfInferredProjects*/ false); // TODO: report errors return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.OpenExternalProjects] = function (request) { _this.projectService.openExternalProjects(request.arguments.projects); // TODO: report errors return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.CloseExternalProject] = function (request) { _this.projectService.closeExternalProject(request.arguments.projectFileName); // TODO: report errors return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.SynchronizeProjectList] = function (request) { var result = _this.projectService.synchronizeProjectList(request.arguments.knownProjects); if (!result.some(function (p) { return p.projectErrors && p.projectErrors.length !== 0; })) { return _this.requiredResponse(result); } var converted = ts.map(result, function (p) { if (!p.projectErrors || p.projectErrors.length === 0) { return p; } return { info: p.info, changes: p.changes, files: p.files, projectErrors: _this.convertToDiagnosticsWithLinePosition(p.projectErrors, /*scriptInfo*/ undefined) }; }); return _this.requiredResponse(converted); }, _a[server.CommandNames.ApplyChangedToOpenFiles] = function (request) { _this.changeSeq++; _this.projectService.applyChangesInOpenFiles(request.arguments.openFiles, request.arguments.changedFiles, request.arguments.closedFiles); // TODO: report errors return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.Exit] = function () { _this.exit(); return _this.notRequired(); }, _a[server.CommandNames.Definition] = function (request) { return _this.requiredResponse(_this.getDefinition(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.DefinitionFull] = function (request) { return _this.requiredResponse(_this.getDefinition(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.DefinitionAndBoundSpan] = function (request) { return _this.requiredResponse(_this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.DefinitionAndBoundSpanFull] = function (request) { return _this.requiredResponse(_this.getDefinitionAndBoundSpan(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.TypeDefinition] = function (request) { return _this.requiredResponse(_this.getTypeDefinition(request.arguments)); }, _a[server.CommandNames.Implementation] = function (request) { return _this.requiredResponse(_this.getImplementation(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.ImplementationFull] = function (request) { return _this.requiredResponse(_this.getImplementation(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.References] = function (request) { return _this.requiredResponse(_this.getReferences(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.ReferencesFull] = function (request) { return _this.requiredResponse(_this.getReferences(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.Rename] = function (request) { return _this.requiredResponse(_this.getRenameLocations(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.RenameLocationsFull] = function (request) { return _this.requiredResponse(_this.getRenameLocations(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.RenameInfoFull] = function (request) { return _this.requiredResponse(_this.getRenameInfo(request.arguments)); }, _a[server.CommandNames.Open] = function (request) { _this.openClientFile(server.toNormalizedPath(request.arguments.file), request.arguments.fileContent, server.convertScriptKindName(request.arguments.scriptKindName), request.arguments.projectRootPath ? server.toNormalizedPath(request.arguments.projectRootPath) : undefined); return _this.notRequired(); }, _a[server.CommandNames.Quickinfo] = function (request) { return _this.requiredResponse(_this.getQuickInfoWorker(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.QuickinfoFull] = function (request) { return _this.requiredResponse(_this.getQuickInfoWorker(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.OutliningSpans] = function (request) { return _this.requiredResponse(_this.getOutliningSpans(request.arguments)); }, _a[server.CommandNames.TodoComments] = function (request) { return _this.requiredResponse(_this.getTodoComments(request.arguments)); }, _a[server.CommandNames.Indentation] = function (request) { return _this.requiredResponse(_this.getIndentation(request.arguments)); }, _a[server.CommandNames.NameOrDottedNameSpan] = function (request) { return _this.requiredResponse(_this.getNameOrDottedNameSpan(request.arguments)); }, _a[server.CommandNames.BreakpointStatement] = function (request) { return _this.requiredResponse(_this.getBreakpointStatement(request.arguments)); }, _a[server.CommandNames.BraceCompletion] = function (request) { return _this.requiredResponse(_this.isValidBraceCompletion(request.arguments)); }, _a[server.CommandNames.DocCommentTemplate] = function (request) { return _this.requiredResponse(_this.getDocCommentTemplate(request.arguments)); }, _a[server.CommandNames.GetSpanOfEnclosingComment] = function (request) { return _this.requiredResponse(_this.getSpanOfEnclosingComment(request.arguments)); }, _a[server.CommandNames.Format] = function (request) { return _this.requiredResponse(_this.getFormattingEditsForRange(request.arguments)); }, _a[server.CommandNames.Formatonkey] = function (request) { return _this.requiredResponse(_this.getFormattingEditsAfterKeystroke(request.arguments)); }, _a[server.CommandNames.FormatFull] = function (request) { return _this.requiredResponse(_this.getFormattingEditsForDocumentFull(request.arguments)); }, _a[server.CommandNames.FormatonkeyFull] = function (request) { return _this.requiredResponse(_this.getFormattingEditsAfterKeystrokeFull(request.arguments)); }, _a[server.CommandNames.FormatRangeFull] = function (request) { return _this.requiredResponse(_this.getFormattingEditsForRangeFull(request.arguments)); }, _a[server.CommandNames.Completions] = function (request) { return _this.requiredResponse(_this.getCompletions(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.CompletionsFull] = function (request) { return _this.requiredResponse(_this.getCompletions(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.CompletionDetails] = function (request) { return _this.requiredResponse(_this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.CompletionDetailsFull] = function (request) { return _this.requiredResponse(_this.getCompletionEntryDetails(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.CompileOnSaveAffectedFileList] = function (request) { return _this.requiredResponse(_this.getCompileOnSaveAffectedFileList(request.arguments)); }, _a[server.CommandNames.CompileOnSaveEmitFile] = function (request) { return _this.requiredResponse(_this.emitFile(request.arguments)); }, _a[server.CommandNames.SignatureHelp] = function (request) { return _this.requiredResponse(_this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.SignatureHelpFull] = function (request) { return _this.requiredResponse(_this.getSignatureHelpItems(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.CompilerOptionsDiagnosticsFull] = function (request) { return _this.requiredResponse(_this.getCompilerOptionsDiagnostics(request.arguments)); }, _a[server.CommandNames.EncodedSemanticClassificationsFull] = function (request) { return _this.requiredResponse(_this.getEncodedSemanticClassifications(request.arguments)); }, _a[server.CommandNames.Cleanup] = function () { _this.cleanup(); return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.SemanticDiagnosticsSync] = function (request) { return _this.requiredResponse(_this.getSemanticDiagnosticsSync(request.arguments)); }, _a[server.CommandNames.SyntacticDiagnosticsSync] = function (request) { return _this.requiredResponse(_this.getSyntacticDiagnosticsSync(request.arguments)); }, _a[server.CommandNames.Geterr] = function (request) { _this.errorCheck.startNew(function (next) { return _this.getDiagnostics(next, request.arguments.delay, request.arguments.files); }); return _this.notRequired(); }, _a[server.CommandNames.GeterrForProject] = function (request) { _this.errorCheck.startNew(function (next) { return _this.getDiagnosticsForProject(next, request.arguments.delay, request.arguments.file); }); return _this.notRequired(); }, _a[server.CommandNames.Change] = function (request) { _this.change(request.arguments); return _this.notRequired(); }, _a[server.CommandNames.Configure] = function (request) { _this.projectService.setHostConfiguration(request.arguments); _this.doOutput(/*info*/ undefined, server.CommandNames.Configure, request.seq, /*success*/ true); return _this.notRequired(); }, _a[server.CommandNames.Reload] = function (request) { _this.reload(request.arguments, request.seq); return _this.requiredResponse({ reloadFinished: true }); }, _a[server.CommandNames.Saveto] = function (request) { var savetoArgs = request.arguments; _this.saveToTmp(savetoArgs.file, savetoArgs.tmpfile); return _this.notRequired(); }, _a[server.CommandNames.Close] = function (request) { var closeArgs = request.arguments; _this.closeClientFile(closeArgs.file); return _this.notRequired(); }, _a[server.CommandNames.Navto] = function (request) { return _this.requiredResponse(_this.getNavigateToItems(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.NavtoFull] = function (request) { return _this.requiredResponse(_this.getNavigateToItems(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.Brace] = function (request) { return _this.requiredResponse(_this.getBraceMatching(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.BraceFull] = function (request) { return _this.requiredResponse(_this.getBraceMatching(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.NavBar] = function (request) { return _this.requiredResponse(_this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.NavBarFull] = function (request) { return _this.requiredResponse(_this.getNavigationBarItems(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.NavTree] = function (request) { return _this.requiredResponse(_this.getNavigationTree(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.NavTreeFull] = function (request) { return _this.requiredResponse(_this.getNavigationTree(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.Occurrences] = function (request) { return _this.requiredResponse(_this.getOccurrences(request.arguments)); }, _a[server.CommandNames.DocumentHighlights] = function (request) { return _this.requiredResponse(_this.getDocumentHighlights(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.DocumentHighlightsFull] = function (request) { return _this.requiredResponse(_this.getDocumentHighlights(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.CompilerOptionsForInferredProjects] = function (request) { _this.setCompilerOptionsForInferredProjects(request.arguments); return _this.requiredResponse(/*response*/ true); }, _a[server.CommandNames.ProjectInfo] = function (request) { return _this.requiredResponse(_this.getProjectInfo(request.arguments)); }, _a[server.CommandNames.ReloadProjects] = function () { _this.projectService.reloadProjects(); return _this.notRequired(); }, _a[server.CommandNames.GetCodeFixes] = function (request) { return _this.requiredResponse(_this.getCodeFixes(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.GetCodeFixesFull] = function (request) { return _this.requiredResponse(_this.getCodeFixes(request.arguments, /*simplifiedResult*/ false)); }, _a[server.CommandNames.ApplyCodeActionCommand] = function (request) { _this.applyCodeActionCommand(request.command, request.seq, request.arguments); return _this.notRequired(); // Response will come asynchronously. }, _a[server.CommandNames.GetSupportedCodeFixes] = function () { return _this.requiredResponse(_this.getSupportedCodeFixes()); }, _a[server.CommandNames.GetApplicableRefactors] = function (request) { return _this.requiredResponse(_this.getApplicableRefactors(request.arguments)); }, _a[server.CommandNames.GetEditsForRefactor] = function (request) { return _this.requiredResponse(_this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ true)); }, _a[server.CommandNames.GetEditsForRefactorFull] = function (request) { return _this.requiredResponse(_this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false)); }, _a)); this.host = opts.host; this.cancellationToken = opts.cancellationToken; this.typingsInstaller = opts.typingsInstaller; this.byteLength = opts.byteLength; this.hrtime = opts.hrtime; this.logger = opts.logger; this.canUseEvents = opts.canUseEvents; var throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = this.canUseEvents ? opts.eventHandler || (function (event) { return _this.defaultEventHandler(event); }) : undefined; var multistepOperationHost = { executeWithRequestId: function (requestId, action) { return _this.executeWithRequestId(requestId, action); }, getCurrentRequestId: function () { return _this.currentRequestId; }, getServerHost: function () { return _this.host; }, logError: function (err, cmd) { return _this.logError(err, cmd); }, sendRequestCompletedEvent: function (requestId) { return _this.sendRequestCompletedEvent(requestId); }, isCancellationRequested: function () { return _this.cancellationToken.isCancellationRequested(); } }; this.errorCheck = new MultistepOperation(multistepOperationHost); var settings = { host: this.host, logger: this.logger, cancellationToken: this.cancellationToken, useSingleInferredProject: opts.useSingleInferredProject, useInferredProjectPerProjectRoot: opts.useInferredProjectPerProjectRoot, typingsInstaller: this.typingsInstaller, throttleWaitMilliseconds: throttleWaitMilliseconds, eventHandler: this.eventHandler, globalPlugins: opts.globalPlugins, pluginProbeLocations: opts.pluginProbeLocations, allowLocalPluginLoads: opts.allowLocalPluginLoads }; this.projectService = new server.ProjectService(settings); this.gcTimer = new server.GcTimer(this.host, /*delay*/ 7000, this.logger); var _a; } Session.prototype.sendRequestCompletedEvent = function (requestId) { this.event({ request_seq: requestId }, "requestCompleted"); }; Session.prototype.defaultEventHandler = function (event) { switch (event.eventName) { case server.ProjectsUpdatedInBackgroundEvent: var openFiles = event.data.openFiles; this.projectsUpdatedInBackgroundEvent(openFiles); break; case server.ConfigFileDiagEvent: var _a = event.data, triggerFile = _a.triggerFile, configFile = _a.configFileName, diagnostics = _a.diagnostics; var bakedDiags = ts.map(diagnostics, function (diagnostic) { return formatConfigFileDiag(diagnostic, /*includeFileName*/ true); }); this.event({ triggerFile: triggerFile, configFile: configFile, diagnostics: bakedDiags }, "configFileDiag"); break; case server.ProjectLanguageServiceStateEvent: { var eventName = "projectLanguageServiceState"; this.event({ projectName: event.data.project.getProjectName(), languageServiceEnabled: event.data.languageServiceEnabled }, eventName); break; } case server.ProjectInfoTelemetryEvent: { var eventName = "telemetry"; this.event({ telemetryEventName: event.eventName, payload: event.data, }, eventName); break; } } }; Session.prototype.projectsUpdatedInBackgroundEvent = function (openFiles) { var _this = this; this.projectService.logger.info("got projects updated in background, updating diagnostics for " + openFiles); if (openFiles.length) { var checkList_1 = this.createCheckList(openFiles); // For now only queue error checking for open files. We can change this to include non open files as well this.errorCheck.startNew(function (next) { return _this.updateErrorCheck(next, checkList_1, 100, /*requireOpen*/ true); }); // Send project changed event this.event({ openFiles: openFiles }, "projectsUpdatedInBackground"); } }; Session.prototype.logError = function (err, cmd) { var msg = "Exception on executing command " + cmd; if (err.message) { msg += ":\n" + server.indent(err.message); if (err.stack) { msg += "\n" + server.indent(err.stack); } } this.logger.msg(msg, server.Msg.Err); }; Session.prototype.send = function (msg) { if (msg.type === "event" && !this.canUseEvents) { if (this.logger.hasLevel(server.LogLevel.verbose)) { this.logger.info("Session does not support events: ignored event: " + JSON.stringify(msg)); } return; } this.host.write(formatMessage(msg, this.logger, this.byteLength, this.host.newLine)); }; Session.prototype.event = function (body, eventName) { this.send(toEvent(eventName, body)); }; // For backwards-compatibility only. /** @deprecated */ Session.prototype.output = function (info, cmdName, reqSeq, errorMsg) { this.doOutput(info, cmdName, reqSeq, /*success*/ !errorMsg, errorMsg); }; Session.prototype.doOutput = function (info, cmdName, reqSeq, success, message) { var res = { seq: 0, type: "response", command: cmdName, request_seq: reqSeq, success: success, }; if (success) { res.body = info; } else { ts.Debug.assert(info === undefined); } if (message) { res.message = message; } this.send(res); }; Session.prototype.semanticCheck = function (file, project) { try { var diags = server.emptyArray; if (!isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { diags = project.getLanguageService().getSemanticDiagnostics(file); } var bakedDiags = diags.map(function (diag) { return formatDiag(file, project, diag); }); this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag"); } catch (err) { this.logError(err, "semantic check"); } }; Session.prototype.syntacticCheck = function (file, project) { try { var diags = project.getLanguageService().getSyntacticDiagnostics(file); if (diags) { var bakedDiags = diags.map(function (diag) { return formatDiag(file, project, diag); }); this.event({ file: file, diagnostics: bakedDiags }, "syntaxDiag"); } } catch (err) { this.logError(err, "syntactic check"); } }; Session.prototype.updateErrorCheck = function (next, checkList, ms, requireOpen) { var _this = this; if (requireOpen === void 0) { requireOpen = true; } var seq = this.changeSeq; var followMs = Math.min(ms, 200); var index = 0; var checkOne = function () { if (_this.changeSeq === seq) { var checkSpec_1 = checkList[index]; index++; if (checkSpec_1.project.containsFile(checkSpec_1.fileName, requireOpen)) { _this.syntacticCheck(checkSpec_1.fileName, checkSpec_1.project); if (_this.changeSeq === seq) { next.immediate(function () { _this.semanticCheck(checkSpec_1.fileName, checkSpec_1.project); if (checkList.length > index) { next.delay(followMs, checkOne); } }); } } } }; if (checkList.length > index && this.changeSeq === seq) { next.delay(ms, checkOne); } }; Session.prototype.cleanProjects = function (caption, projects) { if (!projects) { return; } this.logger.info("cleaning " + caption); for (var _i = 0, projects_1 = projects; _i < projects_1.length; _i++) { var p = projects_1[_i]; p.getLanguageService(/*ensureSynchronized*/ false).cleanupSemanticCache(); } }; Session.prototype.cleanup = function () { this.cleanProjects("inferred projects", this.projectService.inferredProjects); this.cleanProjects("configured projects", ts.arrayFrom(this.projectService.configuredProjects.values())); this.cleanProjects("external projects", this.projectService.externalProjects); if (this.host.gc) { this.logger.info("host.gc()"); this.host.gc(); } }; Session.prototype.getEncodedSemanticClassifications = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; return project.getLanguageService().getEncodedSemanticClassifications(file, args); }; Session.prototype.getProject = function (projectFileName) { return projectFileName && this.projectService.findProject(projectFileName); }; Session.prototype.getConfigFileAndProject = function (args) { var project = this.getProject(args.projectFileName); var file = server.toNormalizedPath(args.file); return { configFile: project && project.hasConfigFile(file) && file, project: project }; }; Session.prototype.getConfigFileDiagnostics = function (configFile, project, includeLinePosition) { var projectErrors = project.getAllProjectErrors(); var optionsErrors = project.getLanguageService().getCompilerOptionsDiagnostics(); var diagnosticsForConfigFile = ts.filter(ts.concatenate(projectErrors, optionsErrors), function (diagnostic) { return diagnostic.file && diagnostic.file.fileName === configFile; }); return includeLinePosition ? this.convertToDiagnosticsWithLinePositionFromDiagnosticFile(diagnosticsForConfigFile) : ts.map(diagnosticsForConfigFile, function (diagnostic) { return formatConfigFileDiag(diagnostic, /*includeFileName*/ false); }); }; Session.prototype.convertToDiagnosticsWithLinePositionFromDiagnosticFile = function (diagnostics) { var _this = this; return diagnostics.map(function (d) { return ({ message: ts.flattenDiagnosticMessageText(d.messageText, _this.host.newLine), start: d.start, length: d.length, category: ts.DiagnosticCategory[d.category].toLowerCase(), code: d.code, startLocation: d.file && convertToLocation(ts.getLineAndCharacterOfPosition(d.file, d.start)), endLocation: d.file && convertToLocation(ts.getLineAndCharacterOfPosition(d.file, d.start + d.length)) }); }); }; Session.prototype.getCompilerOptionsDiagnostics = function (args) { var project = this.getProject(args.projectFileName); // Get diagnostics that dont have associated file with them // The diagnostics which have file would be in config file and // would be reported as part of configFileDiagnostics return this.convertToDiagnosticsWithLinePosition(ts.filter(project.getLanguageService().getCompilerOptionsDiagnostics(), function (diagnostic) { return !diagnostic.file; }), /*scriptInfo*/ undefined); }; Session.prototype.convertToDiagnosticsWithLinePosition = function (diagnostics, scriptInfo) { var _this = this; return diagnostics.map(function (d) { return ({ message: ts.flattenDiagnosticMessageText(d.messageText, _this.host.newLine), start: d.start, length: d.length, category: ts.DiagnosticCategory[d.category].toLowerCase(), code: d.code, source: d.source, startLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start), endLocation: scriptInfo && scriptInfo.positionToLineOffset(d.start + d.length) }); }); }; Session.prototype.getDiagnosticsWorker = function (args, isSemantic, selector, includeLinePosition) { var _a = this.getFileAndProject(args), project = _a.project, file = _a.file; if (isSemantic && isDeclarationFileInJSOnlyNonConfiguredProject(project, file)) { return server.emptyArray; } var scriptInfo = project.getScriptInfoForNormalizedPath(file); var diagnostics = selector(project, file); return includeLinePosition ? this.convertToDiagnosticsWithLinePosition(diagnostics, scriptInfo) : diagnostics.map(function (d) { return formatDiag(file, project, d); }); }; Session.prototype.getDefinition = function (args, simplifiedResult) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var definitions = project.getLanguageService().getDefinitionAtPosition(file, position); if (!definitions) { return server.emptyArray; } if (simplifiedResult) { return this.mapDefinitionInfo(definitions, project); } else { return definitions; } }; Session.prototype.getDefinitionAndBoundSpan = function (args, simplifiedResult) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var scriptInfo = project.getScriptInfo(file); var definitionAndBoundSpan = project.getLanguageService().getDefinitionAndBoundSpan(file, position); if (!definitionAndBoundSpan || !definitionAndBoundSpan.definitions) { return { definitions: server.emptyArray, textSpan: undefined }; } if (simplifiedResult) { return { definitions: this.mapDefinitionInfo(definitionAndBoundSpan.definitions, project), textSpan: this.toLocationTextSpan(definitionAndBoundSpan.textSpan, scriptInfo) }; } return definitionAndBoundSpan; }; Session.prototype.mapDefinitionInfo = function (definitions, project) { var _this = this; return definitions.map(function (def) { return _this.toFileSpan(def.fileName, def.textSpan, project); }); }; Session.prototype.toFileSpan = function (fileName, textSpan, project) { var scriptInfo = project.getScriptInfo(fileName); return { file: fileName, start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)) }; }; Session.prototype.getTypeDefinition = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var definitions = project.getLanguageService().getTypeDefinitionAtPosition(file, position); if (!definitions) { return server.emptyArray; } return this.mapDefinitionInfo(definitions, project); }; Session.prototype.getImplementation = function (args, simplifiedResult) { var _this = this; var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var implementations = project.getLanguageService().getImplementationAtPosition(file, position); if (!implementations) { return server.emptyArray; } if (simplifiedResult) { return implementations.map(function (_a) { var fileName = _a.fileName, textSpan = _a.textSpan; return _this.toFileSpan(fileName, textSpan, project); }); } else { return implementations; } }; Session.prototype.getOccurrences = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var occurrences = project.getLanguageService().getOccurrencesAtPosition(file, position); if (!occurrences) { return server.emptyArray; } return occurrences.map(function (occurrence) { var fileName = occurrence.fileName, isWriteAccess = occurrence.isWriteAccess, textSpan = occurrence.textSpan, isInString = occurrence.isInString; var scriptInfo = project.getScriptInfo(fileName); var result = { start: scriptInfo.positionToLineOffset(textSpan.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)), file: fileName, isWriteAccess: isWriteAccess, }; // no need to serialize the property if it is not true if (isInString) { result.isInString = isInString; } return result; }); }; Session.prototype.getSyntacticDiagnosticsSync = function (args) { var configFile = this.getConfigFileAndProject(args).configFile; if (configFile) { // all the config file errors are reported as part of semantic check so nothing to report here return server.emptyArray; } return this.getDiagnosticsWorker(args, /*isSemantic*/ false, function (project, file) { return project.getLanguageService().getSyntacticDiagnostics(file); }, args.includeLinePosition); }; Session.prototype.getSemanticDiagnosticsSync = function (args) { var _a = this.getConfigFileAndProject(args), configFile = _a.configFile, project = _a.project; if (configFile) { return this.getConfigFileDiagnostics(configFile, project, args.includeLinePosition); } return this.getDiagnosticsWorker(args, /*isSemantic*/ true, function (project, file) { return project.getLanguageService().getSemanticDiagnostics(file); }, args.includeLinePosition); }; Session.prototype.getDocumentHighlights = function (args, simplifiedResult) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); var documentHighlights = project.getLanguageService().getDocumentHighlights(file, position, args.filesToSearch); if (!documentHighlights) { return server.emptyArray; } if (simplifiedResult) { return documentHighlights.map(convertToDocumentHighlightsItem); } else { return documentHighlights; } function convertToDocumentHighlightsItem(documentHighlights) { var fileName = documentHighlights.fileName, highlightSpans = documentHighlights.highlightSpans; var scriptInfo = project.getScriptInfo(fileName); return { file: fileName, highlightSpans: highlightSpans.map(convertHighlightSpan) }; function convertHighlightSpan(highlightSpan) { var textSpan = highlightSpan.textSpan, kind = highlightSpan.kind; var start = scriptInfo.positionToLineOffset(textSpan.start); var end = scriptInfo.positionToLineOffset(ts.textSpanEnd(textSpan)); return { start: start, end: end, kind: kind }; } } }; Session.prototype.setCompilerOptionsForInferredProjects = function (args) { this.projectService.setCompilerOptionsForInferredProjects(args.options, args.projectRootPath); }; Session.prototype.getProjectInfo = function (args) { return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList, /*excludeConfigFiles*/ false); }; Session.prototype.getProjectInfoWorker = function (uncheckedFileName, projectFileName, needFileNameList, excludeConfigFiles) { var project = this.getFileAndProjectWorker(uncheckedFileName, projectFileName).project; project.updateGraph(); var projectInfo = { configFileName: project.getProjectName(), languageServiceDisabled: !project.languageServiceEnabled, fileNames: needFileNameList ? project.getFileNames(/*excludeFilesFromExternalLibraries*/ false, excludeConfigFiles) : undefined }; return projectInfo; }; Session.prototype.getRenameInfo = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var position = this.getPositionInFile(args, file); return project.getLanguageService().getRenameInfo(file, position); }; Session.prototype.getProjects = function (args) { var projects; if (args.projectFileName) { var project = this.getProject(args.projectFileName); if (project) { projects = [project]; } } else { var scriptInfo = this.projectService.getScriptInfo(args.file); projects = scriptInfo.containingProjects; } // filter handles case when 'projects' is undefined projects = ts.filter(projects, function (p) { return p.languageServiceEnabled; }); if (!projects || !projects.length) { return server.Errors.ThrowNoProject(); } return projects; }; Session.prototype.getDefaultProject = function (args) { if (args.projectFileName) { var project = this.getProject(args.projectFileName); if (project) { return project; } } var info = this.projectService.getScriptInfo(args.file); return info.getDefaultProject(); }; Session.prototype.getRenameLocations = function (args, simplifiedResult) { var file = server.toNormalizedPath(args.file); var position = this.getPositionInFile(args, file); var projects = this.getProjects(args); if (simplifiedResult) { var defaultProject = this.getDefaultProject(args); // The rename info should be the same for every project var renameInfo = defaultProject.getLanguageService().getRenameInfo(file, position); if (!renameInfo) { return undefined; } if (!renameInfo.canRename) { return { info: renameInfo, locs: server.emptyArray }; } var fileSpans = server.combineProjectOutput(projects, function (project) { var renameLocations = project.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments); if (!renameLocations) { return server.emptyArray; } return renameLocations.map(function (location) { var locationScriptInfo = project.getScriptInfo(location.fileName); return { file: location.fileName, start: locationScriptInfo.positionToLineOffset(location.textSpan.start), end: locationScriptInfo.positionToLineOffset(ts.textSpanEnd(location.textSpan)), }; }); }, compareRenameLocation, function (a, b) { return a.file === b.file && a.start.line === b.start.line && a.start.offset === b.start.offset; }); var locs = []; for (var _i = 0, fileSpans_1 = fileSpans; _i < fileSpans_1.length; _i++) { var cur = fileSpans_1[_i]; var curFileAccum = void 0; if (locs.length > 0) { curFileAccum = locs[locs.length - 1]; if (curFileAccum.file !== cur.file) { curFileAccum = undefined; } } if (!curFileAccum) { curFileAccum = { file: cur.file, locs: [] }; locs.push(curFileAccum); } curFileAccum.locs.push({ start: cur.start, end: cur.end }); } return { info: renameInfo, locs: locs }; } else { return server.combineProjectOutput(projects, function (p) { return p.getLanguageService().findRenameLocations(file, position, args.findInStrings, args.findInComments); }, /*comparer*/ undefined, renameLocationIsEqualTo); } function renameLocationIsEqualTo(a, b) { if (a === b) { return true; } if (!a || !b) { return false; } return a.fileName === b.fileName && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length; } function compareRenameLocation(a, b) { if (a.file < b.file) { return -1; } else if (a.file > b.file) { return 1; } else { // reverse sort assuming no overlap if (a.start.line < b.start.line) { return 1; } else if (a.start.line > b.start.line) { return -1; } else { return b.start.offset - a.start.offset; } } } }; Session.prototype.getReferences = function (args, simplifiedResult) { var file = server.toNormalizedPath(args.file); var projects = this.getProjects(args); var defaultProject = this.getDefaultProject(args); var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = this.getPosition(args, scriptInfo); if (simplifiedResult) { var nameInfo = defaultProject.getLanguageService().getQuickInfoAtPosition(file, position); if (!nameInfo) { return undefined; } var displayString = ts.displayPartsToString(nameInfo.displayParts); var nameSpan = nameInfo.textSpan; var nameColStart = scriptInfo.positionToLineOffset(nameSpan.start).offset; var nameText = scriptInfo.getSnapshot().getText(nameSpan.start, ts.textSpanEnd(nameSpan)); var refs = server.combineProjectOutput(projects, function (project) { var references = project.getLanguageService().getReferencesAtPosition(file, position); if (!references) { return server.emptyArray; } return references.map(function (ref) { var refScriptInfo = project.getScriptInfo(ref.fileName); var start = refScriptInfo.positionToLineOffset(ref.textSpan.start); var refLineSpan = refScriptInfo.lineToTextSpan(start.line - 1); var lineText = refScriptInfo.getSnapshot().getText(refLineSpan.start, ts.textSpanEnd(refLineSpan)).replace(/\r|\n/g, ""); return { file: ref.fileName, start: start, lineText: lineText, end: refScriptInfo.positionToLineOffset(ts.textSpanEnd(ref.textSpan)), isWriteAccess: ref.isWriteAccess, isDefinition: ref.isDefinition }; }); }, compareFileStart, areReferencesResponseItemsForTheSameLocation); return { refs: refs, symbolName: nameText, symbolStartOffset: nameColStart, symbolDisplayString: displayString }; } else { return server.combineProjectOutput(projects, function (project) { return project.getLanguageService().findReferences(file, position); }, /*comparer*/ undefined, ts.equateValues); } function areReferencesResponseItemsForTheSameLocation(a, b) { if (a && b) { return a.file === b.file && a.start === b.start && a.end === b.end; } return false; } }; /** * @param fileName is the name of the file to be opened * @param fileContent is a version of the file content that is known to be more up to date than the one on disk */ Session.prototype.openClientFile = function (fileName, fileContent, scriptKind, projectRootPath) { this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath); }; Session.prototype.getPosition = function (args, scriptInfo) { return args.position !== undefined ? args.position : scriptInfo.lineOffsetToPosition(args.line, args.offset); }; Session.prototype.getPositionInFile = function (args, file) { var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); return this.getPosition(args, scriptInfo); }; Session.prototype.getFileAndProject = function (args) { return this.getFileAndProjectWorker(args.file, args.projectFileName); }; Session.prototype.getFileAndLanguageServiceForSyntacticOperation = function (args) { // Since this is syntactic operation, there should always be project for the file // we wouldnt have to ensure project but rather throw if we dont get project var file = server.toNormalizedPath(args.file); var project = this.getProject(args.projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ false); if (!project) { return server.Errors.ThrowNoProject(); } return { file: file, languageService: project.getLanguageService(/*ensureSynchronized*/ false) }; }; Session.prototype.getFileAndProjectWorker = function (uncheckedFileName, projectFileName) { var file = server.toNormalizedPath(uncheckedFileName); var project = this.getProject(projectFileName) || this.projectService.getDefaultProjectForFile(file, /*ensureProject*/ true); return { file: file, project: project }; }; Session.prototype.getOutliningSpans = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; return languageService.getOutliningSpans(file); }; Session.prototype.getTodoComments = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; return project.getLanguageService().getTodoComments(file, args.descriptors); }; Session.prototype.getDocCommentTemplate = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var position = this.getPositionInFile(args, file); return languageService.getDocCommentTemplateAtPosition(file, position); }; Session.prototype.getSpanOfEnclosingComment = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var onlyMultiLine = args.onlyMultiLine; var position = this.getPositionInFile(args, file); return languageService.getSpanOfEnclosingComment(file, position, onlyMultiLine); }; Session.prototype.getIndentation = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var position = this.getPositionInFile(args, file); var options = args.options ? server.convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); var indentation = languageService.getIndentationAtPosition(file, position, options); return { position: position, indentation: indentation }; }; Session.prototype.getBreakpointStatement = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var position = this.getPositionInFile(args, file); return languageService.getBreakpointStatementAtPosition(file, position); }; Session.prototype.getNameOrDottedNameSpan = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var position = this.getPositionInFile(args, file); return languageService.getNameOrDottedNameSpan(file, position, position); }; Session.prototype.isValidBraceCompletion = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var position = this.getPositionInFile(args, file); return languageService.isValidBraceCompletionAtPosition(file, position, args.openingBrace.charCodeAt(0)); }; Session.prototype.getQuickInfoWorker = function (args, simplifiedResult) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var quickInfo = project.getLanguageService().getQuickInfoAtPosition(file, this.getPosition(args, scriptInfo)); if (!quickInfo) { return undefined; } if (simplifiedResult) { var displayString = ts.displayPartsToString(quickInfo.displayParts); var docString = ts.displayPartsToString(quickInfo.documentation); return { kind: quickInfo.kind, kindModifiers: quickInfo.kindModifiers, start: scriptInfo.positionToLineOffset(quickInfo.textSpan.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(quickInfo.textSpan)), displayString: displayString, documentation: docString, tags: quickInfo.tags || [] }; } else { return quickInfo; } }; Session.prototype.getFormattingEditsForRange = function (args) { var _this = this; var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var startPosition = scriptInfo.lineOffsetToPosition(args.line, args.offset); var endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); // TODO: avoid duplicate code (with formatonkey) var edits = languageService.getFormattingEditsForRange(file, startPosition, endPosition, this.projectService.getFormatCodeOptions(file)); if (!edits) { return undefined; } return edits.map(function (edit) { return _this.convertTextChangeToCodeEdit(edit, scriptInfo); }); }; Session.prototype.getFormattingEditsForRangeFull = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var options = args.options ? server.convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return languageService.getFormattingEditsForRange(file, args.position, args.endPosition, options); }; Session.prototype.getFormattingEditsForDocumentFull = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var options = args.options ? server.convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return languageService.getFormattingEditsForDocument(file, options); }; Session.prototype.getFormattingEditsAfterKeystrokeFull = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var options = args.options ? server.convertFormatOptions(args.options) : this.projectService.getFormatCodeOptions(file); return languageService.getFormattingEditsAfterKeystroke(file, args.position, args.key, options); }; Session.prototype.getFormattingEditsAfterKeystroke = function (args) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = scriptInfo.lineOffsetToPosition(args.line, args.offset); var formatOptions = this.projectService.getFormatCodeOptions(file); var edits = languageService.getFormattingEditsAfterKeystroke(file, position, args.key, formatOptions); // Check whether we should auto-indent. This will be when // the position is on a line containing only whitespace. // This should leave the edits returned from // getFormattingEditsAfterKeystroke either empty or pertaining // only to the previous line. If all this is true, then // add edits necessary to properly indent the current line. if ((args.key === "\n") && ((!edits) || (edits.length === 0) || allEditsBeforePos(edits, position))) { var _b = scriptInfo.getLineInfo(args.line), lineText = _b.lineText, absolutePosition = _b.absolutePosition; if (lineText && lineText.search("\\S") < 0) { var preferredIndent = languageService.getIndentationAtPosition(file, position, formatOptions); var hasIndent = 0; var i = void 0, len = void 0; for (i = 0, len = lineText.length; i < len; i++) { if (lineText.charAt(i) === " ") { hasIndent++; } else if (lineText.charAt(i) === "\t") { hasIndent += formatOptions.tabSize; } else { break; } } // i points to the first non whitespace character if (preferredIndent !== hasIndent) { var firstNoWhiteSpacePosition = absolutePosition + i; edits.push({ span: ts.createTextSpanFromBounds(absolutePosition, firstNoWhiteSpacePosition), newText: ts.formatting.getIndentationString(preferredIndent, formatOptions) }); } } } if (!edits) { return undefined; } return edits.map(function (edit) { return { start: scriptInfo.positionToLineOffset(edit.span.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(edit.span)), newText: edit.newText ? edit.newText : "" }; }); }; Session.prototype.getCompletions = function (args, simplifiedResult) { var _this = this; var prefix = args.prefix || ""; var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = this.getPosition(args, scriptInfo); var completions = project.getLanguageService().getCompletionsAtPosition(file, position, args); if (simplifiedResult) { return ts.mapDefined(completions && completions.entries, function (entry) { if (completions.isMemberCompletion || ts.startsWith(entry.name.toLowerCase(), prefix.toLowerCase())) { var name = entry.name, kind = entry.kind, kindModifiers = entry.kindModifiers, sortText = entry.sortText, replacementSpan = entry.replacementSpan, hasAction = entry.hasAction, source = entry.source, isRecommended = entry.isRecommended; var convertedSpan = replacementSpan ? _this.toLocationTextSpan(replacementSpan, scriptInfo) : undefined; // Use `hasAction || undefined` to avoid serializing `false`. return { name: name, kind: kind, kindModifiers: kindModifiers, sortText: sortText, replacementSpan: convertedSpan, hasAction: hasAction || undefined, source: source, isRecommended: isRecommended }; } }).sort(function (a, b) { return ts.compareStringsCaseSensitiveUI(a.name, b.name); }); } else { return completions; } }; Session.prototype.getCompletionEntryDetails = function (args, simplifiedResult) { var _this = this; var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = this.getPosition(args, scriptInfo); var formattingOptions = project.projectService.getFormatCodeOptions(file); var result = ts.mapDefined(args.entryNames, function (entryName) { var _a = typeof entryName === "string" ? { name: entryName, source: undefined } : entryName, name = _a.name, source = _a.source; return project.getLanguageService().getCompletionEntryDetails(file, position, name, formattingOptions, source); }); return simplifiedResult ? result.map(function (details) { return (__assign({}, details, { codeActions: ts.map(details.codeActions, function (action) { return _this.mapCodeAction(action, scriptInfo); }) })); }) : result; }; Session.prototype.getCompileOnSaveAffectedFileList = function (args) { var info = this.projectService.getScriptInfoEnsuringProjectsUptoDate(args.file); if (!info) { return server.emptyArray; } var result = []; // if specified a project, we only return affected file list in this project var projectsToSearch = args.projectFileName ? [this.projectService.findProject(args.projectFileName)] : info.containingProjects; for (var _i = 0, projectsToSearch_1 = projectsToSearch; _i < projectsToSearch_1.length; _i++) { var project = projectsToSearch_1[_i]; if (project.compileOnSaveEnabled && project.languageServiceEnabled && !project.getCompilationSettings().noEmit) { result.push({ projectFileName: project.getProjectName(), fileNames: project.getCompileOnSaveAffectedFileList(info), projectUsesOutFile: !!project.getCompilationSettings().outFile || !!project.getCompilationSettings().out }); } } return result; }; Session.prototype.emitFile = function (args) { var _this = this; var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; if (!project) { server.Errors.ThrowNoProject(); } if (!project.languageServiceEnabled) { return false; } var scriptInfo = project.getScriptInfo(file); return project.emitFile(scriptInfo, function (path, data, writeByteOrderMark) { return _this.host.writeFile(path, data, writeByteOrderMark); }); }; Session.prototype.getSignatureHelpItems = function (args, simplifiedResult) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = this.getPosition(args, scriptInfo); var helpItems = project.getLanguageService().getSignatureHelpItems(file, position); if (!helpItems) { return undefined; } if (simplifiedResult) { var span_16 = helpItems.applicableSpan; return { items: helpItems.items, applicableSpan: { start: scriptInfo.positionToLineOffset(span_16.start), end: scriptInfo.positionToLineOffset(span_16.start + span_16.length) }, selectedItemIndex: helpItems.selectedItemIndex, argumentIndex: helpItems.argumentIndex, argumentCount: helpItems.argumentCount, }; } else { return helpItems; } }; Session.prototype.createCheckList = function (fileNames, defaultProject) { var _this = this; return ts.mapDefined(fileNames, function (uncheckedFileName) { var fileName = server.toNormalizedPath(uncheckedFileName); var project = defaultProject || _this.projectService.getDefaultProjectForFile(fileName, /*ensureProject*/ false); return project && { fileName: fileName, project: project }; }); }; Session.prototype.getDiagnostics = function (next, delay, fileNames) { var checkList = this.createCheckList(fileNames); if (checkList.length > 0) { this.updateErrorCheck(next, checkList, delay); } }; Session.prototype.change = function (args) { var scriptInfo = this.projectService.getScriptInfo(args.file); ts.Debug.assert(!!scriptInfo); var start = scriptInfo.lineOffsetToPosition(args.line, args.offset); var end = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); if (start >= 0) { this.changeSeq++; this.projectService.applyChangesToFile(scriptInfo, [{ span: { start: start, length: end - start }, newText: args.insertString }]); } }; Session.prototype.reload = function (args, reqSeq) { var file = server.toNormalizedPath(args.file); var tempFileName = args.tmpfile && server.toNormalizedPath(args.tmpfile); var info = this.projectService.getScriptInfoForNormalizedPath(file); if (info) { this.changeSeq++; // make sure no changes happen before this one is finished if (info.reloadFromFile(tempFileName)) { this.doOutput(/*info*/ undefined, server.CommandNames.Reload, reqSeq, /*success*/ true); } } }; Session.prototype.saveToTmp = function (fileName, tempFileName) { var scriptInfo = this.projectService.getScriptInfo(fileName); if (scriptInfo) { scriptInfo.saveTo(tempFileName); } }; Session.prototype.closeClientFile = function (fileName) { if (!fileName) { return; } var file = ts.normalizePath(fileName); this.projectService.closeClientFile(file); }; Session.prototype.mapLocationNavigationBarItems = function (items, scriptInfo) { var _this = this; return ts.map(items, function (item) { return ({ text: item.text, kind: item.kind, kindModifiers: item.kindModifiers, spans: item.spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); }), childItems: _this.mapLocationNavigationBarItems(item.childItems, scriptInfo), indent: item.indent }); }); }; Session.prototype.getNavigationBarItems = function (args, simplifiedResult) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var items = languageService.getNavigationBarItems(file); return !items ? undefined : simplifiedResult ? this.mapLocationNavigationBarItems(items, this.projectService.getScriptInfoForNormalizedPath(file)) : items; }; Session.prototype.toLocationNavigationTree = function (tree, scriptInfo) { var _this = this; return { text: tree.text, kind: tree.kind, kindModifiers: tree.kindModifiers, spans: tree.spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); }), childItems: ts.map(tree.childItems, function (item) { return _this.toLocationNavigationTree(item, scriptInfo); }) }; }; Session.prototype.toLocationTextSpan = function (span, scriptInfo) { return { start: scriptInfo.positionToLineOffset(span.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(span)) }; }; Session.prototype.getNavigationTree = function (args, simplifiedResult) { var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var tree = languageService.getNavigationTree(file); return !tree ? undefined : simplifiedResult ? this.toLocationNavigationTree(tree, this.projectService.getScriptInfoForNormalizedPath(file)) : tree; }; Session.prototype.getNavigateToItems = function (args, simplifiedResult) { var projects = this.getProjects(args); var fileName = args.currentFileOnly ? args.file && ts.normalizeSlashes(args.file) : undefined; if (simplifiedResult) { return server.combineProjectOutput(projects, function (project) { var navItems = project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()); if (!navItems) { return server.emptyArray; } return navItems.map(function (navItem) { var scriptInfo = project.getScriptInfo(navItem.fileName); var bakedItem = { name: navItem.name, kind: navItem.kind, file: navItem.fileName, start: scriptInfo.positionToLineOffset(navItem.textSpan.start), end: scriptInfo.positionToLineOffset(ts.textSpanEnd(navItem.textSpan)) }; if (navItem.kindModifiers && (navItem.kindModifiers !== "")) { bakedItem.kindModifiers = navItem.kindModifiers; } if (navItem.matchKind !== "none") { bakedItem.matchKind = navItem.matchKind; } if (navItem.containerName && (navItem.containerName.length > 0)) { bakedItem.containerName = navItem.containerName; } if (navItem.containerKind && (navItem.containerKind.length > 0)) { bakedItem.containerKind = navItem.containerKind; } return bakedItem; }); }, /*comparer*/ undefined, areNavToItemsForTheSameLocation); } else { return server.combineProjectOutput(projects, function (project) { return project.getLanguageService().getNavigateToItems(args.searchValue, args.maxResultCount, fileName, /*excludeDts*/ project.isNonTsProject()); }, /*comparer*/ undefined, navigateToItemIsEqualTo); } function navigateToItemIsEqualTo(a, b) { if (a === b) { return true; } if (!a || !b) { return false; } return a.containerKind === b.containerKind && a.containerName === b.containerName && a.fileName === b.fileName && a.isCaseSensitive === b.isCaseSensitive && a.kind === b.kind && a.kindModifiers === b.containerName && a.matchKind === b.matchKind && a.name === b.name && a.textSpan.start === b.textSpan.start && a.textSpan.length === b.textSpan.length; } function areNavToItemsForTheSameLocation(a, b) { if (a && b) { return a.file === b.file && a.start === b.start && a.end === b.end; } return false; } }; Session.prototype.getSupportedCodeFixes = function () { return ts.getSupportedCodeFixes(); }; Session.prototype.isLocation = function (locationOrSpan) { return locationOrSpan.line !== undefined; }; Session.prototype.extractPositionAndRange = function (args, scriptInfo) { var position = undefined; var textRange; if (this.isLocation(args)) { position = getPosition(args); } else { var _a = this.getStartAndEndPosition(args, scriptInfo), startPosition = _a.startPosition, endPosition = _a.endPosition; textRange = { pos: startPosition, end: endPosition }; } return { position: position, textRange: textRange }; function getPosition(loc) { return loc.position !== undefined ? loc.position : scriptInfo.lineOffsetToPosition(loc.line, loc.offset); } }; Session.prototype.getApplicableRefactors = function (args) { var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = project.getScriptInfoForNormalizedPath(file); var _b = this.extractPositionAndRange(args, scriptInfo), position = _b.position, textRange = _b.textRange; return project.getLanguageService().getApplicableRefactors(file, position || textRange); }; Session.prototype.getEditsForRefactor = function (args, simplifiedResult) { var _this = this; var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = project.getScriptInfoForNormalizedPath(file); var _b = this.extractPositionAndRange(args, scriptInfo), position = _b.position, textRange = _b.textRange; var result = project.getLanguageService().getEditsForRefactor(file, this.projectService.getFormatCodeOptions(file), position || textRange, args.refactor, args.action); if (result === undefined) { return { edits: [] }; } if (simplifiedResult) { var renameFilename = result.renameFilename, renameLocation = result.renameLocation, edits = result.edits; var mappedRenameLocation = void 0; if (renameFilename !== undefined && renameLocation !== undefined) { var renameScriptInfo = project.getScriptInfoForNormalizedPath(server.toNormalizedPath(renameFilename)); var snapshot = renameScriptInfo.getSnapshot(); var oldText = snapshot.getText(0, snapshot.getLength()); mappedRenameLocation = getLocationInNewDocument(oldText, renameFilename, renameLocation, edits); } return { renameLocation: mappedRenameLocation, renameFilename: renameFilename, edits: edits.map(function (change) { return _this.mapTextChangesToCodeEdits(project, change); }) }; } else { return result; } }; Session.prototype.getCodeFixes = function (args, simplifiedResult) { var _this = this; if (args.errorCodes.length === 0) { return undefined; } var _a = this.getFileAndProject(args), file = _a.file, project = _a.project; var scriptInfo = project.getScriptInfoForNormalizedPath(file); var _b = this.getStartAndEndPosition(args, scriptInfo), startPosition = _b.startPosition, endPosition = _b.endPosition; var formatOptions = this.projectService.getFormatCodeOptions(file); var codeActions = project.getLanguageService().getCodeFixesAtPosition(file, startPosition, endPosition, args.errorCodes, formatOptions); if (!codeActions) { return undefined; } if (simplifiedResult) { return codeActions.map(function (codeAction) { return _this.mapCodeAction(codeAction, scriptInfo); }); } else { return codeActions; } }; Session.prototype.applyCodeActionCommand = function (commandName, requestSeq, args) { var _this = this; var commands = args.command; // They should be sending back the command we sent them. var _loop_11 = function (command) { var project = this_1.getFileAndProject(command).project; var output = function (success, message) { return _this.doOutput({}, commandName, requestSeq, success, message); }; project.getLanguageService().applyCodeActionCommand(command).then(function (result) { output(/*success*/ true, result.successMessage); }, function (error) { output(/*success*/ false, error); }); }; var this_1 = this; for (var _i = 0, _a = ts.toArray(commands); _i < _a.length; _i++) { var command = _a[_i]; _loop_11(command); } }; Session.prototype.getStartAndEndPosition = function (args, scriptInfo) { var startPosition = undefined, endPosition = undefined; if (args.startPosition !== undefined) { startPosition = args.startPosition; } else { startPosition = scriptInfo.lineOffsetToPosition(args.startLine, args.startOffset); // save the result so we don't always recompute args.startPosition = startPosition; } if (args.endPosition !== undefined) { endPosition = args.endPosition; } else { endPosition = scriptInfo.lineOffsetToPosition(args.endLine, args.endOffset); args.endPosition = endPosition; } return { startPosition: startPosition, endPosition: endPosition }; }; Session.prototype.mapCodeAction = function (_a, scriptInfo) { var _this = this; var description = _a.description, unmappedChanges = _a.changes, commands = _a.commands; var changes = unmappedChanges.map(function (change) { return ({ fileName: change.fileName, textChanges: change.textChanges.map(function (textChange) { return _this.convertTextChangeToCodeEdit(textChange, scriptInfo); }) }); }); return { description: description, changes: changes, commands: commands }; }; Session.prototype.mapTextChangesToCodeEdits = function (project, textChanges) { var _this = this; var scriptInfo = project.getScriptInfoForNormalizedPath(server.toNormalizedPath(textChanges.fileName)); return { fileName: textChanges.fileName, textChanges: textChanges.textChanges.map(function (textChange) { return _this.convertTextChangeToCodeEdit(textChange, scriptInfo); }) }; }; Session.prototype.convertTextChangeToCodeEdit = function (change, scriptInfo) { return { start: scriptInfo.positionToLineOffset(change.span.start), end: scriptInfo.positionToLineOffset(change.span.start + change.span.length), newText: change.newText ? change.newText : "" }; }; Session.prototype.getBraceMatching = function (args, simplifiedResult) { var _this = this; var _a = this.getFileAndLanguageServiceForSyntacticOperation(args), file = _a.file, languageService = _a.languageService; var scriptInfo = this.projectService.getScriptInfoForNormalizedPath(file); var position = this.getPosition(args, scriptInfo); var spans = languageService.getBraceMatchingAtPosition(file, position); return !spans ? undefined : simplifiedResult ? spans.map(function (span) { return _this.toLocationTextSpan(span, scriptInfo); }) : spans; }; Session.prototype.getDiagnosticsForProject = function (next, delay, fileName) { var _a = this.getProjectInfoWorker(fileName, /*projectFileName*/ undefined, /*needFileNameList*/ true, /*excludeConfigFiles*/ true), fileNames = _a.fileNames, languageServiceDisabled = _a.languageServiceDisabled; if (languageServiceDisabled) { return; } // No need to analyze lib.d.ts var fileNamesInProject = fileNames.filter(function (value) { return !ts.stringContains(value, "lib.d.ts"); }); if (fileNamesInProject.length === 0) { return; } // Sort the file name list to make the recently touched files come first var highPriorityFiles = []; var mediumPriorityFiles = []; var lowPriorityFiles = []; var veryLowPriorityFiles = []; var normalizedFileName = server.toNormalizedPath(fileName); var project = this.projectService.getDefaultProjectForFile(normalizedFileName, /*ensureProject*/ true); for (var _i = 0, fileNamesInProject_1 = fileNamesInProject; _i < fileNamesInProject_1.length; _i++) { var fileNameInProject = fileNamesInProject_1[_i]; if (this.getCanonicalFileName(fileNameInProject) === this.getCanonicalFileName(fileName)) { highPriorityFiles.push(fileNameInProject); } else { var info = this.projectService.getScriptInfo(fileNameInProject); if (!info.isScriptOpen()) { if (ts.fileExtensionIs(fileNameInProject, ".d.ts" /* Dts */)) { veryLowPriorityFiles.push(fileNameInProject); } else { lowPriorityFiles.push(fileNameInProject); } } else { mediumPriorityFiles.push(fileNameInProject); } } } var sortedFiles = highPriorityFiles.concat(mediumPriorityFiles, lowPriorityFiles, veryLowPriorityFiles); var checkList = sortedFiles.map(function (fileName) { return ({ fileName: fileName, project: project }); }); // Project level error analysis runs on background files too, therefore // doesn't require the file to be opened this.updateErrorCheck(next, checkList, delay, /*requireOpen*/ false); }; Session.prototype.getCanonicalFileName = function (fileName) { var name = this.host.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); return ts.normalizePath(name); }; Session.prototype.exit = function () { }; Session.prototype.notRequired = function () { return { responseRequired: false }; }; Session.prototype.requiredResponse = function (response) { return { response: response, responseRequired: true }; }; Session.prototype.addProtocolHandler = function (command, handler) { if (this.handlers.has(command)) { throw new Error("Protocol handler already exists for command \"" + command + "\""); } this.handlers.set(command, handler); }; Session.prototype.setCurrentRequest = function (requestId) { ts.Debug.assert(this.currentRequestId === undefined); this.currentRequestId = requestId; this.cancellationToken.setRequest(requestId); }; Session.prototype.resetCurrentRequest = function (requestId) { ts.Debug.assert(this.currentRequestId === requestId); this.currentRequestId = undefined; this.cancellationToken.resetRequest(requestId); }; Session.prototype.executeWithRequestId = function (requestId, f) { try { this.setCurrentRequest(requestId); return f(); } finally { this.resetCurrentRequest(requestId); } }; Session.prototype.executeCommand = function (request) { var handler = this.handlers.get(request.command); if (handler) { return this.executeWithRequestId(request.seq, function () { return handler(request); }); } else { this.logger.msg("Unrecognized JSON command:" + server.stringifyIndented(request), server.Msg.Err); this.doOutput(/*info*/ undefined, server.CommandNames.Unknown, request.seq, /*success*/ false, "Unrecognized JSON command: " + request.command); return { responseRequired: false }; } }; Session.prototype.onMessage = function (message) { this.gcTimer.scheduleCollect(); var start; if (this.logger.hasLevel(server.LogLevel.requestTime)) { start = this.hrtime(); if (this.logger.hasLevel(server.LogLevel.verbose)) { this.logger.info("request:" + server.indent(message)); } } var request; try { request = JSON.parse(message); var _a = this.executeCommand(request), response = _a.response, responseRequired = _a.responseRequired; if (this.logger.hasLevel(server.LogLevel.requestTime)) { var elapsedTime = hrTimeToMilliseconds(this.hrtime(start)).toFixed(4); if (responseRequired) { this.logger.perftrc(request.seq + "::" + request.command + ": elapsed time (in milliseconds) " + elapsedTime); } else { this.logger.perftrc(request.seq + "::" + request.command + ": async elapsed time (in milliseconds) " + elapsedTime); } } if (response) { this.doOutput(response, request.command, request.seq, /*success*/ true); } else if (responseRequired) { this.doOutput(/*info*/ undefined, request.command, request.seq, /*success*/ false, "No content available."); } } catch (err) { if (err instanceof ts.OperationCanceledException) { // Handle cancellation exceptions this.doOutput({ canceled: true }, request.command, request.seq, /*success*/ true); return; } this.logError(err, message); this.doOutput( /*info*/ undefined, request ? request.command : server.CommandNames.Unknown, request ? request.seq : 0, /*success*/ false, "Error processing request. " + err.message + "\n" + err.stack); } }; return Session; }()); server.Session = Session; /* @internal */ // Exported only for tests function getLocationInNewDocument(oldText, renameFilename, renameLocation, edits) { var newText = applyEdits(oldText, renameFilename, edits); var _a = ts.computeLineAndCharacterOfPosition(ts.computeLineStarts(newText), renameLocation), line = _a.line, character = _a.character; return { line: line + 1, offset: character + 1 }; } server.getLocationInNewDocument = getLocationInNewDocument; function applyEdits(text, textFilename, edits) { for (var _i = 0, edits_3 = edits; _i < edits_3.length; _i++) { var _a = edits_3[_i], fileName = _a.fileName, textChanges_3 = _a.textChanges; if (fileName !== textFilename) { continue; } for (var i = textChanges_3.length - 1; i >= 0; i--) { var _b = textChanges_3[i], newText = _b.newText, _c = _b.span, start = _c.start, length_8 = _c.length; text = text.slice(0, start) + newText + text.slice(start + length_8); } } return text; } })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { var server; (function (server) { var lineCollectionCapacity = 4; var CharRangeSection; (function (CharRangeSection) { CharRangeSection[CharRangeSection["PreStart"] = 0] = "PreStart"; CharRangeSection[CharRangeSection["Start"] = 1] = "Start"; CharRangeSection[CharRangeSection["Entire"] = 2] = "Entire"; CharRangeSection[CharRangeSection["Mid"] = 3] = "Mid"; CharRangeSection[CharRangeSection["End"] = 4] = "End"; CharRangeSection[CharRangeSection["PostEnd"] = 5] = "PostEnd"; })(CharRangeSection || (CharRangeSection = {})); var EditWalker = /** @class */ (function () { function EditWalker() { this.goSubtree = true; this.lineIndex = new LineIndex(); this.endBranch = []; this.state = 2 /* Entire */; this.initialText = ""; this.trailingText = ""; this.lineIndex.root = new LineNode(); this.startPath = [this.lineIndex.root]; this.stack = [this.lineIndex.root]; } Object.defineProperty(EditWalker.prototype, "done", { get: function () { return false; }, enumerable: true, configurable: true }); EditWalker.prototype.insertLines = function (insertedText, suppressTrailingText) { if (suppressTrailingText) { this.trailingText = ""; } if (insertedText) { insertedText = this.initialText + insertedText + this.trailingText; } else { insertedText = this.initialText + this.trailingText; } var lm = LineIndex.linesFromText(insertedText); var lines = lm.lines; if (lines.length > 1) { if (lines[lines.length - 1] === "") { lines.pop(); } } var branchParent; var lastZeroCount; for (var k = this.endBranch.length - 1; k >= 0; k--) { this.endBranch[k].updateCounts(); if (this.endBranch[k].charCount() === 0) { lastZeroCount = this.endBranch[k]; if (k > 0) { branchParent = this.endBranch[k - 1]; } else { branchParent = this.branchNode; } } } if (lastZeroCount) { branchParent.remove(lastZeroCount); } // path at least length two (root and leaf) var leafNode = this.startPath[this.startPath.length - 1]; if (lines.length > 0) { leafNode.text = lines[0]; if (lines.length > 1) { var insertedNodes = new Array(lines.length - 1); var startNode = leafNode; for (var i = 1; i < lines.length; i++) { insertedNodes[i - 1] = new LineLeaf(lines[i]); } var pathIndex = this.startPath.length - 2; while (pathIndex >= 0) { var insertionNode = this.startPath[pathIndex]; insertedNodes = insertionNode.insertAt(startNode, insertedNodes); pathIndex--; startNode = insertionNode; } var insertedNodesLen = insertedNodes.length; while (insertedNodesLen > 0) { var newRoot = new LineNode(); newRoot.add(this.lineIndex.root); insertedNodes = newRoot.insertAt(this.lineIndex.root, insertedNodes); insertedNodesLen = insertedNodes.length; this.lineIndex.root = newRoot; } this.lineIndex.root.updateCounts(); } else { for (var j = this.startPath.length - 2; j >= 0; j--) { this.startPath[j].updateCounts(); } } } else { var insertionNode = this.startPath[this.startPath.length - 2]; // no content for leaf node, so delete it insertionNode.remove(leafNode); for (var j = this.startPath.length - 2; j >= 0; j--) { this.startPath[j].updateCounts(); } } return this.lineIndex; }; EditWalker.prototype.post = function (_relativeStart, _relativeLength, lineCollection) { // have visited the path for start of range, now looking for end // if range is on single line, we will never make this state transition if (lineCollection === this.lineCollectionAtBranch) { this.state = 4 /* End */; } // always pop stack because post only called when child has been visited this.stack.pop(); }; EditWalker.prototype.pre = function (_relativeStart, _relativeLength, lineCollection, _parent, nodeType) { // currentNode corresponds to parent, but in the new tree var currentNode = this.stack[this.stack.length - 1]; if ((this.state === 2 /* Entire */) && (nodeType === 1 /* Start */)) { // if range is on single line, we will never make this state transition this.state = 1 /* Start */; this.branchNode = currentNode; this.lineCollectionAtBranch = lineCollection; } var child; function fresh(node) { if (node.isLeaf()) { return new LineLeaf(""); } else return new LineNode(); } switch (nodeType) { case 0 /* PreStart */: this.goSubtree = false; if (this.state !== 4 /* End */) { currentNode.add(lineCollection); } break; case 1 /* Start */: if (this.state === 4 /* End */) { this.goSubtree = false; } else { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); } break; case 2 /* Entire */: if (this.state !== 4 /* End */) { child = fresh(lineCollection); currentNode.add(child); this.startPath.push(child); } else { if (!lineCollection.isLeaf()) { child = fresh(lineCollection); currentNode.add(child); this.endBranch.push(child); } } break; case 3 /* Mid */: this.goSubtree = false; break; case 4 /* End */: if (this.state !== 4 /* End */) { this.goSubtree = false; } else { if (!lineCollection.isLeaf()) { child = fresh(lineCollection); currentNode.add(child); this.endBranch.push(child); } } break; case 5 /* PostEnd */: this.goSubtree = false; if (this.state !== 1 /* Start */) { currentNode.add(lineCollection); } break; } if (this.goSubtree) { this.stack.push(child); } }; // just gather text from the leaves EditWalker.prototype.leaf = function (relativeStart, relativeLength, ll) { if (this.state === 1 /* Start */) { this.initialText = ll.text.substring(0, relativeStart); } else if (this.state === 2 /* Entire */) { this.initialText = ll.text.substring(0, relativeStart); this.trailingText = ll.text.substring(relativeStart + relativeLength); } else { // state is CharRangeSection.End this.trailingText = ll.text.substring(relativeStart + relativeLength); } }; return EditWalker; }()); // text change information var TextChange = /** @class */ (function () { function TextChange(pos, deleteLen, insertedText) { this.pos = pos; this.deleteLen = deleteLen; this.insertedText = insertedText; } TextChange.prototype.getTextChangeRange = function () { return ts.createTextChangeRange(ts.createTextSpan(this.pos, this.deleteLen), this.insertedText ? this.insertedText.length : 0); }; return TextChange; }()); var ScriptVersionCache = /** @class */ (function () { function ScriptVersionCache() { this.changes = []; this.versions = new Array(ScriptVersionCache.maxVersions); this.minVersion = 0; // no versions earlier than min version will maintain change history this.currentVersion = 0; } ScriptVersionCache.prototype.versionToIndex = function (version) { if (version < this.minVersion || version > this.currentVersion) { return undefined; } return version % ScriptVersionCache.maxVersions; }; ScriptVersionCache.prototype.currentVersionToIndex = function () { return this.currentVersion % ScriptVersionCache.maxVersions; }; // REVIEW: can optimize by coalescing simple edits ScriptVersionCache.prototype.edit = function (pos, deleteLen, insertedText) { this.changes.push(new TextChange(pos, deleteLen, insertedText)); if (this.changes.length > ScriptVersionCache.changeNumberThreshold || deleteLen > ScriptVersionCache.changeLengthThreshold || insertedText && insertedText.length > ScriptVersionCache.changeLengthThreshold) { this.getSnapshot(); } }; ScriptVersionCache.prototype.getSnapshot = function () { return this._getSnapshot(); }; ScriptVersionCache.prototype._getSnapshot = function () { var snap = this.versions[this.currentVersionToIndex()]; if (this.changes.length > 0) { var snapIndex = snap.index; for (var _i = 0, _a = this.changes; _i < _a.length; _i++) { var change = _a[_i]; snapIndex = snapIndex.edit(change.pos, change.deleteLen, change.insertedText); } snap = new LineIndexSnapshot(this.currentVersion + 1, this, snapIndex, this.changes); this.currentVersion = snap.version; this.versions[this.currentVersionToIndex()] = snap; this.changes = []; if ((this.currentVersion - this.minVersion) >= ScriptVersionCache.maxVersions) { this.minVersion = (this.currentVersion - ScriptVersionCache.maxVersions) + 1; } } return snap; }; ScriptVersionCache.prototype.getSnapshotVersion = function () { return this._getSnapshot().version; }; ScriptVersionCache.prototype.getLineInfo = function (line) { return this._getSnapshot().index.lineNumberToInfo(line); }; ScriptVersionCache.prototype.lineOffsetToPosition = function (line, column) { return this._getSnapshot().index.absolutePositionOfStartOfLine(line) + (column - 1); }; ScriptVersionCache.prototype.positionToLineOffset = function (position) { return this._getSnapshot().index.positionToLineOffset(position); }; ScriptVersionCache.prototype.lineToTextSpan = function (line) { var index = this._getSnapshot().index; var _a = index.lineNumberToInfo(line + 1), lineText = _a.lineText, absolutePosition = _a.absolutePosition; var len = lineText !== undefined ? lineText.length : index.absolutePositionOfStartOfLine(line + 2) - absolutePosition; return ts.createTextSpan(absolutePosition, len); }; ScriptVersionCache.prototype.getTextChangesBetweenVersions = function (oldVersion, newVersion) { if (oldVersion < newVersion) { if (oldVersion >= this.minVersion) { var textChangeRanges = []; for (var i = oldVersion + 1; i <= newVersion; i++) { var snap = this.versions[this.versionToIndex(i)]; for (var _i = 0, _a = snap.changesSincePreviousVersion; _i < _a.length; _i++) { var textChange = _a[_i]; textChangeRanges.push(textChange.getTextChangeRange()); } } return ts.collapseTextChangeRangesAcrossMultipleVersions(textChangeRanges); } else { return undefined; } } else { return ts.unchangedTextChangeRange; } }; ScriptVersionCache.fromString = function (script) { var svc = new ScriptVersionCache(); var snap = new LineIndexSnapshot(0, svc, new LineIndex()); svc.versions[svc.currentVersion] = snap; var lm = LineIndex.linesFromText(script); snap.index.load(lm.lines); return svc; }; ScriptVersionCache.changeNumberThreshold = 8; ScriptVersionCache.changeLengthThreshold = 256; ScriptVersionCache.maxVersions = 8; return ScriptVersionCache; }()); server.ScriptVersionCache = ScriptVersionCache; var LineIndexSnapshot = /** @class */ (function () { function LineIndexSnapshot(version, cache, index, changesSincePreviousVersion) { if (changesSincePreviousVersion === void 0) { changesSincePreviousVersion = server.emptyArray; } this.version = version; this.cache = cache; this.index = index; this.changesSincePreviousVersion = changesSincePreviousVersion; } LineIndexSnapshot.prototype.getText = function (rangeStart, rangeEnd) { return this.index.getText(rangeStart, rangeEnd - rangeStart); }; LineIndexSnapshot.prototype.getLength = function () { return this.index.root.charCount(); }; LineIndexSnapshot.prototype.getChangeRange = function (oldSnapshot) { if (oldSnapshot instanceof LineIndexSnapshot && this.cache === oldSnapshot.cache) { if (this.version <= oldSnapshot.version) { return ts.unchangedTextChangeRange; } else { return this.cache.getTextChangesBetweenVersions(oldSnapshot.version, this.version); } } }; return LineIndexSnapshot; }()); /* @internal */ var LineIndex = /** @class */ (function () { function LineIndex() { // set this to true to check each edit for accuracy this.checkEdits = false; } LineIndex.prototype.absolutePositionOfStartOfLine = function (oneBasedLine) { return this.lineNumberToInfo(oneBasedLine).absolutePosition; }; LineIndex.prototype.positionToLineOffset = function (position) { var _a = this.root.charOffsetToLineInfo(1, position), oneBasedLine = _a.oneBasedLine, zeroBasedColumn = _a.zeroBasedColumn; return { line: oneBasedLine, offset: zeroBasedColumn + 1 }; }; LineIndex.prototype.positionToColumnAndLineText = function (position) { return this.root.charOffsetToLineInfo(1, position); }; LineIndex.prototype.lineNumberToInfo = function (oneBasedLine) { var lineCount = this.root.lineCount(); if (oneBasedLine <= lineCount) { var _a = this.root.lineNumberToInfo(oneBasedLine, 0), position = _a.position, leaf = _a.leaf; return { absolutePosition: position, lineText: leaf && leaf.text }; } else { return { absolutePosition: this.root.charCount(), lineText: undefined }; } }; LineIndex.prototype.load = function (lines) { if (lines.length > 0) { var leaves = []; for (var i = 0; i < lines.length; i++) { leaves[i] = new LineLeaf(lines[i]); } this.root = LineIndex.buildTreeFromBottom(leaves); } else { this.root = new LineNode(); } }; LineIndex.prototype.walk = function (rangeStart, rangeLength, walkFns) { this.root.walk(rangeStart, rangeLength, walkFns); }; LineIndex.prototype.getText = function (rangeStart, rangeLength) { var accum = ""; if ((rangeLength > 0) && (rangeStart < this.root.charCount())) { this.walk(rangeStart, rangeLength, { goSubtree: true, done: false, leaf: function (relativeStart, relativeLength, ll) { accum = accum.concat(ll.text.substring(relativeStart, relativeStart + relativeLength)); } }); } return accum; }; LineIndex.prototype.getLength = function () { return this.root.charCount(); }; LineIndex.prototype.every = function (f, rangeStart, rangeEnd) { if (!rangeEnd) { rangeEnd = this.root.charCount(); } var walkFns = { goSubtree: true, done: false, leaf: function (relativeStart, relativeLength, ll) { if (!f(ll, relativeStart, relativeLength)) { this.done = true; } } }; this.walk(rangeStart, rangeEnd - rangeStart, walkFns); return !walkFns.done; }; LineIndex.prototype.edit = function (pos, deleteLength, newText) { if (this.root.charCount() === 0) { ts.Debug.assert(deleteLength === 0); // Can't delete from empty document if (newText !== undefined) { this.load(LineIndex.linesFromText(newText).lines); return this; } } else { var checkText = void 0; if (this.checkEdits) { var source = this.getText(0, this.root.charCount()); checkText = source.slice(0, pos) + newText + source.slice(pos + deleteLength); } var walker = new EditWalker(); var suppressTrailingText = false; if (pos >= this.root.charCount()) { // insert at end pos = this.root.charCount() - 1; var endString = this.getText(pos, 1); if (newText) { newText = endString + newText; } else { newText = endString; } deleteLength = 0; suppressTrailingText = true; } else if (deleteLength > 0) { // check whether last characters deleted are line break var e = pos + deleteLength; var _a = this.positionToColumnAndLineText(e), zeroBasedColumn = _a.zeroBasedColumn, lineText = _a.lineText; if (zeroBasedColumn === 0) { // move range end just past line that will merge with previous line deleteLength += lineText.length; // store text by appending to end of insertedText newText = newText ? newText + lineText : lineText; } } this.root.walk(pos, deleteLength, walker); walker.insertLines(newText, suppressTrailingText); if (this.checkEdits) { var updatedText = walker.lineIndex.getText(0, walker.lineIndex.getLength()); ts.Debug.assert(checkText === updatedText, "buffer edit mismatch"); } return walker.lineIndex; } }; LineIndex.buildTreeFromBottom = function (nodes) { if (nodes.length < lineCollectionCapacity) { return new LineNode(nodes); } var interiorNodes = new Array(Math.ceil(nodes.length / lineCollectionCapacity)); var nodeIndex = 0; for (var i = 0; i < interiorNodes.length; i++) { var end = Math.min(nodeIndex + lineCollectionCapacity, nodes.length); interiorNodes[i] = new LineNode(nodes.slice(nodeIndex, end)); nodeIndex = end; } return this.buildTreeFromBottom(interiorNodes); }; LineIndex.linesFromText = function (text) { var lineMap = ts.computeLineStarts(text); if (lineMap.length === 0) { return { lines: [], lineMap: lineMap }; } var lines = new Array(lineMap.length); var lc = lineMap.length - 1; for (var lmi = 0; lmi < lc; lmi++) { lines[lmi] = text.substring(lineMap[lmi], lineMap[lmi + 1]); } var endText = text.substring(lineMap[lc]); if (endText.length > 0) { lines[lc] = endText; } else { lines.pop(); } return { lines: lines, lineMap: lineMap }; }; return LineIndex; }()); server.LineIndex = LineIndex; var LineNode = /** @class */ (function () { function LineNode(children) { if (children === void 0) { children = []; } this.children = children; this.totalChars = 0; this.totalLines = 0; if (children.length) this.updateCounts(); } LineNode.prototype.isLeaf = function () { return false; }; LineNode.prototype.updateCounts = function () { this.totalChars = 0; this.totalLines = 0; for (var _i = 0, _a = this.children; _i < _a.length; _i++) { var child = _a[_i]; this.totalChars += child.charCount(); this.totalLines += child.lineCount(); } }; LineNode.prototype.execWalk = function (rangeStart, rangeLength, walkFns, childIndex, nodeType) { if (walkFns.pre) { walkFns.pre(rangeStart, rangeLength, this.children[childIndex], this, nodeType); } if (walkFns.goSubtree) { this.children[childIndex].walk(rangeStart, rangeLength, walkFns); if (walkFns.post) { walkFns.post(rangeStart, rangeLength, this.children[childIndex], this, nodeType); } } else { walkFns.goSubtree = true; } return walkFns.done; }; LineNode.prototype.skipChild = function (relativeStart, relativeLength, childIndex, walkFns, nodeType) { if (walkFns.pre && (!walkFns.done)) { walkFns.pre(relativeStart, relativeLength, this.children[childIndex], this, nodeType); walkFns.goSubtree = true; } }; LineNode.prototype.walk = function (rangeStart, rangeLength, walkFns) { // assume (rangeStart < this.totalChars) && (rangeLength <= this.totalChars) var childIndex = 0; var childCharCount = this.children[childIndex].charCount(); // find sub-tree containing start var adjustedStart = rangeStart; while (adjustedStart >= childCharCount) { this.skipChild(adjustedStart, rangeLength, childIndex, walkFns, 0 /* PreStart */); adjustedStart -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } // Case I: both start and end of range in same subtree if ((adjustedStart + rangeLength) <= childCharCount) { if (this.execWalk(adjustedStart, rangeLength, walkFns, childIndex, 2 /* Entire */)) { return; } } else { // Case II: start and end of range in different subtrees (possibly with subtrees in the middle) if (this.execWalk(adjustedStart, childCharCount - adjustedStart, walkFns, childIndex, 1 /* Start */)) { return; } var adjustedLength = rangeLength - (childCharCount - adjustedStart); childIndex++; var child = this.children[childIndex]; childCharCount = child.charCount(); while (adjustedLength > childCharCount) { if (this.execWalk(0, childCharCount, walkFns, childIndex, 3 /* Mid */)) { return; } adjustedLength -= childCharCount; childIndex++; childCharCount = this.children[childIndex].charCount(); } if (adjustedLength > 0) { if (this.execWalk(0, adjustedLength, walkFns, childIndex, 4 /* End */)) { return; } } } // Process any subtrees after the one containing range end if (walkFns.pre) { var clen = this.children.length; if (childIndex < (clen - 1)) { for (var ej = childIndex + 1; ej < clen; ej++) { this.skipChild(0, 0, ej, walkFns, 5 /* PostEnd */); } } } }; // Input position is relative to the start of this node. // Output line number is absolute. LineNode.prototype.charOffsetToLineInfo = function (lineNumberAccumulator, relativePosition) { if (this.children.length === 0) { // Root node might have no children if this is an empty document. return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: undefined }; } for (var _i = 0, _a = this.children; _i < _a.length; _i++) { var child = _a[_i]; if (child.charCount() > relativePosition) { if (child.isLeaf()) { return { oneBasedLine: lineNumberAccumulator, zeroBasedColumn: relativePosition, lineText: child.text }; } else { return child.charOffsetToLineInfo(lineNumberAccumulator, relativePosition); } } else { relativePosition -= child.charCount(); lineNumberAccumulator += child.lineCount(); } } // Skipped all children var leaf = this.lineNumberToInfo(this.lineCount(), 0).leaf; return { oneBasedLine: this.lineCount(), zeroBasedColumn: leaf.charCount(), lineText: undefined }; }; /** * Input line number is relative to the start of this node. * Output line number is relative to the child. * positionAccumulator will be an absolute position once relativeLineNumber reaches 0. */ LineNode.prototype.lineNumberToInfo = function (relativeOneBasedLine, positionAccumulator) { for (var _i = 0, _a = this.children; _i < _a.length; _i++) { var child = _a[_i]; var childLineCount = child.lineCount(); if (childLineCount >= relativeOneBasedLine) { return child.isLeaf() ? { position: positionAccumulator, leaf: child } : child.lineNumberToInfo(relativeOneBasedLine, positionAccumulator); } else { relativeOneBasedLine -= childLineCount; positionAccumulator += child.charCount(); } } return { position: positionAccumulator, leaf: undefined }; }; LineNode.prototype.splitAfter = function (childIndex) { var splitNode; var clen = this.children.length; childIndex++; var endLength = childIndex; if (childIndex < clen) { splitNode = new LineNode(); while (childIndex < clen) { splitNode.add(this.children[childIndex]); childIndex++; } splitNode.updateCounts(); } this.children.length = endLength; return splitNode; }; LineNode.prototype.remove = function (child) { var childIndex = this.findChildIndex(child); var clen = this.children.length; if (childIndex < (clen - 1)) { for (var i = childIndex; i < (clen - 1); i++) { this.children[i] = this.children[i + 1]; } } this.children.pop(); }; LineNode.prototype.findChildIndex = function (child) { var childIndex = this.children.indexOf(child); ts.Debug.assert(childIndex !== -1); return childIndex; }; LineNode.prototype.insertAt = function (child, nodes) { var childIndex = this.findChildIndex(child); var clen = this.children.length; var nodeCount = nodes.length; // if child is last and there is more room and only one node to place, place it if ((clen < lineCollectionCapacity) && (childIndex === (clen - 1)) && (nodeCount === 1)) { this.add(nodes[0]); this.updateCounts(); return []; } else { var shiftNode = this.splitAfter(childIndex); var nodeIndex = 0; childIndex++; while ((childIndex < lineCollectionCapacity) && (nodeIndex < nodeCount)) { this.children[childIndex] = nodes[nodeIndex]; childIndex++; nodeIndex++; } var splitNodes = []; var splitNodeCount = 0; if (nodeIndex < nodeCount) { splitNodeCount = Math.ceil((nodeCount - nodeIndex) / lineCollectionCapacity); splitNodes = new Array(splitNodeCount); var splitNodeIndex = 0; for (var i = 0; i < splitNodeCount; i++) { splitNodes[i] = new LineNode(); } var splitNode = splitNodes[0]; while (nodeIndex < nodeCount) { splitNode.add(nodes[nodeIndex]); nodeIndex++; if (splitNode.children.length === lineCollectionCapacity) { splitNodeIndex++; splitNode = splitNodes[splitNodeIndex]; } } for (var i = splitNodes.length - 1; i >= 0; i--) { if (splitNodes[i].children.length === 0) { splitNodes.pop(); } } } if (shiftNode) { splitNodes.push(shiftNode); } this.updateCounts(); for (var i = 0; i < splitNodeCount; i++) { splitNodes[i].updateCounts(); } return splitNodes; } }; // assume there is room for the item; return true if more room LineNode.prototype.add = function (collection) { this.children.push(collection); ts.Debug.assert(this.children.length <= lineCollectionCapacity); }; LineNode.prototype.charCount = function () { return this.totalChars; }; LineNode.prototype.lineCount = function () { return this.totalLines; }; return LineNode; }()); var LineLeaf = /** @class */ (function () { function LineLeaf(text) { this.text = text; } LineLeaf.prototype.isLeaf = function () { return true; }; LineLeaf.prototype.walk = function (rangeStart, rangeLength, walkFns) { walkFns.leaf(rangeStart, rangeLength, this); }; LineLeaf.prototype.charCount = function () { return this.text.length; }; LineLeaf.prototype.lineCount = function () { return 1; }; return LineLeaf; }()); })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// var ts; (function (ts) { var server; (function (server) { /* @internal */ var TextStorage = /** @class */ (function () { function TextStorage(host, fileName) { this.host = host; this.fileName = fileName; this.svcVersion = 0; this.textVersion = 0; } TextStorage.prototype.getVersion = function () { return this.svc ? "SVC-" + this.svcVersion + "-" + this.svc.getSnapshotVersion() : "Text-" + this.textVersion; }; TextStorage.prototype.hasScriptVersionCache_TestOnly = function () { return this.svc !== undefined; }; TextStorage.prototype.useScriptVersionCache_TestOnly = function () { this.switchToScriptVersionCache(); }; TextStorage.prototype.useText = function (newText) { this.svc = undefined; this.text = newText; this.lineMap = undefined; this.textVersion++; }; TextStorage.prototype.edit = function (start, end, newText) { this.switchToScriptVersionCache().edit(start, end - start, newText); this.ownFileText = false; this.text = undefined; this.lineMap = undefined; }; /** * Set the contents as newText * returns true if text changed */ TextStorage.prototype.reload = function (newText) { ts.Debug.assert(newText !== undefined); // Reload always has fresh content this.pendingReloadFromDisk = false; // If text changed set the text // This also ensures that if we had switched to version cache, // we are switching back to text. // The change to version cache will happen when needed // Thus avoiding the computation if there are no changes if (this.text !== newText) { this.useText(newText); // We cant guarantee new text is own file text this.ownFileText = false; return true; } }; /** * Reads the contents from tempFile(if supplied) or own file and sets it as contents * returns true if text changed */ TextStorage.prototype.reloadWithFileText = function (tempFileName) { var reloaded = this.reload(this.getFileText(tempFileName)); this.ownFileText = !tempFileName || tempFileName === this.fileName; return reloaded; }; /** * Reloads the contents from the file if there is no pending reload from disk or the contents of file are same as file text * returns true if text changed */ TextStorage.prototype.reloadFromDisk = function () { if (!this.pendingReloadFromDisk && !this.ownFileText) { return this.reloadWithFileText(); } return false; }; TextStorage.prototype.delayReloadFromFileIntoText = function () { this.pendingReloadFromDisk = true; }; TextStorage.prototype.getSnapshot = function () { return this.useScriptVersionCacheIfValidOrOpen() ? this.svc.getSnapshot() : ts.ScriptSnapshot.fromString(this.getOrLoadText()); }; TextStorage.prototype.getLineInfo = function (line) { return this.switchToScriptVersionCache().getLineInfo(line); }; /** * @param line 0 based index */ TextStorage.prototype.lineToTextSpan = function (line) { if (!this.useScriptVersionCacheIfValidOrOpen()) { var lineMap = this.getLineMap(); var start = lineMap[line]; // -1 since line is 1-based var end = line + 1 < lineMap.length ? lineMap[line + 1] : this.text.length; return ts.createTextSpanFromBounds(start, end); } return this.svc.lineToTextSpan(line); }; /** * @param line 1 based index * @param offset 1 based index */ TextStorage.prototype.lineOffsetToPosition = function (line, offset) { if (!this.useScriptVersionCacheIfValidOrOpen()) { return ts.computePositionOfLineAndCharacter(this.getLineMap(), line - 1, offset - 1, this.text); } // TODO: assert this offset is actually on the line return this.svc.lineOffsetToPosition(line, offset); }; TextStorage.prototype.positionToLineOffset = function (position) { if (!this.useScriptVersionCacheIfValidOrOpen()) { var _a = ts.computeLineAndCharacterOfPosition(this.getLineMap(), position), line = _a.line, character = _a.character; return { line: line + 1, offset: character + 1 }; } return this.svc.positionToLineOffset(position); }; TextStorage.prototype.getFileText = function (tempFileName) { return this.host.readFile(tempFileName || this.fileName) || ""; }; TextStorage.prototype.switchToScriptVersionCache = function () { if (!this.svc || this.pendingReloadFromDisk) { this.svc = server.ScriptVersionCache.fromString(this.getOrLoadText()); this.svcVersion++; } return this.svc; }; TextStorage.prototype.useScriptVersionCacheIfValidOrOpen = function () { // If this is open script, use the cache if (this.isOpen) { return this.switchToScriptVersionCache(); } // Else if the svc is uptodate with the text, we are good return !this.pendingReloadFromDisk && this.svc; }; TextStorage.prototype.getOrLoadText = function () { if (this.text === undefined || this.pendingReloadFromDisk) { ts.Debug.assert(!this.svc || this.pendingReloadFromDisk, "ScriptVersionCache should not be set when reloading from disk"); this.reloadWithFileText(); } return this.text; }; TextStorage.prototype.getLineMap = function () { ts.Debug.assert(!this.svc, "ScriptVersionCache should not be set"); return this.lineMap || (this.lineMap = ts.computeLineStarts(this.getOrLoadText())); }; return TextStorage; }()); server.TextStorage = TextStorage; /*@internal*/ function isDynamicFileName(fileName) { return ts.getBaseFileName(fileName)[0] === "^"; } server.isDynamicFileName = isDynamicFileName; var ScriptInfo = /** @class */ (function () { function ScriptInfo(host, fileName, scriptKind, hasMixedContent, path) { this.host = host; this.fileName = fileName; this.scriptKind = scriptKind; this.hasMixedContent = hasMixedContent; this.path = path; /** * All projects that include this file */ this.containingProjects = []; this.isDynamic = isDynamicFileName(fileName); this.textStorage = new TextStorage(host, fileName); if (hasMixedContent || this.isDynamic) { this.textStorage.reload(""); } this.scriptKind = scriptKind ? scriptKind : ts.getScriptKindFromFileName(fileName); } /*@internal*/ ScriptInfo.prototype.isDynamicOrHasMixedContent = function () { return this.hasMixedContent || this.isDynamic; }; ScriptInfo.prototype.isScriptOpen = function () { return this.textStorage.isOpen; }; ScriptInfo.prototype.open = function (newText) { this.textStorage.isOpen = true; if (newText !== undefined && this.textStorage.reload(newText)) { // reload new contents only if the existing contents changed this.markContainingProjectsAsDirty(); } }; ScriptInfo.prototype.close = function (fileExists) { if (fileExists === void 0) { fileExists = true; } this.textStorage.isOpen = false; if (this.isDynamicOrHasMixedContent() || !fileExists) { if (this.textStorage.reload("")) { this.markContainingProjectsAsDirty(); } } else if (this.textStorage.reloadFromDisk()) { this.markContainingProjectsAsDirty(); } }; ScriptInfo.prototype.getSnapshot = function () { return this.textStorage.getSnapshot(); }; ScriptInfo.prototype.getFormatCodeSettings = function () { return this.formatCodeSettings; }; ScriptInfo.prototype.attachToProject = function (project) { var isNew = !this.isAttached(project); if (isNew) { this.containingProjects.push(project); } return isNew; }; ScriptInfo.prototype.isAttached = function (project) { // unrolled for common cases switch (this.containingProjects.length) { case 0: return false; case 1: return this.containingProjects[0] === project; case 2: return this.containingProjects[0] === project || this.containingProjects[1] === project; default: return ts.contains(this.containingProjects, project); } }; ScriptInfo.prototype.detachFromProject = function (project) { // unrolled for common cases switch (this.containingProjects.length) { case 0: return; case 1: if (this.containingProjects[0] === project) { this.containingProjects.pop(); } break; case 2: if (this.containingProjects[0] === project) { this.containingProjects[0] = this.containingProjects.pop(); } else if (this.containingProjects[1] === project) { this.containingProjects.pop(); } break; default: ts.unorderedRemoveItem(this.containingProjects, project); break; } }; ScriptInfo.prototype.detachAllProjects = function () { for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) { var p = _a[_i]; if (p.projectKind === server.ProjectKind.Configured) { p.directoryStructureHost.addOrDeleteFile(this.fileName, this.path, ts.FileWatcherEventKind.Deleted); } var isInfoRoot = p.isRoot(this); // detach is unnecessary since we'll clean the list of containing projects anyways p.removeFile(this, /*fileExists*/ false, /*detachFromProjects*/ false); // If the info was for the external or configured project's root, // add missing file as the root if (isInfoRoot && p.projectKind !== server.ProjectKind.Inferred) { p.addMissingFileRoot(this.fileName); } } ts.clear(this.containingProjects); }; ScriptInfo.prototype.getDefaultProject = function () { switch (this.containingProjects.length) { case 0: return server.Errors.ThrowNoProject(); case 1: return this.containingProjects[0]; default: // if this file belongs to multiple projects, the first configured project should be // the default project; if no configured projects, the first external project should // be the default project; otherwise the first inferred project should be the default. var firstExternalProject = void 0; for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) { var project = _a[_i]; if (project.projectKind === server.ProjectKind.Configured) { return project; } else if (project.projectKind === server.ProjectKind.External && !firstExternalProject) { firstExternalProject = project; } } return firstExternalProject || this.containingProjects[0]; } }; ScriptInfo.prototype.registerFileUpdate = function () { for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) { var p = _a[_i]; p.registerFileUpdate(this.path); } }; ScriptInfo.prototype.setFormatOptions = function (formatSettings) { if (formatSettings) { if (!this.formatCodeSettings) { this.formatCodeSettings = server.getDefaultFormatCodeSettings(this.host); } server.mergeMapLikes(this.formatCodeSettings, formatSettings); } }; ScriptInfo.prototype.getLatestVersion = function () { return this.textStorage.getVersion(); }; ScriptInfo.prototype.saveTo = function (fileName) { var snap = this.textStorage.getSnapshot(); this.host.writeFile(fileName, snap.getText(0, snap.getLength())); }; /*@internal*/ ScriptInfo.prototype.delayReloadNonMixedContentFile = function () { ts.Debug.assert(!this.isDynamicOrHasMixedContent()); this.textStorage.delayReloadFromFileIntoText(); this.markContainingProjectsAsDirty(); }; ScriptInfo.prototype.reloadFromFile = function (tempFileName) { if (this.isDynamicOrHasMixedContent()) { this.textStorage.reload(""); this.markContainingProjectsAsDirty(); } else { if (this.textStorage.reloadWithFileText(tempFileName)) { this.markContainingProjectsAsDirty(); } } }; /*@internal*/ ScriptInfo.prototype.getLineInfo = function (line) { return this.textStorage.getLineInfo(line); }; ScriptInfo.prototype.editContent = function (start, end, newText) { this.textStorage.edit(start, end, newText); this.markContainingProjectsAsDirty(); }; ScriptInfo.prototype.markContainingProjectsAsDirty = function () { for (var _i = 0, _a = this.containingProjects; _i < _a.length; _i++) { var p = _a[_i]; p.markAsDirty(); } }; ScriptInfo.prototype.isOrphan = function () { return this.containingProjects.length === 0; }; /** * @param line 1 based index */ ScriptInfo.prototype.lineToTextSpan = function (line) { return this.textStorage.lineToTextSpan(line); }; /** * @param line 1 based index * @param offset 1 based index */ ScriptInfo.prototype.lineOffsetToPosition = function (line, offset) { return this.textStorage.lineOffsetToPosition(line, offset); }; ScriptInfo.prototype.positionToLineOffset = function (position) { return this.textStorage.positionToLineOffset(position); }; ScriptInfo.prototype.isJavaScript = function () { return this.scriptKind === 1 /* JS */ || this.scriptKind === 2 /* JSX */; }; return ScriptInfo; }()); server.ScriptInfo = ScriptInfo; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /* @internal */ var ts; (function (ts) { var ConfigFileProgramReloadLevel; (function (ConfigFileProgramReloadLevel) { ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["None"] = 0] = "None"; /** Update the file name list from the disk */ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Partial"] = 1] = "Partial"; /** Reload completely by re-reading contents of config file from disk and updating program */ ConfigFileProgramReloadLevel[ConfigFileProgramReloadLevel["Full"] = 2] = "Full"; })(ConfigFileProgramReloadLevel = ts.ConfigFileProgramReloadLevel || (ts.ConfigFileProgramReloadLevel = {})); /** * Updates the existing missing file watches with the new set of missing files after new program is created */ function updateMissingFilePathsWatch(program, missingFileWatches, createMissingFileWatch) { var missingFilePaths = program.getMissingFilePaths(); var newMissingFilePathMap = ts.arrayToSet(missingFilePaths); // Update the missing file paths watcher ts.mutateMap(missingFileWatches, newMissingFilePathMap, { // Watch the missing files createNewValue: createMissingFileWatch, // Files that are no longer missing (e.g. because they are no longer required) // should no longer be watched. onDeleteValue: closeFileWatcher }); } ts.updateMissingFilePathsWatch = updateMissingFilePathsWatch; /** * Updates the existing wild card directory watches with the new set of wild card directories from the config file * after new program is created because the config file was reloaded or program was created first time from the config file * Note that there is no need to call this function when the program is updated with additional files without reloading config files, * as wildcard directories wont change unless reloading config file */ function updateWatchingWildcardDirectories(existingWatchedForWildcards, wildcardDirectories, watchDirectory) { ts.mutateMap(existingWatchedForWildcards, wildcardDirectories, { // Create new watch and recursive info createNewValue: createWildcardDirectoryWatcher, // Close existing watch thats not needed any more onDeleteValue: closeFileWatcherOf, // Close existing watch that doesnt match in the flags onExistingValue: updateWildcardDirectoryWatcher }); function createWildcardDirectoryWatcher(directory, flags) { // Create new watch and recursive info return { watcher: watchDirectory(directory, flags), flags: flags }; } function updateWildcardDirectoryWatcher(existingWatcher, flags, directory) { // Watcher needs to be updated if the recursive flags dont match if (existingWatcher.flags === flags) { return; } existingWatcher.watcher.close(); existingWatchedForWildcards.set(directory, createWildcardDirectoryWatcher(directory, flags)); } } ts.updateWatchingWildcardDirectories = updateWatchingWildcardDirectories; function addFileWatcher(host, file, cb) { return host.watchFile(file, cb); } ts.addFileWatcher = addFileWatcher; function addFileWatcherWithLogging(host, file, cb, log) { var watcherCaption = "FileWatcher:: "; return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb); } ts.addFileWatcherWithLogging = addFileWatcherWithLogging; function addFileWatcherWithOnlyTriggerLogging(host, file, cb, log) { var watcherCaption = "FileWatcher:: "; return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb); } ts.addFileWatcherWithOnlyTriggerLogging = addFileWatcherWithOnlyTriggerLogging; function addFilePathWatcher(host, file, cb, path) { return host.watchFile(file, function (fileName, eventKind) { return cb(fileName, eventKind, path); }); } ts.addFilePathWatcher = addFilePathWatcher; function addFilePathWatcherWithLogging(host, file, cb, path, log) { var watcherCaption = "FileWatcher:: "; return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, file, cb, path); } ts.addFilePathWatcherWithLogging = addFilePathWatcherWithLogging; function addFilePathWatcherWithOnlyTriggerLogging(host, file, cb, path, log) { var watcherCaption = "FileWatcher:: "; return createWatcherWithLogging(addFileWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, file, cb, path); } ts.addFilePathWatcherWithOnlyTriggerLogging = addFilePathWatcherWithOnlyTriggerLogging; function addDirectoryWatcher(host, directory, cb, flags) { var recursive = (flags & 1 /* Recursive */) !== 0; return host.watchDirectory(directory, cb, recursive); } ts.addDirectoryWatcher = addDirectoryWatcher; function addDirectoryWatcherWithLogging(host, directory, cb, flags, log) { var watcherCaption = "DirectoryWatcher " + ((flags & 1 /* Recursive */) !== 0 ? "recursive" : "") + ":: "; return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ false, host, directory, cb, flags); } ts.addDirectoryWatcherWithLogging = addDirectoryWatcherWithLogging; function addDirectoryWatcherWithOnlyTriggerLogging(host, directory, cb, flags, log) { var watcherCaption = "DirectoryWatcher " + ((flags & 1 /* Recursive */) !== 0 ? "recursive" : "") + ":: "; return createWatcherWithLogging(addDirectoryWatcher, watcherCaption, log, /*logOnlyTrigger*/ true, host, directory, cb, flags); } ts.addDirectoryWatcherWithOnlyTriggerLogging = addDirectoryWatcherWithOnlyTriggerLogging; function createWatcherWithLogging(addWatch, watcherCaption, log, logOnlyTrigger, host, file, cb, optional) { var info = "PathInfo: " + file; if (!logOnlyTrigger) { log(watcherCaption + "Added: " + info); } var watcher = addWatch(host, file, function (fileName, cbOptional1) { var optionalInfo = cbOptional1 !== undefined ? " " + cbOptional1 : ""; log(watcherCaption + "Trigger: " + fileName + optionalInfo + " " + info); var start = ts.timestamp(); cb(fileName, cbOptional1, optional); var elapsed = ts.timestamp() - start; log(watcherCaption + "Elapsed: " + elapsed + "ms Trigger: " + fileName + optionalInfo + " " + info); }, optional); return { close: function () { if (!logOnlyTrigger) { log(watcherCaption + "Close: " + info); } watcher.close(); } }; } function closeFileWatcher(watcher) { watcher.close(); } ts.closeFileWatcher = closeFileWatcher; function closeFileWatcherOf(objWithWatcher) { objWithWatcher.watcher.close(); } ts.closeFileWatcherOf = closeFileWatcherOf; })(ts || (ts = {})); /// /// /// /*@internal*/ var ts; (function (ts) { ts.maxNumberOfFilesToIterateForInvalidation = 256; function createResolutionCache(resolutionHost, rootDirForResolution) { var filesWithChangedSetOfUnresolvedImports; var filesWithInvalidatedResolutions; var allFilesHaveInvalidatedResolution = false; // The resolvedModuleNames and resolvedTypeReferenceDirectives are the cache of resolutions per file. // The key in the map is source file's path. // The values are Map of resolutions with key being name lookedup. var resolvedModuleNames = ts.createMap(); var perDirectoryResolvedModuleNames = ts.createMap(); var resolvedTypeReferenceDirectives = ts.createMap(); var perDirectoryResolvedTypeReferenceDirectives = ts.createMap(); var getCurrentDirectory = ts.memoize(function () { return resolutionHost.getCurrentDirectory(); }); /** * These are the extensions that failed lookup files will have by default, * any other extension of failed lookup will be store that path in custom failed lookup path * This helps in not having to comb through all resolutions when files are added/removed * Note that .d.ts file also has .d.ts extension hence will be part of default extensions */ var failedLookupDefaultExtensions = [".ts" /* Ts */, ".tsx" /* Tsx */, ".js" /* Js */, ".jsx" /* Jsx */, ".json" /* Json */]; var customFailedLookupPaths = ts.createMap(); var directoryWatchesOfFailedLookups = ts.createMap(); var rootDir = rootDirForResolution && ts.removeTrailingDirectorySeparator(ts.getNormalizedAbsolutePath(rootDirForResolution, getCurrentDirectory())); var rootPath = rootDir && resolutionHost.toPath(rootDir); // TypeRoot watches for the types that get added as part of getAutomaticTypeDirectiveNames var typeRootsWatches = ts.createMap(); return { startRecordingFilesWithChangedResolutions: startRecordingFilesWithChangedResolutions, finishRecordingFilesWithChangedResolutions: finishRecordingFilesWithChangedResolutions, // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) startCachingPerDirectoryResolution: clearPerDirectoryResolutions, finishCachingPerDirectoryResolution: finishCachingPerDirectoryResolution, resolveModuleNames: resolveModuleNames, resolveTypeReferenceDirectives: resolveTypeReferenceDirectives, removeResolutionsOfFile: removeResolutionsOfFile, invalidateResolutionOfFile: invalidateResolutionOfFile, createHasInvalidatedResolution: createHasInvalidatedResolution, updateTypeRootsWatch: updateTypeRootsWatch, closeTypeRootsWatch: closeTypeRootsWatch, clear: clear }; function getResolvedModule(resolution) { return resolution.resolvedModule; } function getResolvedTypeReferenceDirective(resolution) { return resolution.resolvedTypeReferenceDirective; } function isInDirectoryPath(dir, file) { if (dir === undefined || file.length <= dir.length) { return false; } return ts.startsWith(file, dir) && file[dir.length] === ts.directorySeparator; } function clear() { ts.clearMap(directoryWatchesOfFailedLookups, ts.closeFileWatcherOf); customFailedLookupPaths.clear(); closeTypeRootsWatch(); resolvedModuleNames.clear(); resolvedTypeReferenceDirectives.clear(); allFilesHaveInvalidatedResolution = false; // perDirectoryResolvedModuleNames and perDirectoryResolvedTypeReferenceDirectives could be non empty if there was exception during program update // (between startCachingPerDirectoryResolution and finishCachingPerDirectoryResolution) clearPerDirectoryResolutions(); } function startRecordingFilesWithChangedResolutions() { filesWithChangedSetOfUnresolvedImports = []; } function finishRecordingFilesWithChangedResolutions() { var collected = filesWithChangedSetOfUnresolvedImports; filesWithChangedSetOfUnresolvedImports = undefined; return collected; } function createHasInvalidatedResolution() { if (allFilesHaveInvalidatedResolution) { // Any file asked would have invalidated resolution filesWithInvalidatedResolutions = undefined; return ts.returnTrue; } var collected = filesWithInvalidatedResolutions; filesWithInvalidatedResolutions = undefined; return function (path) { return collected && collected.has(path); }; } function clearPerDirectoryResolutions() { perDirectoryResolvedModuleNames.clear(); perDirectoryResolvedTypeReferenceDirectives.clear(); } function finishCachingPerDirectoryResolution() { allFilesHaveInvalidatedResolution = false; directoryWatchesOfFailedLookups.forEach(function (watcher, path) { if (watcher.refCount === 0) { directoryWatchesOfFailedLookups.delete(path); watcher.watcher.close(); } }); clearPerDirectoryResolutions(); } function resolveModuleName(moduleName, containingFile, compilerOptions, host) { var primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host); // return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts if (!resolutionHost.getGlobalCache) { return primaryResult; } // otherwise try to load typings from @types var globalCache = resolutionHost.getGlobalCache(); if (globalCache !== undefined && !ts.isExternalModuleNameRelative(moduleName) && !(primaryResult.resolvedModule && ts.extensionIsTypeScript(primaryResult.resolvedModule.extension))) { // create different collection of failed lookup locations for second pass // if it will fail and we've already found something during the first pass - we don't want to pollute its results var _a = ts.loadModuleFromGlobalCache(moduleName, resolutionHost.projectName, compilerOptions, host, globalCache), resolvedModule = _a.resolvedModule, failedLookupLocations = _a.failedLookupLocations; if (resolvedModule) { return { resolvedModule: resolvedModule, failedLookupLocations: ts.addRange(primaryResult.failedLookupLocations, failedLookupLocations) }; } } // Default return the result from the first pass return primaryResult; } function resolveNamesWithLocalCache(names, containingFile, cache, perDirectoryCache, loader, getResolutionWithResolvedFileName, reusedNames, logChanges) { var path = resolutionHost.toPath(containingFile); var resolutionsInFile = cache.get(path) || cache.set(path, ts.createMap()).get(path); var dirPath = ts.getDirectoryPath(path); var perDirectoryResolution = perDirectoryCache.get(dirPath); if (!perDirectoryResolution) { perDirectoryResolution = ts.createMap(); perDirectoryCache.set(dirPath, perDirectoryResolution); } var resolvedModules = []; var compilerOptions = resolutionHost.getCompilationSettings(); var seenNamesInFile = ts.createMap(); for (var _i = 0, names_2 = names; _i < names_2.length; _i++) { var name = names_2[_i]; var resolution = resolutionsInFile.get(name); // Resolution is valid if it is present and not invalidated if (!seenNamesInFile.has(name) && allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated) { var existingResolution = resolution; var resolutionInDirectory = perDirectoryResolution.get(name); if (resolutionInDirectory) { resolution = resolutionInDirectory; } else { resolution = loader(name, containingFile, compilerOptions, resolutionHost); perDirectoryResolution.set(name, resolution); } resolutionsInFile.set(name, resolution); if (resolution.failedLookupLocations) { if (existingResolution && existingResolution.failedLookupLocations) { watchAndStopWatchDiffFailedLookupLocations(resolution, existingResolution); } else { watchFailedLookupLocationOfResolution(resolution, 0); } } else if (existingResolution) { stopWatchFailedLookupLocationOfResolution(existingResolution); } if (logChanges && filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) { filesWithChangedSetOfUnresolvedImports.push(path); // reset log changes to avoid recording the same file multiple times logChanges = false; } } ts.Debug.assert(resolution !== undefined && !resolution.isInvalidated); seenNamesInFile.set(name, true); resolvedModules.push(getResolutionWithResolvedFileName(resolution)); } // Stop watching and remove the unused name resolutionsInFile.forEach(function (resolution, name) { if (!seenNamesInFile.has(name) && !ts.contains(reusedNames, name)) { stopWatchFailedLookupLocationOfResolution(resolution); resolutionsInFile.delete(name); } }); return resolvedModules; function resolutionIsEqualTo(oldResolution, newResolution) { if (oldResolution === newResolution) { return true; } if (!oldResolution || !newResolution || oldResolution.isInvalidated) { return false; } var oldResult = getResolutionWithResolvedFileName(oldResolution); var newResult = getResolutionWithResolvedFileName(newResolution); if (oldResult === newResult) { return true; } if (!oldResult || !newResult) { return false; } return oldResult.resolvedFileName === newResult.resolvedFileName; } } function resolveTypeReferenceDirectives(typeDirectiveNames, containingFile) { return resolveNamesWithLocalCache(typeDirectiveNames, containingFile, resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives, ts.resolveTypeReferenceDirective, getResolvedTypeReferenceDirective, /*reusedNames*/ undefined, /*logChanges*/ false); } function resolveModuleNames(moduleNames, containingFile, reusedNames, logChanges) { return resolveNamesWithLocalCache(moduleNames, containingFile, resolvedModuleNames, perDirectoryResolvedModuleNames, resolveModuleName, getResolvedModule, reusedNames, logChanges); } function isNodeModulesDirectory(dirPath) { return ts.endsWith(dirPath, "/node_modules"); } function isNodeModulesAtTypesDirectory(dirPath) { return ts.endsWith(dirPath, "/node_modules/@types"); } function isDirectoryAtleastAtLevelFromFSRoot(dirPath, minLevels) { for (var searchIndex = ts.getRootLength(dirPath); minLevels > 0; minLevels--) { searchIndex = dirPath.indexOf(ts.directorySeparator, searchIndex) + 1; if (searchIndex === 0) { // Folder isnt at expected minimun levels return false; } } return true; } function canWatchDirectory(dirPath) { return isDirectoryAtleastAtLevelFromFSRoot(dirPath, // When root is "/" do not watch directories like: // "/", "/user", "/user/username", "/user/username/folderAtRoot" // When root is "c:/" do not watch directories like: // "c:/", "c:/folderAtRoot" dirPath.charCodeAt(0) === 47 /* slash */ ? 3 : 1); } function filterFSRootDirectoriesToWatch(watchPath, dirPath) { if (!canWatchDirectory(dirPath)) { watchPath.ignore = true; } return watchPath; } function getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath) { if (isInDirectoryPath(rootPath, failedLookupLocationPath)) { return { dir: rootDir, dirPath: rootPath }; } var dir = ts.getDirectoryPath(ts.getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory())); var dirPath = ts.getDirectoryPath(failedLookupLocationPath); // If directory path contains node module, get the most parent node_modules directory for watching while (ts.stringContains(dirPath, "/node_modules/")) { dir = ts.getDirectoryPath(dir); dirPath = ts.getDirectoryPath(dirPath); } // If the directory is node_modules use it to watch if (isNodeModulesDirectory(dirPath)) { return filterFSRootDirectoriesToWatch({ dir: dir, dirPath: dirPath }, ts.getDirectoryPath(dirPath)); } // Use some ancestor of the root directory if (rootPath !== undefined) { while (!isInDirectoryPath(dirPath, rootPath)) { var parentPath = ts.getDirectoryPath(dirPath); if (parentPath === dirPath) { break; } dirPath = parentPath; dir = ts.getDirectoryPath(dir); } } return filterFSRootDirectoriesToWatch({ dir: dir, dirPath: dirPath }, dirPath); } function isPathWithDefaultFailedLookupExtension(path) { return ts.fileExtensionIsOneOf(path, failedLookupDefaultExtensions); } function watchAndStopWatchDiffFailedLookupLocations(resolution, existingResolution) { var failedLookupLocations = resolution.failedLookupLocations; var existingFailedLookupLocations = existingResolution.failedLookupLocations; for (var index = 0; index < failedLookupLocations.length; index++) { if (index === existingFailedLookupLocations.length) { // Additional failed lookup locations, watch from this index watchFailedLookupLocationOfResolution(resolution, index); return; } else if (failedLookupLocations[index] !== existingFailedLookupLocations[index]) { // Different failed lookup locations, // Watch new resolution failed lookup locations from this index and // stop watching existing resolutions from this index watchFailedLookupLocationOfResolution(resolution, index); stopWatchFailedLookupLocationOfResolutionFrom(existingResolution, index); return; } } // All new failed lookup locations are already watched (and are same), // Stop watching failed lookup locations of existing resolution after failed lookup locations length stopWatchFailedLookupLocationOfResolutionFrom(existingResolution, failedLookupLocations.length); } function watchFailedLookupLocationOfResolution(_a, startIndex) { var failedLookupLocations = _a.failedLookupLocations; for (var i = startIndex; i < failedLookupLocations.length; i++) { var failedLookupLocation = failedLookupLocations[i]; var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation); // If the failed lookup location path is not one of the supported extensions, // store it in the custom path if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) { var refCount = customFailedLookupPaths.get(failedLookupLocationPath) || 0; customFailedLookupPaths.set(failedLookupLocationPath, refCount + 1); } var _b = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath), dir = _b.dir, dirPath = _b.dirPath, ignore = _b.ignore; if (!ignore) { var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); if (dirWatcher) { dirWatcher.refCount++; } else { directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 }); } } } } function stopWatchFailedLookupLocationOfResolution(resolution) { if (resolution.failedLookupLocations) { stopWatchFailedLookupLocationOfResolutionFrom(resolution, 0); } } function stopWatchFailedLookupLocationOfResolutionFrom(_a, startIndex) { var failedLookupLocations = _a.failedLookupLocations; for (var i = startIndex; i < failedLookupLocations.length; i++) { var failedLookupLocation = failedLookupLocations[i]; var failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation); var refCount = customFailedLookupPaths.get(failedLookupLocationPath); if (refCount) { if (refCount === 1) { customFailedLookupPaths.delete(failedLookupLocationPath); } else { ts.Debug.assert(refCount > 1); customFailedLookupPaths.set(failedLookupLocationPath, refCount - 1); } } var _b = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath), dirPath = _b.dirPath, ignore = _b.ignore; if (!ignore) { var dirWatcher = directoryWatchesOfFailedLookups.get(dirPath); // Do not close the watcher yet since it might be needed by other failed lookup locations. dirWatcher.refCount--; } } } function createDirectoryWatcher(directory, dirPath) { return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, function (fileOrDirectory) { var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory); if (resolutionHost.getCachedDirectoryStructureHost) { // Since the file existance changed, update the sourceFiles cache resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); } // If the files are added to project root or node_modules directory, always run through the invalidation process // Otherwise run through invalidation only if adding to the immediate directory if (!allFilesHaveInvalidatedResolution && dirPath === rootPath || isNodeModulesDirectory(dirPath) || ts.getDirectoryPath(fileOrDirectoryPath) === dirPath) { if (invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) { resolutionHost.onInvalidatedResolution(); } } }, 1 /* Recursive */); } function removeResolutionsOfFileFromCache(cache, filePath) { // Deleted file, stop watching failed lookups for all the resolutions in the file var resolutions = cache.get(filePath); if (resolutions) { resolutions.forEach(stopWatchFailedLookupLocationOfResolution); cache.delete(filePath); } } function removeResolutionsOfFile(filePath) { removeResolutionsOfFileFromCache(resolvedModuleNames, filePath); removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath); } function invalidateResolutionCache(cache, isInvalidatedResolution, getResolutionWithResolvedFileName) { var seen = ts.createMap(); cache.forEach(function (resolutions, containingFilePath) { var dirPath = ts.getDirectoryPath(containingFilePath); var seenInDir = seen.get(dirPath); if (!seenInDir) { seenInDir = ts.createMap(); seen.set(dirPath, seenInDir); } resolutions.forEach(function (resolution, name) { if (seenInDir.has(name)) { return; } seenInDir.set(name, true); if (!resolution.isInvalidated && isInvalidatedResolution(resolution, getResolutionWithResolvedFileName)) { // Mark the file as needing re-evaluation of module resolution instead of using it blindly. resolution.isInvalidated = true; (filesWithInvalidatedResolutions || (filesWithInvalidatedResolutions = ts.createMap())).set(containingFilePath, true); } }); }); } function hasReachedResolutionIterationLimit() { var maxSize = resolutionHost.maxNumberOfFilesToIterateForInvalidation || ts.maxNumberOfFilesToIterateForInvalidation; return resolvedModuleNames.size > maxSize || resolvedTypeReferenceDirectives.size > maxSize; } function invalidateResolutions(isInvalidatedResolution) { // If more than maxNumberOfFilesToIterateForInvalidation present, // just invalidated all files and recalculate the resolutions for files instead if (hasReachedResolutionIterationLimit()) { allFilesHaveInvalidatedResolution = true; return; } invalidateResolutionCache(resolvedModuleNames, isInvalidatedResolution, getResolvedModule); invalidateResolutionCache(resolvedTypeReferenceDirectives, isInvalidatedResolution, getResolvedTypeReferenceDirective); } function invalidateResolutionOfFile(filePath) { removeResolutionsOfFile(filePath); invalidateResolutions( // Resolution is invalidated if the resulting file name is same as the deleted file path function (resolution, getResolutionWithResolvedFileName) { var result = getResolutionWithResolvedFileName(resolution); return result && resolutionHost.toPath(result.resolvedFileName) === filePath; }); } function invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, isCreatingWatchedDirectory) { var isChangedFailedLookupLocation; if (isCreatingWatchedDirectory) { // Watching directory is created // Invalidate any resolution has failed lookup in this directory isChangedFailedLookupLocation = function (location) { return isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location)); }; } else { // Some file or directory in the watching directory is created // Return early if it does not have any of the watching extension or not the custom failed lookup path var dirOfFileOrDirectory = ts.getDirectoryPath(fileOrDirectoryPath); if (isNodeModulesAtTypesDirectory(dirOfFileOrDirectory) || isNodeModulesDirectory(dirOfFileOrDirectory)) { // Invalidate any resolution from this directory isChangedFailedLookupLocation = function (location) { var locationPath = resolutionHost.toPath(location); return locationPath === fileOrDirectoryPath || ts.startsWith(resolutionHost.toPath(location), fileOrDirectoryPath); }; } else { if (!isPathWithDefaultFailedLookupExtension(fileOrDirectoryPath) && !customFailedLookupPaths.has(fileOrDirectoryPath)) { return false; } // Resolution need to be invalidated if failed lookup location is same as the file or directory getting created isChangedFailedLookupLocation = function (location) { return resolutionHost.toPath(location) === fileOrDirectoryPath; }; } } var hasChangedFailedLookupLocation = function (resolution) { return ts.some(resolution.failedLookupLocations, isChangedFailedLookupLocation); }; var invalidatedFilesCount = filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size; invalidateResolutions( // Resolution is invalidated if the resulting file name is same as the deleted file path hasChangedFailedLookupLocation); return allFilesHaveInvalidatedResolution || filesWithInvalidatedResolutions && filesWithInvalidatedResolutions.size !== invalidatedFilesCount; } function closeTypeRootsWatch() { ts.clearMap(typeRootsWatches, ts.closeFileWatcher); } function createTypeRootsWatch(_typeRootPath, typeRoot) { // Create new watch and recursive info return resolutionHost.watchTypeRootsDirectory(typeRoot, function (fileOrDirectory) { var fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory); if (resolutionHost.getCachedDirectoryStructureHost) { // Since the file existance changed, update the sourceFiles cache resolutionHost.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); } // For now just recompile // We could potentially store more data here about whether it was/would be really be used or not // and with that determine to trigger compilation but for now this is enough resolutionHost.onChangedAutomaticTypeDirectiveNames(); }, 1 /* Recursive */); } /** * Watches the types that would get added as part of getAutomaticTypeDirectiveNames * To be called when compiler options change */ function updateTypeRootsWatch() { var options = resolutionHost.getCompilationSettings(); if (options.types) { // No need to do any watch since resolution cache is going to handle the failed lookups // for the types added by this closeTypeRootsWatch(); return; } // we need to assume the directories exist to ensure that we can get all the type root directories that get included // But filter directories that are at root level to say directory doesnt exist, so that we arent watching them var typeRoots = ts.getEffectiveTypeRoots(options, { directoryExists: directoryExistsForTypeRootWatch, getCurrentDirectory: getCurrentDirectory }); if (typeRoots) { ts.mutateMap(typeRootsWatches, ts.arrayToMap(typeRoots, function (tr) { return resolutionHost.toPath(tr); }), { createNewValue: createTypeRootsWatch, onDeleteValue: ts.closeFileWatcher }); } else { closeTypeRootsWatch(); } } /** * Use this function to return if directory exists to get type roots to watch * If we return directory exists then only the paths will be added to type roots * Hence return true for all directories except root directories which are filtered from watching */ function directoryExistsForTypeRootWatch(nodeTypesDirectory) { var dir = ts.getDirectoryPath(ts.getDirectoryPath(nodeTypesDirectory)); var dirPath = resolutionHost.toPath(dir); return dirPath === rootPath || canWatchDirectory(dirPath); } } ts.createResolutionCache = createResolutionCache; })(ts || (ts = {})); /// var ts; (function (ts) { var server; (function (server) { server.nullTypingsInstaller = { isKnownTypesPackageName: ts.returnFalse, // Should never be called because we never provide a types registry. installPackage: ts.notImplemented, enqueueInstallTypingsRequest: ts.noop, attach: ts.noop, onProjectClosed: ts.noop, globalTypingsCacheLocation: undefined }; var TypingsCacheEntry = /** @class */ (function () { function TypingsCacheEntry() { } return TypingsCacheEntry; }()); function setIsEqualTo(arr1, arr2) { if (arr1 === arr2) { return true; } if ((arr1 || server.emptyArray).length === 0 && (arr2 || server.emptyArray).length === 0) { return true; } var set = ts.createMap(); var unique = 0; for (var _i = 0, arr1_1 = arr1; _i < arr1_1.length; _i++) { var v = arr1_1[_i]; if (set.get(v) !== true) { set.set(v, true); unique++; } } for (var _a = 0, arr2_1 = arr2; _a < arr2_1.length; _a++) { var v = arr2_1[_a]; var isSet = set.get(v); if (isSet === undefined) { return false; } if (isSet === true) { set.set(v, false); unique--; } } return unique === 0; } function typeAcquisitionChanged(opt1, opt2) { return opt1.enable !== opt2.enable || !setIsEqualTo(opt1.include, opt2.include) || !setIsEqualTo(opt1.exclude, opt2.exclude); } function compilerOptionsChanged(opt1, opt2) { // TODO: add more relevant properties return opt1.allowJs !== opt2.allowJs; } function unresolvedImportsChanged(imports1, imports2) { if (imports1 === imports2) { return false; } return !ts.arrayIsEqualTo(imports1, imports2); } var TypingsCache = /** @class */ (function () { function TypingsCache(installer) { this.installer = installer; this.perProjectCache = ts.createMap(); } TypingsCache.prototype.isKnownTypesPackageName = function (name) { return this.installer.isKnownTypesPackageName(name); }; TypingsCache.prototype.installPackage = function (options) { return this.installer.installPackage(options); }; TypingsCache.prototype.getTypingsForProject = function (project, unresolvedImports, forceRefresh) { var typeAcquisition = project.getTypeAcquisition(); if (!typeAcquisition || !typeAcquisition.enable) { return server.emptyArray; } var entry = this.perProjectCache.get(project.getProjectName()); var result = entry ? entry.typings : server.emptyArray; if (forceRefresh || !entry || typeAcquisitionChanged(typeAcquisition, entry.typeAcquisition) || compilerOptionsChanged(project.getCompilationSettings(), entry.compilerOptions) || unresolvedImportsChanged(unresolvedImports, entry.unresolvedImports)) { // Note: entry is now poisoned since it does not really contain typings for a given combination of compiler options\typings options. // instead it acts as a placeholder to prevent issuing multiple requests this.perProjectCache.set(project.getProjectName(), { compilerOptions: project.getCompilationSettings(), typeAcquisition: typeAcquisition, typings: result, unresolvedImports: unresolvedImports, poisoned: true }); // something has been changed, issue a request to update typings this.installer.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports); } return result; }; TypingsCache.prototype.updateTypingsForProject = function (projectName, compilerOptions, typeAcquisition, unresolvedImports, newTypings) { this.perProjectCache.set(projectName, { compilerOptions: compilerOptions, typeAcquisition: typeAcquisition, typings: server.toSortedArray(newTypings), unresolvedImports: unresolvedImports, poisoned: false }); }; TypingsCache.prototype.deleteTypingsForProject = function (projectName) { this.perProjectCache.delete(projectName); }; TypingsCache.prototype.onProjectClosed = function (project) { this.perProjectCache.delete(project.getProjectName()); this.installer.onProjectClosed(project); }; return TypingsCache; }()); server.TypingsCache = TypingsCache; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /// /// /// /// /// var ts; (function (ts) { var server; (function (server) { var ProjectKind; (function (ProjectKind) { ProjectKind[ProjectKind["Inferred"] = 0] = "Inferred"; ProjectKind[ProjectKind["Configured"] = 1] = "Configured"; ProjectKind[ProjectKind["External"] = 2] = "External"; })(ProjectKind = server.ProjectKind || (server.ProjectKind = {})); /* @internal */ function countEachFileTypes(infos) { var result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 }; for (var _i = 0, infos_1 = infos; _i < infos_1.length; _i++) { var info = infos_1[_i]; switch (info.scriptKind) { case 1 /* JS */: result.js += 1; break; case 2 /* JSX */: result.jsx += 1; break; case 3 /* TS */: ts.fileExtensionIs(info.fileName, ".d.ts" /* Dts */) ? result.dts += 1 : result.ts += 1; break; case 4 /* TSX */: result.tsx += 1; break; } } return result; } server.countEachFileTypes = countEachFileTypes; function hasOneOrMoreJsAndNoTsFiles(project) { var counts = countEachFileTypes(project.getScriptInfos()); return counts.js > 0 && counts.ts === 0 && counts.tsx === 0; } function allRootFilesAreJsOrDts(project) { var counts = countEachFileTypes(project.getRootScriptInfos()); return counts.ts === 0 && counts.tsx === 0; } server.allRootFilesAreJsOrDts = allRootFilesAreJsOrDts; function allFilesAreJsOrDts(project) { var counts = countEachFileTypes(project.getScriptInfos()); return counts.ts === 0 && counts.tsx === 0; } server.allFilesAreJsOrDts = allFilesAreJsOrDts; /* @internal */ function hasNoTypeScriptSource(fileNames) { return !fileNames.some(function (fileName) { return (ts.fileExtensionIs(fileName, ".ts" /* Ts */) && !ts.fileExtensionIs(fileName, ".d.ts" /* Dts */)) || ts.fileExtensionIs(fileName, ".tsx" /* Tsx */); }); } server.hasNoTypeScriptSource = hasNoTypeScriptSource; var UnresolvedImportsMap = /** @class */ (function () { function UnresolvedImportsMap() { this.perFileMap = ts.createMap(); this.version = 0; } UnresolvedImportsMap.prototype.clear = function () { this.perFileMap.clear(); this.version = 0; }; UnresolvedImportsMap.prototype.getVersion = function () { return this.version; }; UnresolvedImportsMap.prototype.remove = function (path) { this.perFileMap.delete(path); this.version++; }; UnresolvedImportsMap.prototype.get = function (path) { return this.perFileMap.get(path); }; UnresolvedImportsMap.prototype.set = function (path, value) { this.perFileMap.set(path, value); this.version++; }; return UnresolvedImportsMap; }()); server.UnresolvedImportsMap = UnresolvedImportsMap; /* @internal */ function isScriptInfo(value) { return value instanceof server.ScriptInfo; } server.isScriptInfo = isScriptInfo; var Project = /** @class */ (function () { /*@internal*/ function Project( /*@internal*/ projectName, projectKind, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled, /*@internal*/ directoryStructureHost, currentDirectory) { this.projectName = projectName; this.projectKind = projectKind; this.projectService = projectService; this.documentRegistry = documentRegistry; this.compilerOptions = compilerOptions; this.compileOnSaveEnabled = compileOnSaveEnabled; this.directoryStructureHost = directoryStructureHost; this.rootFiles = []; this.rootFilesMap = ts.createMap(); this.cachedUnresolvedImportsPerFile = new UnresolvedImportsMap(); this.languageServiceEnabled = true; /** * Last version that was reported. */ this.lastReportedVersion = 0; /** * Current project structure version. * This property is changed in 'updateGraph' based on the set of files in program */ this.projectStructureVersion = 0; /** * Current version of the project state. It is changed when: * - new root file was added/removed * - edit happen in some file that is currently included in the project. * This property is different from projectStructureVersion since in most cases edits don't affect set of files in the project */ this.projectStateVersion = 0; /*@internal*/ this.hasChangedAutomaticTypeDirectiveNames = false; this.currentDirectory = this.projectService.getNormalizedAbsolutePath(currentDirectory || ""); this.cancellationToken = new ts.ThrottledCancellationToken(this.projectService.cancellationToken, this.projectService.throttleWaitMilliseconds); if (!this.compilerOptions) { this.compilerOptions = ts.getDefaultCompilerOptions(); this.compilerOptions.allowNonTsExtensions = true; this.compilerOptions.allowJs = true; } else if (hasExplicitListOfFiles || this.compilerOptions.allowJs) { // If files are listed explicitly or allowJs is specified, allow all extensions this.compilerOptions.allowNonTsExtensions = true; } this.setInternalCompilerOptionsForEmittingJsFiles(); var host = this.projectService.host; if (host.trace) { this.trace = function (s) { return host.trace(s); }; } if (host.realpath) { this.realpath = function (path) { return host.realpath(path); }; } // Use the current directory as resolution root only if the project created using current directory string this.resolutionCache = ts.createResolutionCache(this, currentDirectory && this.currentDirectory); this.languageService = ts.createLanguageService(this, this.documentRegistry); if (!languageServiceEnabled) { this.disableLanguageService(); } this.markAsDirty(); } Project.prototype.isNonTsProject = function () { this.updateGraph(); return allFilesAreJsOrDts(this); }; Project.prototype.isJsOnlyProject = function () { this.updateGraph(); return hasOneOrMoreJsAndNoTsFiles(this); }; Project.prototype.getCachedUnresolvedImportsPerFile_TestOnly = function () { return this.cachedUnresolvedImportsPerFile; }; Project.resolveModule = function (moduleName, initialDir, host, log) { var resolvedPath = ts.normalizeSlashes(host.resolvePath(ts.combinePaths(initialDir, "node_modules"))); log("Loading " + moduleName + " from " + initialDir + " (resolved to " + resolvedPath + ")"); var result = host.require(resolvedPath, moduleName); if (result.error) { var err = result.error.stack || result.error.message || JSON.stringify(result.error); log("Failed to load module '" + moduleName + "': " + err); return undefined; } return result.module; }; Project.prototype.isKnownTypesPackageName = function (name) { return this.typingsCache.isKnownTypesPackageName(name); }; Project.prototype.installPackage = function (options) { return this.typingsCache.installPackage(__assign({}, options, { projectName: this.projectName, projectRootPath: this.toPath(this.currentDirectory) })); }; Object.defineProperty(Project.prototype, "typingsCache", { get: function () { return this.projectService.typingsCache; }, enumerable: true, configurable: true }); // Method of LanguageServiceHost Project.prototype.getCompilationSettings = function () { return this.compilerOptions; }; // Method to support public API Project.prototype.getCompilerOptions = function () { return this.getCompilationSettings(); }; Project.prototype.getNewLine = function () { return this.directoryStructureHost.newLine; }; Project.prototype.getProjectVersion = function () { return this.projectStateVersion.toString(); }; Project.prototype.getScriptFileNames = function () { var _this = this; if (!this.rootFiles) { return ts.emptyArray; } var result; this.rootFilesMap.forEach(function (value) { if (_this.languageServiceEnabled || (isScriptInfo(value) && value.isScriptOpen())) { // if language service is disabled - process only files that are open (result || (result = [])).push(isScriptInfo(value) ? value.fileName : value); } }); return ts.addRange(result, this.typingFiles) || ts.emptyArray; }; Project.prototype.getOrCreateScriptInfoAndAttachToProject = function (fileName) { var scriptInfo = this.projectService.getOrCreateScriptInfoNotOpenedByClient(fileName, this.currentDirectory, this.directoryStructureHost); if (scriptInfo) { var existingValue = this.rootFilesMap.get(scriptInfo.path); if (existingValue !== scriptInfo && existingValue !== undefined) { // This was missing path earlier but now the file exists. Update the root this.rootFiles.push(scriptInfo); this.rootFilesMap.set(scriptInfo.path, scriptInfo); } scriptInfo.attachToProject(this); } return scriptInfo; }; Project.prototype.getScriptKind = function (fileName) { var info = this.getOrCreateScriptInfoAndAttachToProject(fileName); return info && info.scriptKind; }; Project.prototype.getScriptVersion = function (filename) { var info = this.getOrCreateScriptInfoAndAttachToProject(filename); return info && info.getLatestVersion(); }; Project.prototype.getScriptSnapshot = function (filename) { var scriptInfo = this.getOrCreateScriptInfoAndAttachToProject(filename); if (scriptInfo) { return scriptInfo.getSnapshot(); } }; Project.prototype.getCancellationToken = function () { return this.cancellationToken; }; Project.prototype.getCurrentDirectory = function () { return this.currentDirectory; }; Project.prototype.getDefaultLibFileName = function () { var nodeModuleBinDir = ts.getDirectoryPath(ts.normalizePath(this.projectService.getExecutingFilePath())); return ts.combinePaths(nodeModuleBinDir, ts.getDefaultLibFileName(this.compilerOptions)); }; Project.prototype.useCaseSensitiveFileNames = function () { return this.directoryStructureHost.useCaseSensitiveFileNames; }; Project.prototype.readDirectory = function (path, extensions, exclude, include, depth) { return this.directoryStructureHost.readDirectory(path, extensions, exclude, include, depth); }; Project.prototype.readFile = function (fileName) { return this.directoryStructureHost.readFile(fileName); }; Project.prototype.fileExists = function (file) { // As an optimization, don't hit the disks for files we already know don't exist // (because we're watching for their creation). var path = this.toPath(file); return !this.isWatchedMissingFile(path) && this.directoryStructureHost.fileExists(file); }; Project.prototype.resolveModuleNames = function (moduleNames, containingFile, reusedNames) { return this.resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, /*logChanges*/ true); }; Project.prototype.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) { return this.resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile); }; Project.prototype.directoryExists = function (path) { return this.directoryStructureHost.directoryExists(path); }; Project.prototype.getDirectories = function (path) { return this.directoryStructureHost.getDirectories(path); }; /*@internal*/ Project.prototype.toPath = function (fileName) { return ts.toPath(fileName, this.currentDirectory, this.projectService.toCanonicalFileName); }; /*@internal*/ Project.prototype.watchDirectoryOfFailedLookupLocation = function (directory, cb, flags) { return this.projectService.watchDirectory(this.projectService.host, directory, cb, flags, "Directory of Failed lookup locations in module resolution" /* FailedLookupLocation */, this); }; /*@internal*/ Project.prototype.onInvalidatedResolution = function () { this.projectService.delayUpdateProjectGraphAndInferredProjectsRefresh(this); }; /*@internal*/ Project.prototype.watchTypeRootsDirectory = function (directory, cb, flags) { return this.projectService.watchDirectory(this.projectService.host, directory, cb, flags, "Type root directory" /* TypeRoots */, this); }; /*@internal*/ Project.prototype.onChangedAutomaticTypeDirectiveNames = function () { this.hasChangedAutomaticTypeDirectiveNames = true; this.projectService.delayUpdateProjectGraphAndInferredProjectsRefresh(this); }; /*@internal*/ Project.prototype.getGlobalCache = function () { return this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined; }; /*@internal*/ Project.prototype.writeLog = function (s) { this.projectService.logger.info(s); }; Project.prototype.setInternalCompilerOptionsForEmittingJsFiles = function () { if (this.projectKind === ProjectKind.Inferred || this.projectKind === ProjectKind.External) { this.compilerOptions.noEmitForJsFiles = true; } }; /** * Get the errors that dont have any file name associated */ Project.prototype.getGlobalProjectErrors = function () { return server.emptyArray; }; Project.prototype.getAllProjectErrors = function () { return server.emptyArray; }; Project.prototype.getLanguageService = function (ensureSynchronized) { if (ensureSynchronized === void 0) { ensureSynchronized = true; } if (ensureSynchronized) { this.updateGraph(); } return this.languageService; }; Project.prototype.ensureBuilder = function () { var _this = this; if (!this.builder) { this.builder = ts.createBuilder({ getCanonicalFileName: this.projectService.toCanonicalFileName, computeHash: function (data) { return _this.projectService.host.createHash(data); } }); } }; Project.prototype.shouldEmitFile = function (scriptInfo) { return scriptInfo && !scriptInfo.isDynamicOrHasMixedContent(); }; Project.prototype.getCompileOnSaveAffectedFileList = function (scriptInfo) { var _this = this; if (!this.languageServiceEnabled) { return []; } this.updateGraph(); this.ensureBuilder(); return ts.mapDefined(this.builder.getFilesAffectedBy(this.program, scriptInfo.path), function (sourceFile) { return _this.shouldEmitFile(_this.projectService.getScriptInfoForPath(sourceFile.path)) ? sourceFile.fileName : undefined; }); }; /** * Returns true if emit was conducted */ Project.prototype.emitFile = function (scriptInfo, writeFile) { if (!this.languageServiceEnabled || !this.shouldEmitFile(scriptInfo)) { return false; } var _a = this.getLanguageService(/*ensureSynchronized*/ false).getEmitOutput(scriptInfo.fileName), emitSkipped = _a.emitSkipped, outputFiles = _a.outputFiles; if (!emitSkipped) { for (var _i = 0, outputFiles_1 = outputFiles; _i < outputFiles_1.length; _i++) { var outputFile = outputFiles_1[_i]; var outputFileAbsoluteFileName = ts.getNormalizedAbsolutePath(outputFile.name, this.currentDirectory); writeFile(outputFileAbsoluteFileName, outputFile.text, outputFile.writeByteOrderMark); } } return !emitSkipped; }; Project.prototype.enableLanguageService = function () { if (this.languageServiceEnabled) { return; } this.languageServiceEnabled = true; this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ true); }; Project.prototype.disableLanguageService = function () { if (!this.languageServiceEnabled) { return; } this.languageService.cleanupSemanticCache(); this.languageServiceEnabled = false; this.resolutionCache.closeTypeRootsWatch(); this.projectService.onUpdateLanguageServiceStateForProject(this, /*languageServiceEnabled*/ false); }; Project.prototype.getProjectName = function () { return this.projectName; }; Project.prototype.getExternalFiles = function () { return server.emptyArray; }; Project.prototype.getSourceFile = function (path) { if (!this.program) { return undefined; } return this.program.getSourceFileByPath(path); }; Project.prototype.close = function () { var _this = this; if (this.program) { // if we have a program - release all files that are enlisted in program but arent root // The releasing of the roots happens later // The project could have pending update remaining and hence the info could be in the files but not in program graph for (var _i = 0, _a = this.program.getSourceFiles(); _i < _a.length; _i++) { var f = _a[_i]; this.detachScriptInfoIfNotRoot(f.fileName); } } // Release external files ts.forEach(this.externalFiles, function (externalFile) { return _this.detachScriptInfoIfNotRoot(externalFile); }); // Always remove root files from the project for (var _b = 0, _c = this.rootFiles; _b < _c.length; _b++) { var root = _c[_b]; root.detachFromProject(this); } this.rootFiles = undefined; this.rootFilesMap = undefined; this.externalFiles = undefined; this.program = undefined; this.builder = undefined; this.resolutionCache.clear(); this.resolutionCache = undefined; this.cachedUnresolvedImportsPerFile = undefined; this.directoryStructureHost = undefined; // Clean up file watchers waiting for missing files if (this.missingFilesMap) { ts.clearMap(this.missingFilesMap, ts.closeFileWatcher); this.missingFilesMap = undefined; } // signal language service to release source files acquired from document registry this.languageService.dispose(); this.languageService = undefined; }; Project.prototype.detachScriptInfoIfNotRoot = function (uncheckedFilename) { var info = this.projectService.getScriptInfo(uncheckedFilename); // We might not find the script info in case its not associated with the project any more // and project graph was not updated (eg delayed update graph in case of files changed/deleted on the disk) if (info && !this.isRoot(info)) { info.detachFromProject(this); } }; Project.prototype.isClosed = function () { return this.rootFiles === undefined; }; Project.prototype.hasRoots = function () { return this.rootFiles && this.rootFiles.length > 0; }; Project.prototype.getRootFiles = function () { return this.rootFiles && this.rootFiles.map(function (info) { return info.fileName; }); }; /*@internal*/ Project.prototype.getRootFilesMap = function () { return this.rootFilesMap; }; Project.prototype.getRootScriptInfos = function () { return this.rootFiles; }; Project.prototype.getScriptInfos = function () { var _this = this; if (!this.languageServiceEnabled) { // if language service is not enabled - return just root files return this.rootFiles; } return ts.map(this.program.getSourceFiles(), function (sourceFile) { var scriptInfo = _this.projectService.getScriptInfoForPath(sourceFile.path); if (!scriptInfo) { ts.Debug.fail("scriptInfo for a file '" + sourceFile.fileName + "' Path: '" + sourceFile.path + "' is missing."); } return scriptInfo; }); }; Project.prototype.getExcludedFiles = function () { return server.emptyArray; }; Project.prototype.getFileNames = function (excludeFilesFromExternalLibraries, excludeConfigFiles) { if (!this.program) { return []; } if (!this.languageServiceEnabled) { // if language service is disabled assume that all files in program are root files + default library var rootFiles = this.getRootFiles(); if (this.compilerOptions) { var defaultLibrary = ts.getDefaultLibFilePath(this.compilerOptions); if (defaultLibrary) { (rootFiles || (rootFiles = [])).push(server.asNormalizedPath(defaultLibrary)); } } return rootFiles; } var result = []; for (var _i = 0, _a = this.program.getSourceFiles(); _i < _a.length; _i++) { var f = _a[_i]; if (excludeFilesFromExternalLibraries && this.program.isSourceFileFromExternalLibrary(f)) { continue; } result.push(server.asNormalizedPath(f.fileName)); } if (!excludeConfigFiles) { var configFile = this.program.getCompilerOptions().configFile; if (configFile) { result.push(server.asNormalizedPath(configFile.fileName)); if (configFile.extendedSourceFiles) { for (var _b = 0, _c = configFile.extendedSourceFiles; _b < _c.length; _b++) { var f = _c[_b]; result.push(server.asNormalizedPath(f)); } } } } return result; }; Project.prototype.hasConfigFile = function (configFilePath) { if (this.program && this.languageServiceEnabled) { var configFile = this.program.getCompilerOptions().configFile; if (configFile) { if (configFilePath === server.asNormalizedPath(configFile.fileName)) { return true; } if (configFile.extendedSourceFiles) { for (var _i = 0, _a = configFile.extendedSourceFiles; _i < _a.length; _i++) { var f = _a[_i]; if (configFilePath === server.asNormalizedPath(f)) { return true; } } } } } return false; }; Project.prototype.containsScriptInfo = function (info) { return this.isRoot(info) || (this.program && this.program.getSourceFileByPath(info.path) !== undefined); }; Project.prototype.containsFile = function (filename, requireOpen) { var info = this.projectService.getScriptInfoForPath(this.toPath(filename)); if (info && (info.isScriptOpen() || !requireOpen)) { return this.containsScriptInfo(info); } }; Project.prototype.isRoot = function (info) { return this.rootFilesMap && this.rootFilesMap.get(info.path) === info; }; // add a root file to project Project.prototype.addRoot = function (info) { ts.Debug.assert(!this.isRoot(info)); this.rootFiles.push(info); this.rootFilesMap.set(info.path, info); info.attachToProject(this); this.markAsDirty(); }; // add a root file that doesnt exist on host Project.prototype.addMissingFileRoot = function (fileName) { var path = this.projectService.toPath(fileName); this.rootFilesMap.set(path, fileName); this.markAsDirty(); }; Project.prototype.removeFile = function (info, fileExists, detachFromProject) { if (this.isRoot(info)) { this.removeRoot(info); } if (fileExists) { // If file is present, just remove the resolutions for the file this.resolutionCache.removeResolutionsOfFile(info.path); } else { this.resolutionCache.invalidateResolutionOfFile(info.path); } this.cachedUnresolvedImportsPerFile.remove(info.path); if (detachFromProject) { info.detachFromProject(this); } this.markAsDirty(); }; Project.prototype.registerFileUpdate = function (fileName) { (this.updatedFileNames || (this.updatedFileNames = ts.createMap())).set(fileName, true); }; Project.prototype.markAsDirty = function () { this.projectStateVersion++; }; Project.prototype.extractUnresolvedImportsFromSourceFile = function (file, result) { var cached = this.cachedUnresolvedImportsPerFile.get(file.path); if (cached) { // found cached result - use it and return for (var _i = 0, cached_2 = cached; _i < cached_2.length; _i++) { var f = cached_2[_i]; result.push(f); } return; } var unresolvedImports; if (file.resolvedModules) { file.resolvedModules.forEach(function (resolvedModule, name) { // pick unresolved non-relative names if (!resolvedModule && !ts.isExternalModuleNameRelative(name)) { // for non-scoped names extract part up-to the first slash // for scoped names - extract up to the second slash var trimmed = name.trim(); var i = trimmed.indexOf("/"); if (i !== -1 && trimmed.charCodeAt(0) === 64 /* at */) { i = trimmed.indexOf("/", i + 1); } if (i !== -1) { trimmed = trimmed.substr(0, i); } (unresolvedImports || (unresolvedImports = [])).push(trimmed); result.push(trimmed); } }); } this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || server.emptyArray); }; /** * Updates set of files that contribute to this project * @returns: true if set of files in the project stays the same and false - otherwise. */ Project.prototype.updateGraph = function () { this.resolutionCache.startRecordingFilesWithChangedResolutions(); var hasChanges = this.updateGraphWorker(); var changedFiles = this.resolutionCache.finishRecordingFilesWithChangedResolutions() || server.emptyArray; for (var _i = 0, changedFiles_1 = changedFiles; _i < changedFiles_1.length; _i++) { var file = changedFiles_1[_i]; // delete cached information for changed files this.cachedUnresolvedImportsPerFile.remove(file); } // update builder only if language service is enabled // otherwise tell it to drop its internal state if (this.languageServiceEnabled) { // 1. no changes in structure, no changes in unresolved imports - do nothing // 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files // (can reuse cached imports for files that were not changed) // 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files // (can reuse cached imports for files that were not changed) // 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch if (hasChanges || changedFiles.length) { var result = []; for (var _a = 0, _b = this.program.getSourceFiles(); _a < _b.length; _a++) { var sourceFile = _b[_a]; this.extractUnresolvedImportsFromSourceFile(sourceFile, result); } this.lastCachedUnresolvedImportsList = server.toDeduplicatedSortedArray(result); } var cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, this.lastCachedUnresolvedImportsList, hasChanges); if (this.setTypings(cachedTypings)) { hasChanges = this.updateGraphWorker() || hasChanges; } if (this.builder) { this.builder.updateProgram(this.program); } } else { this.lastCachedUnresolvedImportsList = undefined; if (this.builder) { this.builder.clear(); } } if (hasChanges) { this.projectStructureVersion++; } return !hasChanges; }; Project.prototype.setTypings = function (typings) { if (ts.arrayIsEqualTo(this.typingFiles, typings)) { return false; } this.typingFiles = typings; this.markAsDirty(); return true; }; Project.prototype.updateGraphWorker = function () { var _this = this; var oldProgram = this.program; ts.Debug.assert(!this.isClosed(), "Called update graph worker of closed project"); this.writeLog("Starting updateGraphWorker: Project: " + this.getProjectName()); var start = ts.timestamp(); this.hasInvalidatedResolution = this.resolutionCache.createHasInvalidatedResolution(); this.resolutionCache.startCachingPerDirectoryResolution(); this.program = this.languageService.getProgram(); this.resolutionCache.finishCachingPerDirectoryResolution(); // bump up the version if // - oldProgram is not set - this is a first time updateGraph is called // - newProgram is different from the old program and structure of the old program was not reused. var hasChanges = !oldProgram || (this.program !== oldProgram && !(oldProgram.structureIsReused & 2 /* Completely */)); this.hasChangedAutomaticTypeDirectiveNames = false; if (hasChanges) { if (oldProgram) { for (var _i = 0, _a = oldProgram.getSourceFiles(); _i < _a.length; _i++) { var f = _a[_i]; if (this.program.getSourceFileByPath(f.path)) { continue; } // new program does not contain this file - detach it from the project this.detachScriptInfoFromProject(f.fileName); } } // Update the missing file paths watcher ts.updateMissingFilePathsWatch(this.program, this.missingFilesMap || (this.missingFilesMap = ts.createMap()), // Watch the missing files function (missingFilePath) { return _this.addMissingFileWatcher(missingFilePath); }); // Watch the type locations that would be added to program as part of automatic type resolutions if (this.languageServiceEnabled) { this.resolutionCache.updateTypeRootsWatch(); } } var oldExternalFiles = this.externalFiles || server.emptyArray; this.externalFiles = this.getExternalFiles(); server.enumerateInsertsAndDeletes(this.externalFiles, oldExternalFiles, // Ensure a ScriptInfo is created for new external files. This is performed indirectly // by the LSHost for files in the program when the program is retrieved above but // the program doesn't contain external files so this must be done explicitly. function (inserted) { var scriptInfo = _this.projectService.getOrCreateScriptInfoNotOpenedByClient(inserted, _this.currentDirectory, _this.directoryStructureHost); scriptInfo.attachToProject(_this); }, function (removed) { return _this.detachScriptInfoFromProject(removed); }, ts.compareStringsCaseSensitive); var elapsed = ts.timestamp() - start; this.writeLog("Finishing updateGraphWorker: Project: " + this.getProjectName() + " structureChanged: " + hasChanges + " Elapsed: " + elapsed + "ms"); return hasChanges; }; Project.prototype.detachScriptInfoFromProject = function (uncheckedFileName) { var scriptInfoToDetach = this.projectService.getScriptInfo(uncheckedFileName); if (scriptInfoToDetach) { scriptInfoToDetach.detachFromProject(this); this.resolutionCache.removeResolutionsOfFile(scriptInfoToDetach.path); } }; Project.prototype.addMissingFileWatcher = function (missingFilePath) { var _this = this; var fileWatcher = this.projectService.watchFile(this.projectService.host, missingFilePath, function (fileName, eventKind) { if (_this.projectKind === ProjectKind.Configured) { _this.directoryStructureHost.addOrDeleteFile(fileName, missingFilePath, eventKind); } if (eventKind === ts.FileWatcherEventKind.Created && _this.missingFilesMap.has(missingFilePath)) { _this.missingFilesMap.delete(missingFilePath); fileWatcher.close(); // When a missing file is created, we should update the graph. _this.projectService.delayUpdateProjectGraphAndInferredProjectsRefresh(_this); } }, "Missing file from program" /* MissingFilePath */, this); return fileWatcher; }; Project.prototype.isWatchedMissingFile = function (path) { return this.missingFilesMap && this.missingFilesMap.has(path); }; Project.prototype.getScriptInfoForNormalizedPath = function (fileName) { var scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(fileName)); if (scriptInfo && !scriptInfo.isAttached(this)) { return server.Errors.ThrowProjectDoesNotContainDocument(fileName, this); } return scriptInfo; }; Project.prototype.getScriptInfo = function (uncheckedFileName) { return this.projectService.getScriptInfo(uncheckedFileName); }; Project.prototype.filesToString = function (writeProjectFileNames) { if (!this.program) { return "\tFiles (0)\n"; } var sourceFiles = this.program.getSourceFiles(); var strBuilder = "\tFiles (" + sourceFiles.length + ")\n"; if (writeProjectFileNames) { for (var _i = 0, sourceFiles_9 = sourceFiles; _i < sourceFiles_9.length; _i++) { var file = sourceFiles_9[_i]; strBuilder += "\t" + file.fileName + "\n"; } } return strBuilder; }; Project.prototype.setCompilerOptions = function (compilerOptions) { if (compilerOptions) { compilerOptions.allowNonTsExtensions = true; if (ts.changesAffectModuleResolution(this.compilerOptions, compilerOptions)) { // reset cached unresolved imports if changes in compiler options affected module resolution this.cachedUnresolvedImportsPerFile.clear(); this.lastCachedUnresolvedImportsList = undefined; } var oldOptions = this.compilerOptions; this.compilerOptions = compilerOptions; this.setInternalCompilerOptionsForEmittingJsFiles(); if (ts.changesAffectModuleResolution(oldOptions, compilerOptions)) { this.resolutionCache.clear(); } this.markAsDirty(); } }; /* @internal */ Project.prototype.getChangesSinceVersion = function (lastKnownVersion) { this.updateGraph(); var info = { projectName: this.getProjectName(), version: this.projectStructureVersion, isInferred: this.projectKind === ProjectKind.Inferred, options: this.getCompilationSettings(), languageServiceDisabled: !this.languageServiceEnabled }; var updatedFileNames = this.updatedFileNames; this.updatedFileNames = undefined; // check if requested version is the same that we have reported last time if (this.lastReportedFileNames && lastKnownVersion === this.lastReportedVersion) { // if current structure version is the same - return info without any changes if (this.projectStructureVersion === this.lastReportedVersion && !updatedFileNames) { return { info: info, projectErrors: this.getGlobalProjectErrors() }; } // compute and return the difference var lastReportedFileNames_1 = this.lastReportedFileNames; var externalFiles = this.getExternalFiles().map(function (f) { return server.toNormalizedPath(f); }); var currentFiles_1 = ts.arrayToSet(this.getFileNames().concat(externalFiles)); var added_1 = []; var removed_1 = []; var updated = updatedFileNames ? ts.arrayFrom(updatedFileNames.keys()) : []; ts.forEachKey(currentFiles_1, function (id) { if (!lastReportedFileNames_1.has(id)) { added_1.push(id); } }); ts.forEachKey(lastReportedFileNames_1, function (id) { if (!currentFiles_1.has(id)) { removed_1.push(id); } }); this.lastReportedFileNames = currentFiles_1; this.lastReportedVersion = this.projectStructureVersion; return { info: info, changes: { added: added_1, removed: removed_1, updated: updated }, projectErrors: this.getGlobalProjectErrors() }; } else { // unknown version - return everything var projectFileNames = this.getFileNames(); var externalFiles = this.getExternalFiles().map(function (f) { return server.toNormalizedPath(f); }); var allFiles = projectFileNames.concat(externalFiles); this.lastReportedFileNames = ts.arrayToSet(allFiles); this.lastReportedVersion = this.projectStructureVersion; return { info: info, files: allFiles, projectErrors: this.getGlobalProjectErrors() }; } }; // remove a root file from project Project.prototype.removeRoot = function (info) { ts.orderedRemoveItem(this.rootFiles, info); this.rootFilesMap.delete(info.path); }; return Project; }()); server.Project = Project; /** * If a file is opened and no tsconfig (or jsconfig) is found, * the file and its imports/references are put into an InferredProject. */ var InferredProject = /** @class */ (function (_super) { __extends(InferredProject, _super); /*@internal*/ function InferredProject(projectService, documentRegistry, compilerOptions, projectRootPath, currentDirectory) { var _this = _super.call(this, InferredProject.newName(), ProjectKind.Inferred, projectService, documentRegistry, /*files*/ undefined, /*languageServiceEnabled*/ true, compilerOptions, /*compileOnSaveEnabled*/ false, projectService.host, currentDirectory) || this; _this._isJsInferredProject = false; _this.projectRootPath = projectRootPath && projectService.toCanonicalFileName(projectRootPath); return _this; } InferredProject.prototype.toggleJsInferredProject = function (isJsInferredProject) { if (isJsInferredProject !== this._isJsInferredProject) { this._isJsInferredProject = isJsInferredProject; this.setCompilerOptions(); } }; InferredProject.prototype.setCompilerOptions = function (options) { // Avoid manipulating the given options directly var newOptions = options ? ts.cloneCompilerOptions(options) : this.getCompilationSettings(); if (!newOptions) { return; } if (this._isJsInferredProject && typeof newOptions.maxNodeModuleJsDepth !== "number") { newOptions.maxNodeModuleJsDepth = 2; } else if (!this._isJsInferredProject) { newOptions.maxNodeModuleJsDepth = undefined; } newOptions.allowJs = true; _super.prototype.setCompilerOptions.call(this, newOptions); }; InferredProject.prototype.addRoot = function (info) { ts.Debug.assert(info.isScriptOpen()); this.projectService.startWatchingConfigFilesForInferredProjectRoot(info, this.projectService.openFiles.get(info.path)); if (!this._isJsInferredProject && info.isJavaScript()) { this.toggleJsInferredProject(/*isJsInferredProject*/ true); } _super.prototype.addRoot.call(this, info); }; InferredProject.prototype.removeRoot = function (info) { this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info); _super.prototype.removeRoot.call(this, info); if (this._isJsInferredProject && info.isJavaScript()) { if (ts.every(this.getRootScriptInfos(), function (rootInfo) { return !rootInfo.isJavaScript(); })) { this.toggleJsInferredProject(/*isJsInferredProject*/ false); } } }; InferredProject.prototype.isProjectWithSingleRoot = function () { // - when useSingleInferredProject is not set and projectRootPath is not set, // we can guarantee that this will be the only root // - other wise it has single root if it has single root script info return (!this.projectRootPath && !this.projectService.useSingleInferredProject) || this.getRootScriptInfos().length === 1; }; InferredProject.prototype.close = function () { var _this = this; ts.forEach(this.getRootScriptInfos(), function (info) { return _this.projectService.stopWatchingConfigFilesForInferredProjectRoot(info); }); _super.prototype.close.call(this); }; InferredProject.prototype.getTypeAcquisition = function () { return { enable: allRootFilesAreJsOrDts(this), include: [], exclude: [] }; }; InferredProject.newName = (function () { var nextId = 1; return function () { var id = nextId; nextId++; return server.makeInferredProjectName(id); }; })(); return InferredProject; }(Project)); server.InferredProject = InferredProject; /** * If a file is opened, the server will look for a tsconfig (or jsconfig) * and if successfull create a ConfiguredProject for it. * Otherwise it will create an InferredProject. */ var ConfiguredProject = /** @class */ (function (_super) { __extends(ConfiguredProject, _super); /*@internal*/ function ConfiguredProject(configFileName, projectService, documentRegistry, hasExplicitListOfFiles, compilerOptions, languageServiceEnabled, compileOnSaveEnabled, cachedDirectoryStructureHost) { var _this = _super.call(this, configFileName, ProjectKind.Configured, projectService, documentRegistry, hasExplicitListOfFiles, languageServiceEnabled, compilerOptions, compileOnSaveEnabled, cachedDirectoryStructureHost, ts.getDirectoryPath(configFileName)) || this; _this.compileOnSaveEnabled = compileOnSaveEnabled; _this.plugins = []; /** Ref count to the project when opened from external project */ _this.externalProjectRefCount = 0; _this.canonicalConfigFilePath = server.asNormalizedPath(projectService.toCanonicalFileName(configFileName)); _this.enablePlugins(); return _this; } /** * If the project has reload from disk pending, it reloads (and then updates graph as part of that) instead of just updating the graph * @returns: true if set of files in the project stays the same and false - otherwise. */ ConfiguredProject.prototype.updateGraph = function () { var reloadLevel = this.pendingReload; this.pendingReload = ts.ConfigFileProgramReloadLevel.None; switch (reloadLevel) { case ts.ConfigFileProgramReloadLevel.Partial: return this.projectService.reloadFileNamesOfConfiguredProject(this); case ts.ConfigFileProgramReloadLevel.Full: this.projectService.reloadConfiguredProject(this); return true; default: return _super.prototype.updateGraph.call(this); } }; /*@internal*/ ConfiguredProject.prototype.getCachedDirectoryStructureHost = function () { return this.directoryStructureHost; }; ConfiguredProject.prototype.getConfigFilePath = function () { return server.asNormalizedPath(this.getProjectName()); }; ConfiguredProject.prototype.enablePlugins = function () { var host = this.projectService.host; var options = this.getCompilationSettings(); if (!host.require) { this.projectService.logger.info("Plugins were requested but not running in environment that supports 'require'. Nothing will be loaded"); return; } // Search our peer node_modules, then any globally-specified probe paths // ../../.. to walk from X/node_modules/typescript/lib/tsserver.js to X/node_modules/ var searchPaths = [ts.combinePaths(this.projectService.getExecutingFilePath(), "../../..")].concat(this.projectService.pluginProbeLocations); if (this.projectService.allowLocalPluginLoads) { var local = ts.getDirectoryPath(this.canonicalConfigFilePath); this.projectService.logger.info("Local plugin loading enabled; adding " + local + " to search paths"); searchPaths.unshift(local); } // Enable tsconfig-specified plugins if (options.plugins) { for (var _i = 0, _a = options.plugins; _i < _a.length; _i++) { var pluginConfigEntry = _a[_i]; this.enablePlugin(pluginConfigEntry, searchPaths); } } if (this.projectService.globalPlugins) { var _loop_12 = function (globalPluginName) { // Skip empty names from odd commandline parses if (!globalPluginName) return "continue"; // Skip already-locally-loaded plugins if (options.plugins && options.plugins.some(function (p) { return p.name === globalPluginName; })) return "continue"; // Provide global: true so plugins can detect why they can't find their config this_2.projectService.logger.info("Loading global plugin " + globalPluginName); this_2.enablePlugin({ name: globalPluginName, global: true }, searchPaths); }; var this_2 = this; // Enable global plugins with synthetic configuration entries for (var _b = 0, _c = this.projectService.globalPlugins; _b < _c.length; _b++) { var globalPluginName = _c[_b]; _loop_12(globalPluginName); } } }; ConfiguredProject.prototype.enablePlugin = function (pluginConfigEntry, searchPaths) { var _this = this; this.projectService.logger.info("Enabling plugin " + pluginConfigEntry.name + " from candidate paths: " + searchPaths.join(",")); var log = function (message) { _this.projectService.logger.info(message); }; for (var _i = 0, searchPaths_1 = searchPaths; _i < searchPaths_1.length; _i++) { var searchPath = searchPaths_1[_i]; var resolvedModule = Project.resolveModule(pluginConfigEntry.name, searchPath, this.projectService.host, log); if (resolvedModule) { this.enableProxy(resolvedModule, pluginConfigEntry); return; } } this.projectService.logger.info("Couldn't find " + pluginConfigEntry.name); }; ConfiguredProject.prototype.enableProxy = function (pluginModuleFactory, configEntry) { try { if (typeof pluginModuleFactory !== "function") { this.projectService.logger.info("Skipped loading plugin " + configEntry.name + " because it did expose a proper factory function"); return; } var info = { config: configEntry, project: this, languageService: this.languageService, languageServiceHost: this, serverHost: this.projectService.host }; var pluginModule = pluginModuleFactory({ typescript: ts }); var newLS = pluginModule.create(info); for (var _i = 0, _a = Object.keys(this.languageService); _i < _a.length; _i++) { var k = _a[_i]; if (!(k in newLS)) { this.projectService.logger.info("Plugin activation warning: Missing proxied method " + k + " in created LS. Patching."); newLS[k] = this.languageService[k]; } } this.projectService.logger.info("Plugin validation succeded"); this.languageService = newLS; this.plugins.push(pluginModule); } catch (e) { this.projectService.logger.info("Plugin activation failed: " + e); } }; /** * Get the errors that dont have any file name associated */ ConfiguredProject.prototype.getGlobalProjectErrors = function () { return ts.filter(this.projectErrors, function (diagnostic) { return !diagnostic.file; }) || server.emptyArray; }; /** * Get all the project errors */ ConfiguredProject.prototype.getAllProjectErrors = function () { return this.projectErrors || server.emptyArray; }; ConfiguredProject.prototype.setProjectErrors = function (projectErrors) { this.projectErrors = projectErrors; }; ConfiguredProject.prototype.setTypeAcquisition = function (newTypeAcquisition) { this.typeAcquisition = newTypeAcquisition; }; ConfiguredProject.prototype.getTypeAcquisition = function () { return this.typeAcquisition; }; ConfiguredProject.prototype.getExternalFiles = function () { var _this = this; return server.toSortedArray(ts.flatMap(this.plugins, function (plugin) { if (typeof plugin.getExternalFiles !== "function") return; try { return plugin.getExternalFiles(_this); } catch (e) { _this.projectService.logger.info("A plugin threw an exception in getExternalFiles: " + e); if (e.stack) { _this.projectService.logger.info(e.stack); } } })); }; /*@internal*/ ConfiguredProject.prototype.watchWildcards = function (wildcardDirectories) { var _this = this; ts.updateWatchingWildcardDirectories(this.directoriesWatchedForWildcards || (this.directoriesWatchedForWildcards = ts.createMap()), wildcardDirectories, // Create new directory watcher function (directory, flags) { return _this.projectService.watchWildcardDirectory(directory, flags, _this); }); }; /*@internal*/ ConfiguredProject.prototype.stopWatchingWildCards = function () { if (this.directoriesWatchedForWildcards) { ts.clearMap(this.directoriesWatchedForWildcards, ts.closeFileWatcherOf); this.directoriesWatchedForWildcards = undefined; } }; ConfiguredProject.prototype.close = function () { if (this.configFileWatcher) { this.configFileWatcher.close(); this.configFileWatcher = undefined; } this.stopWatchingWildCards(); this.projectErrors = undefined; this.configFileSpecs = undefined; _super.prototype.close.call(this); }; /* @internal */ ConfiguredProject.prototype.addExternalProjectReference = function () { this.externalProjectRefCount++; }; /* @internal */ ConfiguredProject.prototype.deleteExternalProjectReference = function () { this.externalProjectRefCount--; }; /** Returns true if the project is needed by any of the open script info/external project */ /* @internal */ ConfiguredProject.prototype.hasOpenRef = function () { var _this = this; if (!!this.externalProjectRefCount) { return true; } // Closed project doesnt have any reference if (this.isClosed()) { return false; } var configFileExistenceInfo = this.projectService.getConfigFileExistenceInfo(this); if (this.projectService.hasPendingProjectUpdate(this)) { // If there is pending update for this project, // we dont know if this project would be needed by any of the open files impacted by this config file // In that case keep the project alive if there are open files impacted by this project return !!configFileExistenceInfo.openFilesImpactedByConfigFile.size; } // If there is no pending update for this project, // We know exact set of open files that get impacted by this configured project as the files in the project // The project is referenced only if open files impacted by this project are present in this project return ts.forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, function (_value, infoPath) { return _this.containsScriptInfo(_this.projectService.getScriptInfoForPath(infoPath)); }) || false; }; ConfiguredProject.prototype.getEffectiveTypeRoots = function () { return ts.getEffectiveTypeRoots(this.getCompilationSettings(), this.directoryStructureHost) || []; }; /*@internal*/ ConfiguredProject.prototype.updateErrorOnNoInputFiles = function (hasFileNames) { if (hasFileNames) { ts.filterMutate(this.projectErrors, function (error) { return !ts.isErrorNoInputFiles(error); }); } else if (!this.configFileSpecs.filesSpecs && !ts.some(this.projectErrors, ts.isErrorNoInputFiles)) { this.projectErrors.push(ts.getErrorForNoInputFiles(this.configFileSpecs, this.getConfigFilePath())); } }; return ConfiguredProject; }(Project)); server.ConfiguredProject = ConfiguredProject; /** * Project whose configuration is handled externally, such as in a '.csproj'. * These are created only if a host explicitly calls `openExternalProject`. */ var ExternalProject = /** @class */ (function (_super) { __extends(ExternalProject, _super); /*@internal*/ function ExternalProject(externalProjectName, projectService, documentRegistry, compilerOptions, languageServiceEnabled, compileOnSaveEnabled, projectFilePath) { var _this = _super.call(this, externalProjectName, ProjectKind.External, projectService, documentRegistry, /*hasExplicitListOfFiles*/ true, languageServiceEnabled, compilerOptions, compileOnSaveEnabled, projectService.host, ts.getDirectoryPath(projectFilePath || ts.normalizeSlashes(externalProjectName))) || this; _this.externalProjectName = externalProjectName; _this.compileOnSaveEnabled = compileOnSaveEnabled; _this.excludedFiles = []; return _this; } ExternalProject.prototype.getExcludedFiles = function () { return this.excludedFiles; }; ExternalProject.prototype.getTypeAcquisition = function () { return this.typeAcquisition; }; ExternalProject.prototype.setTypeAcquisition = function (newTypeAcquisition) { ts.Debug.assert(!!newTypeAcquisition, "newTypeAcquisition may not be null/undefined"); ts.Debug.assert(!!newTypeAcquisition.include, "newTypeAcquisition.include may not be null/undefined"); ts.Debug.assert(!!newTypeAcquisition.exclude, "newTypeAcquisition.exclude may not be null/undefined"); ts.Debug.assert(typeof newTypeAcquisition.enable === "boolean", "newTypeAcquisition.enable may not be null/undefined"); this.typeAcquisition = newTypeAcquisition; }; return ExternalProject; }(Project)); server.ExternalProject = ExternalProject; })(server = ts.server || (ts.server = {})); })(ts || (ts = {})); /// /// /// /// /// /// /// var ts; (function (ts) { var server; (function (server) { server.maxProgramSizeForNonTsFiles = 20 * 1024 * 1024; // tslint:disable variable-name server.ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground"; server.ConfigFileDiagEvent = "configFileDiag"; server.ProjectLanguageServiceStateEvent = "projectLanguageServiceState"; server.ProjectInfoTelemetryEvent = "projectInfo"; function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions) { var map = ts.createMap(); for (var _i = 0, commandLineOptions_1 = commandLineOptions; _i < commandLineOptions_1.length; _i++) { var option = commandLineOptions_1[_i]; if (typeof option.type === "object") { var optionMap = option.type; // verify that map contains only numbers optionMap.forEach(function (value) { ts.Debug.assert(typeof value === "number"); }); map.set(option.name, optionMap); } } return map; } var compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(ts.optionDeclarations); var indentStyle = ts.createMapFromTemplate({ none: ts.IndentStyle.None, block: ts.IndentStyle.Block, smart: ts.IndentStyle.Smart }); /** * How to understand this block: * * The 'match' property is a regexp that matches a filename. * * If 'match' is successful, then: * * All files from 'exclude' are removed from the project. See below. * * All 'types' are included in ATA * * What the heck is 'exclude' ? * * An array of an array of strings and numbers * * Each array is: * * An array of strings and numbers * * The strings are literals * * The numbers refer to capture group indices from the 'match' regexp * * Remember that '1' is the first group * * These are concatenated together to form a new regexp * * Filenames matching these regexps are excluded from the project * This default value is tested in tsserverProjectSystem.ts; add tests there * if you are changing this so that you can be sure your regexp works! */ var defaultTypeSafeList = { "jquery": { // jquery files can have names like "jquery-1.10.2.min.js" (or "jquery.intellisense.js") match: /jquery(-(\.?\d+)+)?(\.intellisense)?(\.min)?\.js$/i, types: ["jquery"] }, "WinJS": { // e.g. c:/temp/UWApp1/lib/winjs-4.0.1/js/base.js match: /^(.*\/winjs-[.\d]+)\/js\/base\.js$/i, exclude: [["^", 1, "/.*"]], types: ["winjs"] // And fetch the @types package for WinJS }, "Kendo": { // e.g. /Kendo3/wwwroot/lib/kendo/kendo.all.min.js match: /^(.*\/kendo(-ui)?)\/kendo\.all(\.min)?\.js$/i, exclude: [["^", 1, "/.*"]], types: ["kendo-ui"] }, "Office Nuget": { // e.g. /scripts/Office/1/excel-15.debug.js match: /^(.*\/office\/1)\/excel-\d+\.debug\.js$/i, exclude: [["^", 1, "/.*"]], types: ["office"] // @types package to fetch instead }, "References": { match: /^(.*\/_references\.js)$/i, exclude: [["^", 1, "$"]] } }; function convertFormatOptions(protocolOptions) { if (ts.isString(protocolOptions.indentStyle)) { protocolOptions.indentStyle = indentStyle.get(protocolOptions.indentStyle.toLowerCase()); ts.Debug.assert(protocolOptions.indentStyle !== undefined); } return protocolOptions; } server.convertFormatOptions = convertFormatOptions; function convertCompilerOptions(protocolOptions) { compilerOptionConverters.forEach(function (mappedValues, id) { var propertyValue = protocolOptions[id]; if (ts.isString(propertyValue)) { protocolOptions[id] = mappedValues.get(propertyValue.toLowerCase()); } }); return protocolOptions; } server.convertCompilerOptions = convertCompilerOptions; function tryConvertScriptKindName(scriptKindName) { return ts.isString(scriptKindName) ? convertScriptKindName(scriptKindName) : scriptKindName; } server.tryConvertScriptKindName = tryConvertScriptKindName; function convertScriptKindName(scriptKindName) { switch (scriptKindName) { case "JS": return 1 /* JS */; case "JSX": return 2 /* JSX */; case "TS": return 3 /* TS */; case "TSX": return 4 /* TSX */; default: return 0 /* Unknown */; } } server.convertScriptKindName = convertScriptKindName; /** * This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project. */ function combineProjectOutput(projects, action, comparer, areEqual) { var outputs = ts.flatMap(projects, action); return comparer ? ts.sortAndDeduplicate(outputs, comparer, areEqual) : ts.deduplicate(outputs, areEqual); } server.combineProjectOutput = combineProjectOutput; var fileNamePropertyReader = { getFileName: function (x) { return x; }, getScriptKind: function (fileName, extraFileExtensions) { var result; if (extraFileExtensions) { var fileExtension_1 = ts.getAnyExtensionFromPath(fileName); if (fileExtension_1) { ts.some(extraFileExtensions, function (info) { if (info.extension === fileExtension_1) { result = info.scriptKind; return true; } return false; }); } } return result; }, hasMixedContent: function (fileName, extraFileExtensions) { return ts.some(extraFileExtensions, function (ext) { return ext.isMixedContent && ts.fileExtensionIs(fileName, ext.extension); }); }, }; var externalFilePropertyReader = { getFileName: function (x) { return x.fileName; }, getScriptKind: function (x) { return tryConvertScriptKindName(x.scriptKind); }, hasMixedContent: function (x) { return x.hasMixedContent; }, }; function findProjectByName(projectName, projects) { for (var _i = 0, projects_2 = projects; _i < projects_2.length; _i++) { var proj = projects_2[_i]; if (proj.getProjectName() === projectName) { return proj; } } } /* @internal */ var WatchType; (function (WatchType) { WatchType["ConfigFilePath"] = "Config file for the program"; WatchType["MissingFilePath"] = "Missing file from program"; WatchType["WildcardDirectories"] = "Wild card directory"; WatchType["ClosedScriptInfo"] = "Closed Script info"; WatchType["ConfigFileForInferredRoot"] = "Config file for the inferred project root"; WatchType["FailedLookupLocation"] = "Directory of Failed lookup locations in module resolution"; WatchType["TypeRoots"] = "Type root directory"; })(WatchType = server.WatchType || (server.WatchType = {})); var ConfigFileWatcherStatus; (function (ConfigFileWatcherStatus) { ConfigFileWatcherStatus["ReloadingFiles"] = "Reloading configured projects for files"; ConfigFileWatcherStatus["ReloadingInferredRootFiles"] = "Reloading configured projects for only inferred root files"; ConfigFileWatcherStatus["UpdatedCallback"] = "Updated the callback"; ConfigFileWatcherStatus["OpenFilesImpactedByConfigFileAdd"] = "File added to open files impacted by this config file"; ConfigFileWatcherStatus["OpenFilesImpactedByConfigFileRemove"] = "File removed from open files impacted by this config file"; ConfigFileWatcherStatus["RootOfInferredProjectTrue"] = "Open file was set as Inferred root"; ConfigFileWatcherStatus["RootOfInferredProjectFalse"] = "Open file was set as not inferred root"; })(ConfigFileWatcherStatus || (ConfigFileWatcherStatus = {})); var ProjectService = /** @class */ (function () { function ProjectService(opts) { var _this = this; /** * Container of all known scripts */ this.filenameToScriptInfo = ts.createMap(); /** * maps external project file name to list of config files that were the part of this project */ this.externalProjectToConfiguredProjectMap = ts.createMap(); /** * external projects (configuration and list of root files is not controlled by tsserver) */ this.externalProjects = []; /** * projects built from openFileRoots */ this.inferredProjects = []; /** * projects specified by a tsconfig.json file */ this.configuredProjects = ts.createMap(); /** * Open files: with value being project root path, and key being Path of the file that is open */ this.openFiles = ts.createMap(); /** * Map of open files that are opened without complete path but have projectRoot as current directory */ this.openFilesWithNonRootedDiskPath = ts.createMap(); this.compilerOptionsForInferredProjectsPerProjectRoot = ts.createMap(); /** * Project size for configured or external projects */ this.projectToSizeMap = ts.createMap(); /** * This is a map of config file paths existance that doesnt need query to disk * - The entry can be present because there is inferred project that needs to watch addition of config file to directory * In this case the exists could be true/false based on config file is present or not * - Or it is present if we have configured project open with config file at that location * In this case the exists property is always true */ this.configFileExistenceInfoCache = ts.createMap(); this.safelist = defaultTypeSafeList; this.legacySafelist = {}; this.pendingProjectUpdates = ts.createMap(); /** Tracks projects that we have already sent telemetry for. */ this.seenProjects = ts.createMap(); this.host = opts.host; this.logger = opts.logger; this.cancellationToken = opts.cancellationToken; this.useSingleInferredProject = opts.useSingleInferredProject; this.useInferredProjectPerProjectRoot = opts.useInferredProjectPerProjectRoot; this.typingsInstaller = opts.typingsInstaller || server.nullTypingsInstaller; this.throttleWaitMilliseconds = opts.throttleWaitMilliseconds; this.eventHandler = opts.eventHandler; this.globalPlugins = opts.globalPlugins || server.emptyArray; this.pluginProbeLocations = opts.pluginProbeLocations || server.emptyArray; this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads; this.typesMapLocation = (opts.typesMapLocation === undefined) ? ts.combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation; ts.Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService"); this.currentDirectory = this.host.getCurrentDirectory(); this.toCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames); this.throttledOperations = new server.ThrottledOperations(this.host, this.logger); if (this.typesMapLocation) { this.loadTypesMap(); } else { this.logger.info("No types map provided; using the default"); } this.typingsInstaller.attach(this); this.typingsCache = new server.TypingsCache(this.typingsInstaller); this.hostConfiguration = { formatCodeOptions: server.getDefaultFormatCodeSettings(this.host), hostInfo: "Unknown host", extraFileExtensions: [] }; this.documentRegistry = ts.createDocumentRegistry(this.host.useCaseSensitiveFileNames, this.currentDirectory); if (this.logger.hasLevel(server.LogLevel.verbose)) { this.watchFile = function (host, file, cb, watchType, project) { return ts.addFileWatcherWithLogging(host, file, cb, _this.createWatcherLog(watchType, project)); }; this.watchFilePath = function (host, file, cb, path, watchType, project) { return ts.addFilePathWatcherWithLogging(host, file, cb, path, _this.createWatcherLog(watchType, project)); }; this.watchDirectory = function (host, dir, cb, flags, watchType, project) { return ts.addDirectoryWatcherWithLogging(host, dir, cb, flags, _this.createWatcherLog(watchType, project)); }; } else if (this.logger.loggingEnabled()) { this.watchFile = function (host, file, cb, watchType, project) { return ts.addFileWatcherWithOnlyTriggerLogging(host, file, cb, _this.createWatcherLog(watchType, project)); }; this.watchFilePath = function (host, file, cb, path, watchType, project) { return ts.addFilePathWatcherWithOnlyTriggerLogging(host, file, cb, path, _this.createWatcherLog(watchType, project)); }; this.watchDirectory = function (host, dir, cb, flags, watchType, project) { return ts.addDirectoryWatcherWithOnlyTriggerLogging(host, dir, cb, flags, _this.createWatcherLog(watchType, project)); }; } else { this.watchFile = ts.addFileWatcher; this.watchFilePath = ts.addFilePathWatcher; this.watchDirectory = ts.addDirectoryWatcher; } } ProjectService.prototype.createWatcherLog = function (watchType, project) { var _this = this; var detailedInfo = " Project: " + (project ? project.getProjectName() : "") + " WatchType: " + watchType; return function (s) { return _this.logger.info(s + detailedInfo); }; }; ProjectService.prototype.toPath = function (fileName) { return ts.toPath(fileName, this.currentDirectory, this.toCanonicalFileName); }; /*@internal*/ ProjectService.prototype.getExecutingFilePath = function () { return this.getNormalizedAbsolutePath(this.host.getExecutingFilePath()); }; /*@internal*/ ProjectService.prototype.getNormalizedAbsolutePath = function (fileName) { return ts.getNormalizedAbsolutePath(fileName, this.host.getCurrentDirectory()); }; /* @internal */ ProjectService.prototype.getChangedFiles_TestOnly = function () { return this.changedFiles; }; /* @internal */ ProjectService.prototype.ensureInferredProjectsUpToDate_TestOnly = function () { this.ensureProjectStructuresUptoDate(); }; /* @internal */ ProjectService.prototype.getCompilerOptionsForInferredProjects = function () { return this.compilerOptionsForInferredProjects; }; /* @internal */ ProjectService.prototype.onUpdateLanguageServiceStateForProject = function (project, languageServiceEnabled) { if (!this.eventHandler) { return; } var event = { eventName: server.ProjectLanguageServiceStateEvent, data: { project: project, languageServiceEnabled: languageServiceEnabled } }; this.eventHandler(event); }; ProjectService.prototype.loadTypesMap = function () { try { var fileContent = this.host.readFile(this.typesMapLocation); if (fileContent === undefined) { this.logger.info("Provided types map file \"" + this.typesMapLocation + "\" doesn't exist"); return; } var raw = JSON.parse(fileContent); // Parse the regexps for (var _i = 0, _a = Object.keys(raw.typesMap); _i < _a.length; _i++) { var k = _a[_i]; raw.typesMap[k].match = new RegExp(raw.typesMap[k].match, "i"); } // raw is now fixed and ready this.safelist = raw.typesMap; for (var key in raw.simpleMap) { if (raw.simpleMap.hasOwnProperty(key)) { this.legacySafelist[key] = raw.simpleMap[key].toLowerCase(); } } } catch (e) { this.logger.info("Error loading types map: " + e); this.safelist = defaultTypeSafeList; this.legacySafelist = {}; } }; ProjectService.prototype.updateTypingsForProject = function (response) { var project = this.findProject(response.projectName); if (!project) { return; } switch (response.kind) { case server.ActionSet: this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typeAcquisition, response.unresolvedImports, response.typings); break; case server.ActionInvalidate: this.typingsCache.deleteTypingsForProject(response.projectName); break; } this.delayUpdateProjectGraphAndInferredProjectsRefresh(project); }; ProjectService.prototype.delayInferredProjectsRefresh = function () { var _this = this; this.pendingInferredProjectUpdate = true; this.throttledOperations.schedule("*refreshInferredProjects*", /*delay*/ 250, function () { if (_this.pendingProjectUpdates.size !== 0) { _this.delayInferredProjectsRefresh(); } else { if (_this.pendingInferredProjectUpdate) { _this.pendingInferredProjectUpdate = false; _this.refreshInferredProjects(); } // Send the event to notify that there were background project updates // send current list of open files _this.sendProjectsUpdatedInBackgroundEvent(); } }); }; ProjectService.prototype.delayUpdateProjectGraph = function (project) { var _this = this; var projectName = project.getProjectName(); this.pendingProjectUpdates.set(projectName, project); this.throttledOperations.schedule(projectName, /*delay*/ 250, function () { if (_this.pendingProjectUpdates.delete(projectName)) { project.updateGraph(); } }); }; /*@internal*/ ProjectService.prototype.hasPendingProjectUpdate = function (project) { return this.pendingProjectUpdates.has(project.getProjectName()); }; ProjectService.prototype.sendProjectsUpdatedInBackgroundEvent = function () { var _this = this; if (!this.eventHandler) { return; } var event = { eventName: server.ProjectsUpdatedInBackgroundEvent, data: { openFiles: ts.arrayFrom(this.openFiles.keys(), function (path) { return _this.getScriptInfoForPath(path).fileName; }) } }; this.eventHandler(event); }; /* @internal */ ProjectService.prototype.delayUpdateProjectGraphAndInferredProjectsRefresh = function (project) { project.markAsDirty(); this.delayUpdateProjectGraph(project); this.delayInferredProjectsRefresh(); }; ProjectService.prototype.delayUpdateProjectGraphs = function (projects) { for (var _i = 0, projects_3 = projects; _i < projects_3.length; _i++) { var project = projects_3[_i]; this.delayUpdateProjectGraph(project); } this.delayInferredProjectsRefresh(); }; ProjectService.prototype.setCompilerOptionsForInferredProjects = function (projectCompilerOptions, projectRootPath) { ts.Debug.assert(projectRootPath === undefined || this.useInferredProjectPerProjectRoot, "Setting compiler options per project root path is only supported when useInferredProjectPerProjectRoot is enabled"); var compilerOptions = convertCompilerOptions(projectCompilerOptions); // always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside // previously we did not expose a way for user to change these settings and this option was enabled by default compilerOptions.allowNonTsExtensions = true; var canonicalProjectRootPath = projectRootPath && this.toCanonicalFileName(projectRootPath); if (canonicalProjectRootPath) { this.compilerOptionsForInferredProjectsPerProjectRoot.set(canonicalProjectRootPath, compilerOptions); } else { this.compilerOptionsForInferredProjects = compilerOptions; } var projectsToUpdate = []; for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { var project = _a[_i]; // Only update compiler options in the following cases: // - Inferred projects without a projectRootPath, if the new options do not apply to // a workspace root // - Inferred projects with a projectRootPath, if the new options do not apply to a // workspace root and there is no more specific set of options for that project's // root path // - Inferred projects with a projectRootPath, if the new options apply to that // project root path. if (canonicalProjectRootPath ? project.projectRootPath === canonicalProjectRootPath : !project.projectRootPath || !this.compilerOptionsForInferredProjectsPerProjectRoot.has(project.projectRootPath)) { project.setCompilerOptions(compilerOptions); project.compileOnSaveEnabled = compilerOptions.compileOnSave; project.markAsDirty(); projectsToUpdate.push(project); } } this.delayUpdateProjectGraphs(projectsToUpdate); }; ProjectService.prototype.findProject = function (projectName) { if (projectName === undefined) { return undefined; } if (server.isInferredProjectName(projectName)) { this.ensureProjectStructuresUptoDate(); return findProjectByName(projectName, this.inferredProjects); } return this.findExternalProjectByProjectName(projectName) || this.findConfiguredProjectByProjectName(server.toNormalizedPath(projectName)); }; ProjectService.prototype.getDefaultProjectForFile = function (fileName, ensureProject) { var scriptInfo = this.getScriptInfoForNormalizedPath(fileName); if (ensureProject && !scriptInfo || scriptInfo.isOrphan()) { this.ensureProjectStructuresUptoDate(); scriptInfo = this.getScriptInfoForNormalizedPath(fileName); if (!scriptInfo) { return server.Errors.ThrowNoProject(); } return scriptInfo.getDefaultProject(); } return scriptInfo && !scriptInfo.isOrphan() && scriptInfo.getDefaultProject(); }; ProjectService.prototype.getScriptInfoEnsuringProjectsUptoDate = function (uncheckedFileName) { this.ensureProjectStructuresUptoDate(); return this.getScriptInfo(uncheckedFileName); }; /** * Ensures the project structures are upto date * This means, * - if there are changedFiles (the files were updated but their containing project graph was not upto date), * their project graph is updated * - If there are pendingProjectUpdates (scheduled to be updated with delay so they can batch update the graph if there are several changes in short time span) * their project graph is updated * - If there were project graph updates and/or there was pending inferred project update and/or called forced the inferred project structure refresh * Inferred projects are created/updated/deleted based on open files states * @param forceInferredProjectsRefresh when true updates the inferred projects even if there is no pending work to update the files/project structures */ ProjectService.prototype.ensureProjectStructuresUptoDate = function (forceInferredProjectsRefresh) { if (this.changedFiles) { var projectsToUpdate = void 0; if (this.changedFiles.length === 1) { // simpliest case - no allocations projectsToUpdate = this.changedFiles[0].containingProjects; } else { projectsToUpdate = []; for (var _i = 0, _a = this.changedFiles; _i < _a.length; _i++) { var f = _a[_i]; ts.addRange(projectsToUpdate, f.containingProjects); } } this.changedFiles = undefined; this.updateProjectGraphs(projectsToUpdate); } if (this.pendingProjectUpdates.size !== 0) { var projectsToUpdate = ts.arrayFrom(this.pendingProjectUpdates.values()); this.pendingProjectUpdates.clear(); this.updateProjectGraphs(projectsToUpdate); } if (this.pendingInferredProjectUpdate || forceInferredProjectsRefresh) { this.pendingInferredProjectUpdate = false; this.refreshInferredProjects(); } }; ProjectService.prototype.findContainingExternalProject = function (fileName) { for (var _i = 0, _a = this.externalProjects; _i < _a.length; _i++) { var proj = _a[_i]; if (proj.containsFile(fileName)) { return proj; } } return undefined; }; ProjectService.prototype.getFormatCodeOptions = function (file) { var formatCodeSettings; if (file) { var info = this.getScriptInfoForNormalizedPath(file); if (info) { formatCodeSettings = info.getFormatCodeSettings(); } } return formatCodeSettings || this.hostConfiguration.formatCodeOptions; }; ProjectService.prototype.updateProjectGraphs = function (projects) { for (var _i = 0, projects_4 = projects; _i < projects_4.length; _i++) { var p = projects_4[_i]; if (!p.updateGraph()) { this.pendingInferredProjectUpdate = true; } } }; ProjectService.prototype.onSourceFileChanged = function (fileName, eventKind) { var info = this.getScriptInfoForNormalizedPath(fileName); if (!info) { this.logger.msg("Error: got watch notification for unknown file: " + fileName); } else if (eventKind === ts.FileWatcherEventKind.Deleted) { // File was deleted this.handleDeletedFile(info); } else if (!info.isScriptOpen()) { if (info.containingProjects.length === 0) { // Orphan script info, remove it as we can always reload it on next open file request this.stopWatchingScriptInfo(info); this.filenameToScriptInfo.delete(info.path); } else { // file has been changed which might affect the set of referenced files in projects that include // this file and set of inferred projects info.delayReloadNonMixedContentFile(); this.delayUpdateProjectGraphs(info.containingProjects); } } }; ProjectService.prototype.handleDeletedFile = function (info) { this.stopWatchingScriptInfo(info); // TODO: handle isOpen = true case if (!info.isScriptOpen()) { this.filenameToScriptInfo.delete(info.path); // capture list of projects since detachAllProjects will wipe out original list var containingProjects = info.containingProjects.slice(); info.detachAllProjects(); // update projects to make sure that set of referenced files is correct this.delayUpdateProjectGraphs(containingProjects); } }; /** * This is to watch whenever files are added or removed to the wildcard directories */ /*@internal*/ ProjectService.prototype.watchWildcardDirectory = function (directory, flags, project) { var _this = this; return this.watchDirectory(this.host, directory, function (fileOrDirectory) { var fileOrDirectoryPath = _this.toPath(fileOrDirectory); project.getCachedDirectoryStructureHost().addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath); var configFilename = project.getConfigFilePath(); // If the the added or created file or directory is not supported file name, ignore the file // But when watched directory is added/removed, we need to reload the file list if (fileOrDirectoryPath !== directory && ts.hasExtension(fileOrDirectoryPath) && !ts.isSupportedSourceFileName(fileOrDirectory, project.getCompilationSettings(), _this.hostConfiguration.extraFileExtensions)) { _this.logger.info("Project: " + configFilename + " Detected file add/remove of non supported extension: " + fileOrDirectory); return; } // Reload is pending, do the reload if (project.pendingReload !== ts.ConfigFileProgramReloadLevel.Full) { project.pendingReload = ts.ConfigFileProgramReloadLevel.Partial; _this.delayUpdateProjectGraphAndInferredProjectsRefresh(project); } }, flags, "Wild card directory" /* WildcardDirectories */, project); }; /** Gets the config file existence info for the configured project */ /*@internal*/ ProjectService.prototype.getConfigFileExistenceInfo = function (project) { return this.configFileExistenceInfoCache.get(project.canonicalConfigFilePath); }; ProjectService.prototype.onConfigChangedForConfiguredProject = function (project, eventKind) { var configFileExistenceInfo = this.getConfigFileExistenceInfo(project); if (eventKind === ts.FileWatcherEventKind.Deleted) { // Update the cached status // We arent updating or removing the cached config file presence info as that will be taken care of by // setConfigFilePresenceByClosedConfigFile when the project is closed (depending on tracking open files) configFileExistenceInfo.exists = false; this.removeProject(project); // Reload the configured projects for the open files in the map as they are affectected by this config file // Since the configured project was deleted, we want to reload projects for all the open files including files // that are not root of the inferred project this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, "Reloading configured projects for files" /* ReloadingFiles */); this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ false); } else { this.logConfigFileWatchUpdate(project.getConfigFilePath(), project.canonicalConfigFilePath, configFileExistenceInfo, "Reloading configured projects for only inferred root files" /* ReloadingInferredRootFiles */); project.pendingReload = ts.ConfigFileProgramReloadLevel.Full; this.delayUpdateProjectGraph(project); // As we scheduled the update on configured project graph, // we would need to schedule the project reload for only the root of inferred projects this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ true); } }; /** * This is the callback function for the config file add/remove/change at any location * that matters to open script info but doesnt have configured project open * for the config file */ ProjectService.prototype.onConfigFileChangeForOpenScriptInfo = function (configFileName, eventKind) { // This callback is called only if we dont have config file project for this config file var canonicalConfigPath = server.normalizedPathToPath(configFileName, this.currentDirectory, this.toCanonicalFileName); var configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigPath); configFileExistenceInfo.exists = (eventKind !== ts.FileWatcherEventKind.Deleted); this.logConfigFileWatchUpdate(configFileName, canonicalConfigPath, configFileExistenceInfo, "Reloading configured projects for files" /* ReloadingFiles */); // Because there is no configured project open for the config file, the tracking open files map // will only have open files that need the re-detection of the project and hence // reload projects for all the tracking open files in the map this.delayReloadConfiguredProjectForFiles(configFileExistenceInfo, /*ignoreIfNotInferredProjectRoot*/ false); }; ProjectService.prototype.removeProject = function (project) { this.logger.info("remove project: " + project.getRootFiles().toString()); project.close(); if (ts.Debug.shouldAssert(1 /* Normal */)) { this.filenameToScriptInfo.forEach(function (info) { return ts.Debug.assert(!info.isAttached(project)); }); } // Remove the project from pending project updates this.pendingProjectUpdates.delete(project.getProjectName()); switch (project.projectKind) { case server.ProjectKind.External: ts.unorderedRemoveItem(this.externalProjects, project); this.projectToSizeMap.delete(project.getProjectName()); break; case server.ProjectKind.Configured: this.configuredProjects.delete(project.canonicalConfigFilePath); this.projectToSizeMap.delete(project.canonicalConfigFilePath); this.setConfigFileExistenceInfoByClosedConfiguredProject(project); break; case server.ProjectKind.Inferred: ts.unorderedRemoveItem(this.inferredProjects, project); break; } }; /*@internal*/ ProjectService.prototype.assignOrphanScriptInfoToInferredProject = function (info, projectRootPath) { ts.Debug.assert(info.isOrphan()); var project = this.getOrCreateInferredProjectForProjectRootPathIfEnabled(info, projectRootPath) || this.getOrCreateSingleInferredProjectIfEnabled() || this.createInferredProject(ts.getDirectoryPath(info.path)); project.addRoot(info); project.updateGraph(); if (!this.useSingleInferredProject && !project.projectRootPath) { // Note that we need to create a copy of the array since the list of project can change for (var _i = 0, _a = this.inferredProjects.slice(0, this.inferredProjects.length - 1); _i < _a.length; _i++) { var inferredProject = _a[_i]; ts.Debug.assert(inferredProject !== project); // Remove the inferred project if the root of it is now part of newly created inferred project // e.g through references // Which means if any root of inferred project is part of more than 1 project can be removed // This logic is same as iterating over all open files and calling // this.removeRootOfInferredProjectIfNowPartOfOtherProject(f); // Since this is also called from refreshInferredProject and closeOpen file // to update inferred projects of the open file, this iteration might be faster // instead of scanning all open files var roots = inferredProject.getRootScriptInfos(); ts.Debug.assert(roots.length === 1 || !!inferredProject.projectRootPath); if (roots.length === 1 && roots[0].containingProjects.length > 1) { this.removeProject(inferredProject); } } } return project; }; /** * Remove this file from the set of open, non-configured files. * @param info The file that has been closed or newly configured */ ProjectService.prototype.closeOpenFile = function (info) { var _this = this; // Closing file should trigger re-reading the file content from disk. This is // because the user may chose to discard the buffer content before saving // to the disk, and the server's version of the file can be out of sync. var fileExists = this.host.fileExists(info.fileName); info.close(fileExists); this.stopWatchingConfigFilesForClosedScriptInfo(info); this.openFiles.delete(info.path); var canonicalFileName = this.toCanonicalFileName(info.fileName); if (this.openFilesWithNonRootedDiskPath.get(canonicalFileName) === info) { this.openFilesWithNonRootedDiskPath.delete(canonicalFileName); } // collect all projects that should be removed var projectsToRemove; for (var _i = 0, _a = info.containingProjects; _i < _a.length; _i++) { var p = _a[_i]; if (p.projectKind === server.ProjectKind.Configured) { if (info.hasMixedContent) { info.registerFileUpdate(); } // Do not remove the project so that we can reuse this project // if it would need to be re-created with next file open } else if (p.projectKind === server.ProjectKind.Inferred && p.isRoot(info)) { // If this was the open root file of inferred project if (p.isProjectWithSingleRoot()) { // - when useSingleInferredProject is not set, we can guarantee that this will be the only root // - other wise remove the project if it is the only root (projectsToRemove || (projectsToRemove = [])).push(p); } else { p.removeFile(info, fileExists, /*detachFromProject*/ true); } } if (!p.languageServiceEnabled) { // if project language service is disabled then we create a program only for open files. // this means that project should be marked as dirty to force rebuilding of the program // on the next request p.markAsDirty(); } } if (projectsToRemove) { for (var _b = 0, projectsToRemove_1 = projectsToRemove; _b < projectsToRemove_1.length; _b++) { var project = projectsToRemove_1[_b]; this.removeProject(project); } // collect orphaned files and assign them to inferred project just like we treat open of a file this.openFiles.forEach(function (projectRootPath, path) { var f = _this.getScriptInfoForPath(path); if (f.isOrphan()) { _this.assignOrphanScriptInfoToInferredProject(f, projectRootPath); } }); // Cleanup script infos that arent part of any project (eg. those could be closed script infos not referenced by any project) // is postponed to next file open so that if file from same project is opened, // we wont end up creating same script infos } // If the current info is being just closed - add the watcher file to track changes // But if file was deleted, handle that part if (fileExists) { this.watchClosedScriptInfo(info); } else { this.handleDeletedFile(info); } }; ProjectService.prototype.deleteOrphanScriptInfoNotInAnyProject = function () { var _this = this; this.filenameToScriptInfo.forEach(function (info) { if (!info.isScriptOpen() && info.isOrphan()) { // if there are not projects that include this script info - delete it _this.stopWatchingScriptInfo(info); _this.filenameToScriptInfo.delete(info.path); } }); }; ProjectService.prototype.configFileExists = function (configFileName, canonicalConfigFilePath, info) { var configFileExistenceInfo = this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (configFileExistenceInfo) { // By default the info would get impacted by presence of config file since its in the detection path // Only adding the info as a root to inferred project will need the existence to be watched by file watcher if (!configFileExistenceInfo.openFilesImpactedByConfigFile.has(info.path)) { configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, false); this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File added to open files impacted by this config file" /* OpenFilesImpactedByConfigFileAdd */); } return configFileExistenceInfo.exists; } // Theoretically we should be adding watch for the directory here itself. // In practice there will be very few scenarios where the config file gets added // somewhere inside the another config file directory. // And technically we could handle that case in configFile's directory watcher in some cases // But given that its a rare scenario it seems like too much overhead. (we werent watching those directories earlier either) // So what we are now watching is: configFile if the configured project corresponding to it is open // Or the whole chain of config files for the roots of the inferred projects // Cache the host value of file exists and add the info to map of open files impacted by this config file var openFilesImpactedByConfigFile = ts.createMap(); openFilesImpactedByConfigFile.set(info.path, false); var exists = this.host.fileExists(configFileName); configFileExistenceInfo = { exists: exists, openFilesImpactedByConfigFile: openFilesImpactedByConfigFile }; this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo); this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File added to open files impacted by this config file" /* OpenFilesImpactedByConfigFileAdd */); return exists; }; ProjectService.prototype.setConfigFileExistenceByNewConfiguredProject = function (project) { var configFileExistenceInfo = this.getConfigFileExistenceInfo(project); if (configFileExistenceInfo) { ts.Debug.assert(configFileExistenceInfo.exists); // close existing watcher if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject) { var configFileName = project.getConfigFilePath(); configFileExistenceInfo.configFileWatcherForRootOfInferredProject.close(); configFileExistenceInfo.configFileWatcherForRootOfInferredProject = undefined; this.logConfigFileWatchUpdate(configFileName, project.canonicalConfigFilePath, configFileExistenceInfo, "Updated the callback" /* UpdatedCallback */); } } else { // We could be in this scenario if project is the configured project tracked by external project // Since that route doesnt check if the config file is present or not this.configFileExistenceInfoCache.set(project.canonicalConfigFilePath, { exists: true, openFilesImpactedByConfigFile: ts.createMap() }); } }; /** * Returns true if the configFileExistenceInfo is needed/impacted by open files that are root of inferred project */ ProjectService.prototype.configFileExistenceImpactsRootOfInferredProject = function (configFileExistenceInfo) { return ts.forEachEntry(configFileExistenceInfo.openFilesImpactedByConfigFile, function (isRootOfInferredProject) { return isRootOfInferredProject; }); }; ProjectService.prototype.setConfigFileExistenceInfoByClosedConfiguredProject = function (closedProject) { var configFileExistenceInfo = this.getConfigFileExistenceInfo(closedProject); ts.Debug.assert(!!configFileExistenceInfo); if (configFileExistenceInfo.openFilesImpactedByConfigFile.size) { var configFileName = closedProject.getConfigFilePath(); // If there are open files that are impacted by this config file existence // but none of them are root of inferred project, the config file watcher will be // created when any of the script infos are added as root of inferred project if (this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)) { ts.Debug.assert(!configFileExistenceInfo.configFileWatcherForRootOfInferredProject); this.createConfigFileWatcherOfConfigFileExistence(configFileName, closedProject.canonicalConfigFilePath, configFileExistenceInfo); } } else { // There is not a single file open thats tracking the status of this config file. Remove from cache this.configFileExistenceInfoCache.delete(closedProject.canonicalConfigFilePath); } }; ProjectService.prototype.logConfigFileWatchUpdate = function (configFileName, canonicalConfigFilePath, configFileExistenceInfo, status) { var _this = this; if (!this.logger.hasLevel(server.LogLevel.verbose)) { return; } var inferredRoots = []; var otherFiles = []; configFileExistenceInfo.openFilesImpactedByConfigFile.forEach(function (isRootOfInferredProject, key) { var info = _this.getScriptInfoForPath(key); (isRootOfInferredProject ? inferredRoots : otherFiles).push(info.fileName); }); var watches = []; if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject) { watches.push("Config file for the inferred project root" /* ConfigFileForInferredRoot */); } if (this.configuredProjects.has(canonicalConfigFilePath)) { watches.push("Config file for the program" /* ConfigFilePath */); } this.logger.info("ConfigFilePresence:: Current Watches: " + watches + ":: File: " + configFileName + " Currently impacted open files: RootsOfInferredProjects: " + inferredRoots + " OtherOpenFiles: " + otherFiles + " Status: " + status); }; /** * Create the watcher for the configFileExistenceInfo */ ProjectService.prototype.createConfigFileWatcherOfConfigFileExistence = function (configFileName, canonicalConfigFilePath, configFileExistenceInfo) { var _this = this; configFileExistenceInfo.configFileWatcherForRootOfInferredProject = this.watchFile(this.host, configFileName, function (_filename, eventKind) { return _this.onConfigFileChangeForOpenScriptInfo(configFileName, eventKind); }, "Config file for the inferred project root" /* ConfigFileForInferredRoot */); this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Updated the callback" /* UpdatedCallback */); }; /** * Close the config file watcher in the cached ConfigFileExistenceInfo * if there arent any open files that are root of inferred project */ ProjectService.prototype.closeConfigFileWatcherOfConfigFileExistenceInfo = function (configFileExistenceInfo) { // Close the config file watcher if there are no more open files that are root of inferred project if (configFileExistenceInfo.configFileWatcherForRootOfInferredProject && !this.configFileExistenceImpactsRootOfInferredProject(configFileExistenceInfo)) { configFileExistenceInfo.configFileWatcherForRootOfInferredProject.close(); configFileExistenceInfo.configFileWatcherForRootOfInferredProject = undefined; } }; /** * This is called on file close, so that we stop watching the config file for this script info */ ProjectService.prototype.stopWatchingConfigFilesForClosedScriptInfo = function (info) { var _this = this; ts.Debug.assert(!info.isScriptOpen()); this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) { var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (configFileExistenceInfo) { var infoIsRootOfInferredProject = configFileExistenceInfo.openFilesImpactedByConfigFile.get(info.path); // Delete the info from map, since this file is no more open configFileExistenceInfo.openFilesImpactedByConfigFile.delete(info.path); _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "File removed from open files impacted by this config file" /* OpenFilesImpactedByConfigFileRemove */); // If the script info was not root of inferred project, // there wont be config file watch open because of this script info if (infoIsRootOfInferredProject) { // But if it is a root, it could be the last script info that is root of inferred project // and hence we would need to close the config file watcher _this.closeConfigFileWatcherOfConfigFileExistenceInfo(configFileExistenceInfo); } // If there are no open files that are impacted by configFileExistenceInfo after closing this script info // there is no configured project present, remove the cached existence info if (!configFileExistenceInfo.openFilesImpactedByConfigFile.size && !_this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) { ts.Debug.assert(!configFileExistenceInfo.configFileWatcherForRootOfInferredProject); _this.configFileExistenceInfoCache.delete(canonicalConfigFilePath); } } }); }; /** * This is called by inferred project whenever script info is added as a root */ /* @internal */ ProjectService.prototype.startWatchingConfigFilesForInferredProjectRoot = function (info, projectRootPath) { var _this = this; ts.Debug.assert(info.isScriptOpen()); this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) { var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (!configFileExistenceInfo) { // Create the cache configFileExistenceInfo = { exists: _this.host.fileExists(configFileName), openFilesImpactedByConfigFile: ts.createMap() }; _this.configFileExistenceInfoCache.set(canonicalConfigFilePath, configFileExistenceInfo); } // Set this file as the root of inferred project configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, true); _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Open file was set as Inferred root" /* RootOfInferredProjectTrue */); // If there is no configured project for this config file, add the file watcher if (!configFileExistenceInfo.configFileWatcherForRootOfInferredProject && !_this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath)) { _this.createConfigFileWatcherOfConfigFileExistence(configFileName, canonicalConfigFilePath, configFileExistenceInfo); } }, projectRootPath); }; /** * This is called by inferred project whenever root script info is removed from it */ /* @internal */ ProjectService.prototype.stopWatchingConfigFilesForInferredProjectRoot = function (info) { var _this = this; this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) { var configFileExistenceInfo = _this.configFileExistenceInfoCache.get(canonicalConfigFilePath); if (configFileExistenceInfo && configFileExistenceInfo.openFilesImpactedByConfigFile.has(info.path)) { ts.Debug.assert(info.isScriptOpen()); // Info is not root of inferred project any more configFileExistenceInfo.openFilesImpactedByConfigFile.set(info.path, false); _this.logConfigFileWatchUpdate(configFileName, canonicalConfigFilePath, configFileExistenceInfo, "Open file was set as not inferred root" /* RootOfInferredProjectFalse */); // Close the config file watcher _this.closeConfigFileWatcherOfConfigFileExistenceInfo(configFileExistenceInfo); } }); }; /** * This function tries to search for a tsconfig.json for the given file. * This is different from the method the compiler uses because * the compiler can assume it will always start searching in the * current directory (the directory in which tsc was invoked). * The server must start searching from the directory containing * the newly opened file. */ ProjectService.prototype.forEachConfigFileLocation = function (info, action, projectRootPath) { var searchPath = server.asNormalizedPath(ts.getDirectoryPath(info.fileName)); while (!projectRootPath || ts.containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames)) { var canonicalSearchPath = server.normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName); var tsconfigFileName = server.asNormalizedPath(ts.combinePaths(searchPath, "tsconfig.json")); var result = action(tsconfigFileName, ts.combinePaths(canonicalSearchPath, "tsconfig.json")); if (result) { return tsconfigFileName; } var jsconfigFileName = server.asNormalizedPath(ts.combinePaths(searchPath, "jsconfig.json")); result = action(jsconfigFileName, ts.combinePaths(canonicalSearchPath, "jsconfig.json")); if (result) { return jsconfigFileName; } var parentPath = server.asNormalizedPath(ts.getDirectoryPath(searchPath)); if (parentPath === searchPath) { break; } searchPath = parentPath; } return undefined; }; /** * This function tries to search for a tsconfig.json for the given file. * This is different from the method the compiler uses because * the compiler can assume it will always start searching in the * current directory (the directory in which tsc was invoked). * The server must start searching from the directory containing * the newly opened file. */ ProjectService.prototype.getConfigFileNameForFile = function (info, projectRootPath) { var _this = this; ts.Debug.assert(info.isScriptOpen()); this.logger.info("Search path: " + ts.getDirectoryPath(info.fileName)); var configFileName = this.forEachConfigFileLocation(info, function (configFileName, canonicalConfigFilePath) { return _this.configFileExists(configFileName, canonicalConfigFilePath, info); }, projectRootPath); if (configFileName) { this.logger.info("For info: " + info.fileName + " :: Config file name: " + configFileName); } else { this.logger.info("For info: " + info.fileName + " :: No config files found."); } return configFileName; }; ProjectService.prototype.printProjects = function () { var _this = this; if (!this.logger.hasLevel(server.LogLevel.normal)) { return; } var writeProjectFileNames = this.logger.hasLevel(server.LogLevel.verbose); this.logger.startGroup(); var counter = 0; var printProjects = function (projects, counter) { for (var _i = 0, projects_5 = projects; _i < projects_5.length; _i++) { var project = projects_5[_i]; _this.logger.info("Project '" + project.getProjectName() + "' (" + server.ProjectKind[project.projectKind] + ") " + counter); _this.logger.info(project.filesToString(writeProjectFileNames)); _this.logger.info("-----------------------------------------------"); counter++; } return counter; }; counter = printProjects(this.externalProjects, counter); counter = printProjects(ts.arrayFrom(this.configuredProjects.values()), counter); printProjects(this.inferredProjects, counter); this.logger.info("Open files: "); this.openFiles.forEach(function (projectRootPath, path) { _this.logger.info("\tFileName: " + _this.getScriptInfoForPath(path).fileName + " ProjectRootPath: " + projectRootPath); }); this.logger.endGroup(); }; ProjectService.prototype.findConfiguredProjectByProjectName = function (configFileName) { // make sure that casing of config file name is consistent var canonicalConfigFilePath = server.asNormalizedPath(this.toCanonicalFileName(configFileName)); return this.getConfiguredProjectByCanonicalConfigFilePath(canonicalConfigFilePath); }; ProjectService.prototype.getConfiguredProjectByCanonicalConfigFilePath = function (canonicalConfigFilePath) { return this.configuredProjects.get(canonicalConfigFilePath); }; ProjectService.prototype.findExternalProjectByProjectName = function (projectFileName) { return findProjectByName(projectFileName, this.externalProjects); }; ProjectService.prototype.convertConfigFileContentToProjectOptions = function (configFilename, cachedDirectoryStructureHost) { configFilename = ts.normalizePath(configFilename); var configFileContent = this.host.readFile(configFilename); var result = ts.parseJsonText(configFilename, configFileContent); if (!result.endOfFileToken) { result.endOfFileToken = { kind: 1 /* EndOfFileToken */ }; } var errors = result.parseDiagnostics; var parsedCommandLine = ts.parseJsonSourceFileConfigFileContent(result, cachedDirectoryStructureHost, ts.getDirectoryPath(configFilename), /*existingOptions*/ {}, configFilename, /*resolutionStack*/ [], this.hostConfiguration.extraFileExtensions); if (parsedCommandLine.errors.length) { errors.push.apply(errors, parsedCommandLine.errors); } ts.Debug.assert(!!parsedCommandLine.fileNames); var projectOptions = { files: parsedCommandLine.fileNames, compilerOptions: parsedCommandLine.options, configHasExtendsProperty: parsedCommandLine.raw.extends !== undefined, configHasFilesProperty: parsedCommandLine.raw.files !== undefined, configHasIncludeProperty: parsedCommandLine.raw.include !== undefined, configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined, wildcardDirectories: ts.createMapFromTemplate(parsedCommandLine.wildcardDirectories), typeAcquisition: parsedCommandLine.typeAcquisition, compileOnSave: parsedCommandLine.compileOnSave }; return { projectOptions: projectOptions, configFileErrors: errors, configFileSpecs: parsedCommandLine.configFileSpecs }; }; ProjectService.prototype.exceededTotalSizeLimitForNonTsFiles = function (name, options, fileNames, propertyReader) { if (options && options.disableSizeLimit || !this.host.getFileSize) { return false; } var availableSpace = server.maxProgramSizeForNonTsFiles; this.projectToSizeMap.set(name, 0); this.projectToSizeMap.forEach(function (val) { return (availableSpace -= (val || 0)); }); var totalNonTsFileSize = 0; for (var _i = 0, fileNames_2 = fileNames; _i < fileNames_2.length; _i++) { var f = fileNames_2[_i]; var fileName = propertyReader.getFileName(f); if (ts.hasTypeScriptFileExtension(fileName)) { continue; } totalNonTsFileSize += this.host.getFileSize(fileName); if (totalNonTsFileSize > server.maxProgramSizeForNonTsFiles) { this.logger.info(getExceedLimitMessage({ propertyReader: propertyReader, hasTypeScriptFileExtension: ts.hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); // Keep the size as zero since it's disabled return true; } } if (totalNonTsFileSize > availableSpace) { this.logger.info(getExceedLimitMessage({ propertyReader: propertyReader, hasTypeScriptFileExtension: ts.hasTypeScriptFileExtension, host: this.host }, totalNonTsFileSize)); return true; } this.projectToSizeMap.set(name, totalNonTsFileSize); return false; function getExceedLimitMessage(context, totalNonTsFileSize) { var files = getTop5LargestFiles(context); return "Non TS file size exceeded limit (" + totalNonTsFileSize + "). Largest files: " + files.map(function (file) { return file.name + ":" + file.size; }).join(", "); } function getTop5LargestFiles(_a) { var propertyReader = _a.propertyReader, hasTypeScriptFileExtension = _a.hasTypeScriptFileExtension, host = _a.host; return fileNames.map(function (f) { return propertyReader.getFileName(f); }) .filter(function (name) { return hasTypeScriptFileExtension(name); }) .map(function (name) { return ({ name: name, size: host.getFileSize(name) }); }) .sort(function (a, b) { return b.size - a.size; }) .slice(0, 5); } }; ProjectService.prototype.createExternalProject = function (projectFileName, files, options, typeAcquisition, excludedFiles) { var compilerOptions = convertCompilerOptions(options); var project = new server.ExternalProject(projectFileName, this, this.documentRegistry, compilerOptions, /*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(projectFileName, compilerOptions, files, externalFilePropertyReader), options.compileOnSave === undefined ? true : options.compileOnSave); project.excludedFiles = excludedFiles; this.addFilesToNonInferredProjectAndUpdateGraph(project, files, externalFilePropertyReader, typeAcquisition); this.externalProjects.push(project); this.sendProjectTelemetry(projectFileName, project); return project; }; ProjectService.prototype.sendProjectTelemetry = function (projectKey, project, projectOptions) { if (this.seenProjects.has(projectKey)) { return; } this.seenProjects.set(projectKey, true); if (!this.eventHandler) { return; } var data = { projectId: this.host.createHash(projectKey), fileStats: server.countEachFileTypes(project.getScriptInfos()), compilerOptions: ts.convertCompilerOptionsForTelemetry(project.getCompilationSettings()), typeAcquisition: convertTypeAcquisition(project.getTypeAcquisition()), extends: projectOptions && projectOptions.configHasExtendsProperty, files: projectOptions && projectOptions.configHasFilesProperty, include: projectOptions && projectOptions.configHasIncludeProperty, exclude: projectOptions && projectOptions.configHasExcludeProperty, compileOnSave: project.compileOnSaveEnabled, configFileName: configFileName(), projectType: project instanceof server.ExternalProject ? "external" : "configured", languageServiceEnabled: project.languageServiceEnabled, version: ts.version, }; this.eventHandler({ eventName: server.ProjectInfoTelemetryEvent, data: data }); function configFileName() { if (!(project instanceof server.ConfiguredProject)) { return "other"; } var configFilePath = project instanceof server.ConfiguredProject && project.getConfigFilePath(); return server.getBaseConfigFileName(configFilePath) || "other"; } function convertTypeAcquisition(_a) { var enable = _a.enable, include = _a.include, exclude = _a.exclude; return { enable: enable, include: include !== undefined && include.length !== 0, exclude: exclude !== undefined && exclude.length !== 0, }; } }; ProjectService.prototype.addFilesToNonInferredProjectAndUpdateGraph = function (project, files, propertyReader, typeAcquisition) { this.updateNonInferredProjectFiles(project, files, propertyReader); project.setTypeAcquisition(typeAcquisition); // This doesnt need scheduling since its either creation or reload of the project project.updateGraph(); }; ProjectService.prototype.createConfiguredProject = function (configFileName) { var _this = this; var cachedDirectoryStructureHost = ts.createCachedDirectoryStructureHost(this.host); var _a = this.convertConfigFileContentToProjectOptions(configFileName, cachedDirectoryStructureHost), projectOptions = _a.projectOptions, configFileErrors = _a.configFileErrors, configFileSpecs = _a.configFileSpecs; this.logger.info("Opened configuration file " + configFileName); var languageServiceEnabled = !this.exceededTotalSizeLimitForNonTsFiles(configFileName, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader); var project = new server.ConfiguredProject(configFileName, this, this.documentRegistry, projectOptions.configHasFilesProperty, projectOptions.compilerOptions, languageServiceEnabled, projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave, cachedDirectoryStructureHost); project.configFileSpecs = configFileSpecs; // TODO: We probably should also watch the configFiles that are extended project.configFileWatcher = this.watchFile(this.host, configFileName, function (_fileName, eventKind) { return _this.onConfigChangedForConfiguredProject(project, eventKind); }, "Config file for the program" /* ConfigFilePath */, project); if (languageServiceEnabled) { project.watchWildcards(projectOptions.wildcardDirectories); } project.setProjectErrors(configFileErrors); var filesToAdd = projectOptions.files.concat(project.getExternalFiles()); this.addFilesToNonInferredProjectAndUpdateGraph(project, filesToAdd, fileNamePropertyReader, projectOptions.typeAcquisition); this.configuredProjects.set(project.canonicalConfigFilePath, project); this.setConfigFileExistenceByNewConfiguredProject(project); this.sendProjectTelemetry(configFileName, project, projectOptions); return project; }; ProjectService.prototype.updateNonInferredProjectFiles = function (project, files, propertyReader) { var projectRootFilesMap = project.getRootFilesMap(); var newRootScriptInfoMap = ts.createMap(); for (var _i = 0, files_3 = files; _i < files_3.length; _i++) { var f = files_3[_i]; var newRootFile = propertyReader.getFileName(f); var normalizedPath = server.toNormalizedPath(newRootFile); var isDynamic = server.isDynamicFileName(normalizedPath); var scriptInfo = void 0; var path = void 0; // Use the project's fileExists so that it can use caching instead of reaching to disk for the query if (!isDynamic && !project.fileExists(newRootFile)) { path = server.normalizedPathToPath(normalizedPath, this.currentDirectory, this.toCanonicalFileName); var existingValue = projectRootFilesMap.get(path); if (server.isScriptInfo(existingValue)) { project.removeFile(existingValue, /*fileExists*/ false, /*detachFromProject*/ true); } projectRootFilesMap.set(path, normalizedPath); scriptInfo = normalizedPath; } else { var scriptKind = propertyReader.getScriptKind(f, this.hostConfiguration.extraFileExtensions); var hasMixedContent = propertyReader.hasMixedContent(f, this.hostConfiguration.extraFileExtensions); scriptInfo = this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(normalizedPath, project.currentDirectory, scriptKind, hasMixedContent, project.directoryStructureHost); path = scriptInfo.path; // If this script info is not already a root add it if (!project.isRoot(scriptInfo)) { project.addRoot(scriptInfo); if (scriptInfo.isScriptOpen()) { // if file is already root in some inferred project // - remove the file from that project and delete the project if necessary this.removeRootOfInferredProjectIfNowPartOfOtherProject(scriptInfo); } } } newRootScriptInfoMap.set(path, scriptInfo); } // project's root file map size is always going to be same or larger than new roots map // as we have already all the new files to the project if (projectRootFilesMap.size > newRootScriptInfoMap.size) { projectRootFilesMap.forEach(function (value, path) { if (!newRootScriptInfoMap.has(path)) { if (server.isScriptInfo(value)) { project.removeFile(value, project.fileExists(path), /*detachFromProject*/ true); } else { projectRootFilesMap.delete(path); } } }); } // Just to ensure that even if root files dont change, the changes to the non root file are picked up, // mark the project as dirty unconditionally project.markAsDirty(); }; ProjectService.prototype.updateNonInferredProject = function (project, newUncheckedFiles, propertyReader, newOptions, newTypeAcquisition, compileOnSave) { project.setCompilerOptions(newOptions); // VS only set the CompileOnSaveEnabled option in the request if the option was changed recently // therefore if it is undefined, it should not be updated. if (compileOnSave !== undefined) { project.compileOnSaveEnabled = compileOnSave; } this.addFilesToNonInferredProjectAndUpdateGraph(project, newUncheckedFiles, propertyReader, newTypeAcquisition); }; /** * Reload the file names from config file specs and update the project graph */ /*@internal*/ ProjectService.prototype.reloadFileNamesOfConfiguredProject = function (project) { var configFileSpecs = project.configFileSpecs; var configFileName = project.getConfigFilePath(); var fileNamesResult = ts.getFileNamesFromConfigSpecs(configFileSpecs, ts.getDirectoryPath(configFileName), project.getCompilationSettings(), project.getCachedDirectoryStructureHost(), this.hostConfiguration.extraFileExtensions); project.updateErrorOnNoInputFiles(fileNamesResult.fileNames.length !== 0); this.updateNonInferredProjectFiles(project, fileNamesResult.fileNames, fileNamePropertyReader); return project.updateGraph(); }; /** * Read the config file of the project again and update the project */ /* @internal */ ProjectService.prototype.reloadConfiguredProject = function (project) { // At this point, there is no reason to not have configFile in the host var host = project.getCachedDirectoryStructureHost(); // Clear the cache since we are reloading the project from disk host.clearCache(); var configFileName = project.getConfigFilePath(); this.logger.info("Reloading configured project " + configFileName); // Read updated contents from disk var _a = this.convertConfigFileContentToProjectOptions(configFileName, host), projectOptions = _a.projectOptions, configFileErrors = _a.configFileErrors, configFileSpecs = _a.configFileSpecs; // Update the project project.configFileSpecs = configFileSpecs; project.setProjectErrors(configFileErrors); if (this.exceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader)) { project.disableLanguageService(); project.stopWatchingWildCards(); } else { project.enableLanguageService(); project.watchWildcards(projectOptions.wildcardDirectories); } this.updateNonInferredProject(project, projectOptions.files, fileNamePropertyReader, projectOptions.compilerOptions, projectOptions.typeAcquisition, projectOptions.compileOnSave); this.sendConfigFileDiagEvent(project, configFileName); }; ProjectService.prototype.sendConfigFileDiagEvent = function (project, triggerFile) { if (!this.eventHandler) { return; } this.eventHandler({ eventName: server.ConfigFileDiagEvent, data: { configFileName: project.getConfigFilePath(), diagnostics: project.getAllProjectErrors(), triggerFile: triggerFile } }); }; ProjectService.prototype.getOrCreateInferredProjectForProjectRootPathIfEnabled = function (info, projectRootPath) { if (!this.useInferredProjectPerProjectRoot) { return undefined; } if (projectRootPath) { var canonicalProjectRootPath = this.toCanonicalFileName(projectRootPath); // if we have an explicit project root path, find (or create) the matching inferred project. for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { var project = _a[_i]; if (project.projectRootPath === canonicalProjectRootPath) { return project; } } return this.createInferredProject(projectRootPath, /*isSingleInferredProject*/ false, projectRootPath); } // we don't have an explicit root path, so we should try to find an inferred project // that more closely contains the file. var bestMatch; for (var _b = 0, _c = this.inferredProjects; _b < _c.length; _b++) { var project = _c[_b]; // ignore single inferred projects (handled elsewhere) if (!project.projectRootPath) continue; // ignore inferred projects that don't contain the root's path if (!ts.containsPath(project.projectRootPath, info.path, this.host.getCurrentDirectory(), !this.host.useCaseSensitiveFileNames)) continue; // ignore inferred projects that are higher up in the project root. // TODO(rbuckton): Should we add the file as a root to these as well? if (bestMatch && bestMatch.projectRootPath.length > project.projectRootPath.length) continue; bestMatch = project; } return bestMatch; }; ProjectService.prototype.getOrCreateSingleInferredProjectIfEnabled = function () { if (!this.useSingleInferredProject) { return undefined; } // If `useInferredProjectPerProjectRoot` is not enabled, then there will only be one // inferred project for all files. If `useInferredProjectPerProjectRoot` is enabled // then we want to put all files that are not opened with a `projectRootPath` into // the same inferred project. // // To avoid the cost of searching through the array and to optimize for the case where // `useInferredProjectPerProjectRoot` is not enabled, we will always put the inferred // project for non-rooted files at the front of the array. if (this.inferredProjects.length > 0 && this.inferredProjects[0].projectRootPath === undefined) { return this.inferredProjects[0]; } // Single inferred project does not have a project root and hence no current directory return this.createInferredProject(/*currentDirectory*/ undefined, /*isSingleInferredProject*/ true); }; ProjectService.prototype.createInferredProject = function (currentDirectory, isSingleInferredProject, projectRootPath) { var compilerOptions = projectRootPath && this.compilerOptionsForInferredProjectsPerProjectRoot.get(projectRootPath) || this.compilerOptionsForInferredProjects; var project = new server.InferredProject(this, this.documentRegistry, compilerOptions, projectRootPath, currentDirectory); if (isSingleInferredProject) { this.inferredProjects.unshift(project); } else { this.inferredProjects.push(project); } return project; }; /*@internal*/ ProjectService.prototype.getOrCreateScriptInfoNotOpenedByClient = function (uncheckedFileName, currentDirectory, hostToQueryFileExistsOn) { return this.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath(server.toNormalizedPath(uncheckedFileName), currentDirectory, /*scriptKind*/ undefined, /*hasMixedContent*/ undefined, hostToQueryFileExistsOn); }; ProjectService.prototype.getScriptInfo = function (uncheckedFileName) { return this.getScriptInfoForNormalizedPath(server.toNormalizedPath(uncheckedFileName)); }; ProjectService.prototype.watchClosedScriptInfo = function (info) { var _this = this; ts.Debug.assert(!info.fileWatcher); // do not watch files with mixed content - server doesn't know how to interpret it if (!info.isDynamicOrHasMixedContent()) { var fileName_2 = info.fileName; info.fileWatcher = this.watchFile(this.host, fileName_2, function (_fileName, eventKind) { return _this.onSourceFileChanged(fileName_2, eventKind); }, "Closed Script info" /* ClosedScriptInfo */); } }; ProjectService.prototype.stopWatchingScriptInfo = function (info) { if (info.fileWatcher) { info.fileWatcher.close(); info.fileWatcher = undefined; } }; /*@internal*/ ProjectService.prototype.getOrCreateScriptInfoNotOpenedByClientForNormalizedPath = function (fileName, currentDirectory, scriptKind, hasMixedContent, hostToQueryFileExistsOn) { return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ false, /*fileContent*/ undefined, scriptKind, hasMixedContent, hostToQueryFileExistsOn); }; /*@internal*/ ProjectService.prototype.getOrCreateScriptInfoOpenedByClientForNormalizedPath = function (fileName, currentDirectory, fileContent, scriptKind, hasMixedContent) { return this.getOrCreateScriptInfoWorker(fileName, currentDirectory, /*openedByClient*/ true, fileContent, scriptKind, hasMixedContent); }; ProjectService.prototype.getOrCreateScriptInfoForNormalizedPath = function (fileName, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) { return this.getOrCreateScriptInfoWorker(fileName, this.currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn); }; ProjectService.prototype.getOrCreateScriptInfoWorker = function (fileName, currentDirectory, openedByClient, fileContent, scriptKind, hasMixedContent, hostToQueryFileExistsOn) { ts.Debug.assert(fileContent === undefined || openedByClient, "ScriptInfo needs to be opened by client to be able to set its user defined content"); var path = server.normalizedPathToPath(fileName, currentDirectory, this.toCanonicalFileName); var info = this.getScriptInfoForPath(path); if (!info) { ts.Debug.assert(ts.isRootedDiskPath(fileName) || openedByClient, "Script info with relative file name can only be open script info"); ts.Debug.assert(!ts.isRootedDiskPath(fileName) || this.currentDirectory === currentDirectory || !this.openFilesWithNonRootedDiskPath.has(this.toCanonicalFileName(fileName)), "Open script files with non rooted disk path opened with current directory context cannot have same canonical names"); var isDynamic = server.isDynamicFileName(fileName); // If the file is not opened by client and the file doesnot exist on the disk, return if (!openedByClient && !isDynamic && !(hostToQueryFileExistsOn || this.host).fileExists(fileName)) { return; } info = new server.ScriptInfo(this.host, fileName, scriptKind, hasMixedContent, path); this.filenameToScriptInfo.set(info.path, info); if (!openedByClient) { this.watchClosedScriptInfo(info); } else if (!ts.isRootedDiskPath(fileName) && currentDirectory !== this.currentDirectory) { // File that is opened by user but isn't rooted disk path this.openFilesWithNonRootedDiskPath.set(this.toCanonicalFileName(fileName), info); } } if (openedByClient && !info.isScriptOpen()) { // Opening closed script info // either it was created just now, or was part of projects but was closed this.stopWatchingScriptInfo(info); info.open(fileContent); if (hasMixedContent) { info.registerFileUpdate(); } } else { ts.Debug.assert(fileContent === undefined); } return info; }; /** * This gets the script info for the normalized path. If the path is not rooted disk path then the open script info with project root context is preferred */ ProjectService.prototype.getScriptInfoForNormalizedPath = function (fileName) { return !ts.isRootedDiskPath(fileName) && this.openFilesWithNonRootedDiskPath.get(this.toCanonicalFileName(fileName)) || this.getScriptInfoForPath(server.normalizedPathToPath(fileName, this.currentDirectory, this.toCanonicalFileName)); }; ProjectService.prototype.getScriptInfoForPath = function (fileName) { return this.filenameToScriptInfo.get(fileName); }; ProjectService.prototype.setHostConfiguration = function (args) { if (args.file) { var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(args.file)); if (info) { info.setFormatOptions(convertFormatOptions(args.formatOptions)); this.logger.info("Host configuration update for file " + args.file); } } else { if (args.hostInfo !== undefined) { this.hostConfiguration.hostInfo = args.hostInfo; this.logger.info("Host information " + args.hostInfo); } if (args.formatOptions) { server.mergeMapLikes(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions)); this.logger.info("Format host information updated"); } if (args.extraFileExtensions) { this.hostConfiguration.extraFileExtensions = args.extraFileExtensions; // We need to update the project structures again as it is possible that existing // project structure could have more or less files depending on extensions permitted this.reloadProjects(); this.logger.info("Host file extension mappings updated"); } } }; ProjectService.prototype.closeLog = function () { this.logger.close(); }; /** * This function rebuilds the project for every file opened by the client * This does not reload contents of open files from disk. But we could do that if needed */ ProjectService.prototype.reloadProjects = function () { this.logger.info("reload projects."); // If we want this to also reload open files from disk, we could do that, // but then we need to make sure we arent calling this function // (and would separate out below reloading of projects to be called when immediate reload is needed) // as there is no need to load contents of the files from the disk // Reload Projects this.reloadConfiguredProjectForFiles(this.openFiles, /*delayReload*/ false, ts.returnTrue); this.refreshInferredProjects(); }; ProjectService.prototype.delayReloadConfiguredProjectForFiles = function (configFileExistenceInfo, ignoreIfNotRootOfInferredProject) { // Get open files to reload projects for this.reloadConfiguredProjectForFiles(configFileExistenceInfo.openFilesImpactedByConfigFile, /*delayReload*/ true, ignoreIfNotRootOfInferredProject ? function (isRootOfInferredProject) { return isRootOfInferredProject; } : // Reload open files if they are root of inferred project ts.returnTrue // Reload all the open files impacted by config file ); this.delayInferredProjectsRefresh(); }; /** * This function goes through all the openFiles and tries to file the config file for them. * If the config file is found and it refers to existing project, it reloads it either immediately * or schedules it for reload depending on delayReload option * If the there is no existing project it just opens the configured project for the config file * reloadForInfo provides a way to filter out files to reload configured project for */ ProjectService.prototype.reloadConfiguredProjectForFiles = function (openFiles, delayReload, shouldReloadProjectFor) { var _this = this; var updatedProjects = ts.createMap(); // try to reload config file for all open files openFiles.forEach(function (openFileValue, path) { // Filter out the files that need to be ignored if (!shouldReloadProjectFor(openFileValue)) { return; } var info = _this.getScriptInfoForPath(path); ts.Debug.assert(info.isScriptOpen()); // This tries to search for a tsconfig.json for the given file. If we found it, // we first detect if there is already a configured project created for it: if so, // we re- read the tsconfig file content and update the project only if we havent already done so // otherwise we create a new one. var configFileName = _this.getConfigFileNameForFile(info, _this.openFiles.get(path)); if (configFileName) { var project = _this.findConfiguredProjectByProjectName(configFileName); if (!project) { _this.createConfiguredProject(configFileName); updatedProjects.set(configFileName, true); } else if (!updatedProjects.has(configFileName)) { if (delayReload) { project.pendingReload = ts.ConfigFileProgramReloadLevel.Full; _this.delayUpdateProjectGraph(project); } else { _this.reloadConfiguredProject(project); } updatedProjects.set(configFileName, true); } } }); }; /** * Remove the root of inferred project if script info is part of another project */ ProjectService.prototype.removeRootOfInferredProjectIfNowPartOfOtherProject = function (info) { // If the script info is root of inferred project, it could only be first containing project // since info is added as root to the inferred project only when there are no other projects containing it // So when it is root of the inferred project and after project structure updates its now part // of multiple project it needs to be removed from that inferred project because: // - references in inferred project supercede the root part // - root / reference in non - inferred project beats root in inferred project // eg. say this is structure /a/b/a.ts /a/b/c.ts where c.ts references a.ts // When a.ts is opened, since there is no configured project/external project a.ts can be part of // a.ts is added as root to inferred project. // Now at time of opening c.ts, c.ts is also not aprt of any existing project, // so it will be added to inferred project as a root. (for sake of this example assume single inferred project is false) // So at this poing a.ts is part of first inferred project and second inferred project (of which c.ts is root) // And hence it needs to be removed from the first inferred project. if (info.containingProjects.length > 1 && info.containingProjects[0].projectKind === server.ProjectKind.Inferred && info.containingProjects[0].isRoot(info)) { var inferredProject = info.containingProjects[0]; if (inferredProject.isProjectWithSingleRoot()) { this.removeProject(inferredProject); } else { inferredProject.removeFile(info, /*fileExists*/ true, /*detachFromProject*/ true); } } }; /** * This function is to update the project structure for every inferred project. * It is called on the premise that all the configured projects are * up to date. * This will go through open files and assign them to inferred project if open file is not part of any other project * After that all the inferred project graphs are updated */ ProjectService.prototype.refreshInferredProjects = function () { var _this = this; this.logger.info("refreshInferredProjects: updating project structure from ..."); this.printProjects(); this.openFiles.forEach(function (projectRootPath, path) { var info = _this.getScriptInfoForPath(path); // collect all orphaned script infos from open files if (info.isOrphan()) { _this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } else { // Or remove the root of inferred project if is referenced in more than one projects _this.removeRootOfInferredProjectIfNowPartOfOtherProject(info); } }); for (var _i = 0, _a = this.inferredProjects; _i < _a.length; _i++) { var p = _a[_i]; p.updateGraph(); } this.logger.info("refreshInferredProjects: updated project structure ..."); this.printProjects(); }; /** * Open file whose contents is managed by the client * @param filename is absolute pathname * @param fileContent is a known version of the file content that is more up to date than the one on disk */ ProjectService.prototype.openClientFile = function (fileName, fileContent, scriptKind, projectRootPath) { return this.openClientFileWithNormalizedPath(server.toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? server.toNormalizedPath(projectRootPath) : undefined); }; ProjectService.prototype.openClientFileWithNormalizedPath = function (fileName, fileContent, scriptKind, hasMixedContent, projectRootPath) { var _this = this; var configFileName; var sendConfigFileDiagEvent = false; var configFileErrors; var info = this.getOrCreateScriptInfoOpenedByClientForNormalizedPath(fileName, projectRootPath ? this.getNormalizedAbsolutePath(projectRootPath) : this.currentDirectory, fileContent, scriptKind, hasMixedContent); var project = this.findContainingExternalProject(fileName); if (!project) { configFileName = this.getConfigFileNameForFile(info, projectRootPath); if (configFileName) { project = this.findConfiguredProjectByProjectName(configFileName); if (!project) { project = this.createConfiguredProject(configFileName); // Send the event only if the project got created as part of this open request sendConfigFileDiagEvent = true; } } } if (project && !project.languageServiceEnabled) { // if project language service is disabled then we create a program only for open files. // this means that project should be marked as dirty to force rebuilding of the program // on the next request project.markAsDirty(); } // At this point if file is part of any any configured or external project, then it would be present in the containing projects // So if it still doesnt have any containing projects, it needs to be part of inferred project if (info.isOrphan()) { // Since the file isnt part of configured project, do not send config file event configFileName = undefined; sendConfigFileDiagEvent = false; this.assignOrphanScriptInfoToInferredProject(info, projectRootPath); } ts.Debug.assert(!info.isOrphan()); this.openFiles.set(info.path, projectRootPath); if (sendConfigFileDiagEvent) { configFileErrors = project.getAllProjectErrors(); this.sendConfigFileDiagEvent(project, fileName); } // Remove the configured projects that have zero references from open files. // This was postponed from closeOpenFile to after opening next file, // so that we can reuse the project if we need to right away this.configuredProjects.forEach(function (project) { if (!project.hasOpenRef()) { _this.removeProject(project); } }); // Delete the orphan files here because there might be orphan script infos (which are not part of project) // when some file/s were closed which resulted in project removal. // It was then postponed to cleanup these script infos so that they can be reused if // the file from that old project is reopened because of opening file from here. this.deleteOrphanScriptInfoNotInAnyProject(); this.printProjects(); return { configFileName: configFileName, configFileErrors: configFileErrors }; }; /** * Close file whose contents is managed by the client * @param filename is absolute pathname */ ProjectService.prototype.closeClientFile = function (uncheckedFileName) { var info = this.getScriptInfoForNormalizedPath(server.toNormalizedPath(uncheckedFileName)); if (info) { this.closeOpenFile(info); } this.printProjects(); }; ProjectService.prototype.collectChanges = function (lastKnownProjectVersions, currentProjects, result) { var _loop_13 = function (proj) { var knownProject = ts.forEach(lastKnownProjectVersions, function (p) { return p.projectName === proj.getProjectName() && p; }); result.push(proj.getChangesSinceVersion(knownProject && knownProject.version)); }; for (var _i = 0, currentProjects_1 = currentProjects; _i < currentProjects_1.length; _i++) { var proj = currentProjects_1[_i]; _loop_13(proj); } }; /* @internal */ ProjectService.prototype.synchronizeProjectList = function (knownProjects) { var files = []; this.collectChanges(knownProjects, this.externalProjects, files); this.collectChanges(knownProjects, ts.arrayFrom(this.configuredProjects.values()), files); this.collectChanges(knownProjects, this.inferredProjects, files); return files; }; /* @internal */ ProjectService.prototype.applyChangesInOpenFiles = function (openFiles, changedFiles, closedFiles) { if (openFiles) { for (var _i = 0, openFiles_1 = openFiles; _i < openFiles_1.length; _i++) { var file = openFiles_1[_i]; var scriptInfo = this.getScriptInfo(file.fileName); ts.Debug.assert(!scriptInfo || !scriptInfo.isScriptOpen(), "Script should not exist and not be open already"); var normalizedPath = scriptInfo ? scriptInfo.fileName : server.toNormalizedPath(file.fileName); this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent); } } if (changedFiles) { for (var _a = 0, changedFiles_2 = changedFiles; _a < changedFiles_2.length; _a++) { var file = changedFiles_2[_a]; var scriptInfo = this.getScriptInfo(file.fileName); ts.Debug.assert(!!scriptInfo); this.applyChangesToFile(scriptInfo, file.changes); } } if (closedFiles) { for (var _b = 0, closedFiles_1 = closedFiles; _b < closedFiles_1.length; _b++) { var file = closedFiles_1[_b]; this.closeClientFile(file); } } // if files were open or closed then explicitly refresh list of inferred projects // otherwise if there were only changes in files - record changed files in `changedFiles` and defer the update if (openFiles || closedFiles) { this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); } }; /* @internal */ ProjectService.prototype.applyChangesToFile = function (scriptInfo, changes) { // apply changes in reverse order for (var i = changes.length - 1; i >= 0; i--) { var change = changes[i]; scriptInfo.editContent(change.span.start, change.span.start + change.span.length, change.newText); } if (!this.changedFiles) { this.changedFiles = [scriptInfo]; } else if (!ts.contains(this.changedFiles, scriptInfo)) { this.changedFiles.push(scriptInfo); } }; ProjectService.prototype.closeConfiguredProjectReferencedFromExternalProject = function (configFile) { var configuredProject = this.findConfiguredProjectByProjectName(configFile); if (configuredProject) { configuredProject.deleteExternalProjectReference(); if (!configuredProject.hasOpenRef()) { this.removeProject(configuredProject); return true; } } return false; }; ProjectService.prototype.closeExternalProject = function (uncheckedFileName, suppressRefresh) { if (suppressRefresh === void 0) { suppressRefresh = false; } var fileName = server.toNormalizedPath(uncheckedFileName); var configFiles = this.externalProjectToConfiguredProjectMap.get(fileName); if (configFiles) { var shouldRefreshInferredProjects = false; for (var _i = 0, configFiles_1 = configFiles; _i < configFiles_1.length; _i++) { var configFile = configFiles_1[_i]; if (this.closeConfiguredProjectReferencedFromExternalProject(configFile)) { shouldRefreshInferredProjects = true; } } this.externalProjectToConfiguredProjectMap.delete(fileName); if (shouldRefreshInferredProjects && !suppressRefresh) { this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); } } else { // close external project var externalProject = this.findExternalProjectByProjectName(uncheckedFileName); if (externalProject) { this.removeProject(externalProject); if (!suppressRefresh) { this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); } } } }; ProjectService.prototype.openExternalProjects = function (projects) { var _this = this; // record project list before the update var projectsToClose = ts.arrayToMap(this.externalProjects, function (p) { return p.getProjectName(); }, function (_) { return true; }); ts.forEachKey(this.externalProjectToConfiguredProjectMap, function (externalProjectName) { projectsToClose.set(externalProjectName, true); }); for (var _i = 0, projects_6 = projects; _i < projects_6.length; _i++) { var externalProject = projects_6[_i]; this.openExternalProject(externalProject, /*suppressRefreshOfInferredProjects*/ true); // delete project that is present in input list projectsToClose.delete(externalProject.projectFileName); } // close projects that were missing in the input list ts.forEachKey(projectsToClose, function (externalProjectName) { _this.closeExternalProject(externalProjectName, /*suppressRefresh*/ true); }); this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); }; ProjectService.escapeFilenameForRegex = function (filename) { return filename.replace(this.filenameEscapeRegexp, "\\$&"); }; ProjectService.prototype.resetSafeList = function () { this.safelist = defaultTypeSafeList; }; ProjectService.prototype.applySafeList = function (proj) { var _this = this; var rootFiles = proj.rootFiles, typeAcquisition = proj.typeAcquisition; ts.Debug.assert(!!typeAcquisition, "proj.typeAcquisition should be set by now"); // If type acquisition has been explicitly disabled, do not exclude anything from the project if (typeAcquisition.enable === false) { return []; } var typeAcqInclude = typeAcquisition.include || (typeAcquisition.include = []); var excludeRules = []; var normalizedNames = rootFiles.map(function (f) { return ts.normalizeSlashes(f.fileName); }); var excludedFiles = []; var _loop_14 = function (name) { var rule = this_3.safelist[name]; for (var _i = 0, normalizedNames_1 = normalizedNames; _i < normalizedNames_1.length; _i++) { var root = normalizedNames_1[_i]; if (rule.match.test(root)) { this_3.logger.info("Excluding files based on rule " + name + " matching file '" + root + "'"); // If the file matches, collect its types packages and exclude rules if (rule.types) { for (var _a = 0, _b = rule.types; _a < _b.length; _a++) { var type = _b[_a]; // Best-effort de-duping here - doesn't need to be unduplicated but // we don't want the list to become a 400-element array of just 'kendo' if (typeAcqInclude.indexOf(type) < 0) { typeAcqInclude.push(type); } } } if (rule.exclude) { var _loop_15 = function (exclude) { var processedRule = root.replace(rule.match, function () { var groups = []; for (var _i = 0; _i < arguments.length; _i++) { groups[_i] = arguments[_i]; } return exclude.map(function (groupNumberOrString) { // RegExp group numbers are 1-based, but the first element in groups // is actually the original string, so it all works out in the end. if (typeof groupNumberOrString === "number") { if (!ts.isString(groups[groupNumberOrString])) { // Specification was wrong - exclude nothing! _this.logger.info("Incorrect RegExp specification in safelist rule " + name + " - not enough groups"); // * can't appear in a filename; escape it because it's feeding into a RegExp return "\\*"; } return ProjectService.escapeFilenameForRegex(groups[groupNumberOrString]); } return groupNumberOrString; }).join(""); }); if (excludeRules.indexOf(processedRule) === -1) { excludeRules.push(processedRule); } }; for (var _c = 0, _d = rule.exclude; _c < _d.length; _c++) { var exclude = _d[_c]; _loop_15(exclude); } } else { // If not rules listed, add the default rule to exclude the matched file var escaped = ProjectService.escapeFilenameForRegex(root); if (excludeRules.indexOf(escaped) < 0) { excludeRules.push(escaped); } } } } }; var this_3 = this; for (var _i = 0, _a = Object.keys(this.safelist); _i < _a.length; _i++) { var name = _a[_i]; _loop_14(name); } var excludeRegexes = excludeRules.map(function (e) { return new RegExp(e, "i"); }); var filesToKeep = []; var _loop_16 = function (i) { if (excludeRegexes.some(function (re) { return re.test(normalizedNames[i]); })) { excludedFiles.push(normalizedNames[i]); } else { var exclude = false; if (typeAcquisition.enable || typeAcquisition.enableAutoDiscovery) { var baseName = ts.getBaseFileName(normalizedNames[i].toLowerCase()); if (ts.fileExtensionIs(baseName, "js")) { var inferredTypingName = ts.removeFileExtension(baseName); var cleanedTypingName = ts.removeMinAndVersionNumbers(inferredTypingName); if (this_4.legacySafelist[cleanedTypingName]) { this_4.logger.info("Excluded '" + normalizedNames[i] + "' because it matched " + cleanedTypingName + " from the legacy safelist"); excludedFiles.push(normalizedNames[i]); // *exclude* it from the project... exclude = true; // ... but *include* it in the list of types to acquire var typeName = this_4.legacySafelist[cleanedTypingName]; // Same best-effort dedupe as above if (typeAcqInclude.indexOf(typeName) < 0) { typeAcqInclude.push(typeName); } } } } if (!exclude) { // Exclude any minified files that get this far if (/^.+[\.-]min\.js$/.test(normalizedNames[i])) { excludedFiles.push(normalizedNames[i]); } else { filesToKeep.push(proj.rootFiles[i]); } } } }; var this_4 = this; for (var i = 0; i < proj.rootFiles.length; i++) { _loop_16(i); } proj.rootFiles = filesToKeep; return excludedFiles; }; ProjectService.prototype.openExternalProject = function (proj, suppressRefreshOfInferredProjects) { if (suppressRefreshOfInferredProjects === void 0) { suppressRefreshOfInferredProjects = false; } // typingOptions has been deprecated and is only supported for backward compatibility // purposes. It should be removed in future releases - use typeAcquisition instead. if (proj.typingOptions && !proj.typeAcquisition) { var typeAcquisition = ts.convertEnableAutoDiscoveryToEnable(proj.typingOptions); proj.typeAcquisition = typeAcquisition; } proj.typeAcquisition = proj.typeAcquisition || {}; proj.typeAcquisition.include = proj.typeAcquisition.include || []; proj.typeAcquisition.exclude = proj.typeAcquisition.exclude || []; if (proj.typeAcquisition.enable === undefined) { proj.typeAcquisition.enable = server.hasNoTypeScriptSource(proj.rootFiles.map(function (f) { return f.fileName; })); } var excludedFiles = this.applySafeList(proj); var tsConfigFiles; var rootFiles = []; for (var _i = 0, _a = proj.rootFiles; _i < _a.length; _i++) { var file = _a[_i]; var normalized = server.toNormalizedPath(file.fileName); if (server.getBaseConfigFileName(normalized)) { if (this.host.fileExists(normalized)) { (tsConfigFiles || (tsConfigFiles = [])).push(normalized); } } else { rootFiles.push(file); } } // sort config files to simplify comparison later if (tsConfigFiles) { tsConfigFiles.sort(); } var externalProject = this.findExternalProjectByProjectName(proj.projectFileName); var exisingConfigFiles; if (externalProject) { externalProject.excludedFiles = excludedFiles; if (!tsConfigFiles) { var compilerOptions = convertCompilerOptions(proj.options); if (this.exceededTotalSizeLimitForNonTsFiles(proj.projectFileName, compilerOptions, proj.rootFiles, externalFilePropertyReader)) { externalProject.disableLanguageService(); } else { externalProject.enableLanguageService(); } // external project already exists and not config files were added - update the project and return; this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, compilerOptions, proj.typeAcquisition, proj.options.compileOnSave); return; } // some config files were added to external project (that previously were not there) // close existing project and later we'll open a set of configured projects for these files this.closeExternalProject(proj.projectFileName, /*suppressRefresh*/ true); } else if (this.externalProjectToConfiguredProjectMap.get(proj.projectFileName)) { // this project used to include config files if (!tsConfigFiles) { // config files were removed from the project - close existing external project which in turn will close configured projects this.closeExternalProject(proj.projectFileName, /*suppressRefresh*/ true); } else { // project previously had some config files - compare them with new set of files and close all configured projects that correspond to unused files var oldConfigFiles = this.externalProjectToConfiguredProjectMap.get(proj.projectFileName); var iNew = 0; var iOld = 0; while (iNew < tsConfigFiles.length && iOld < oldConfigFiles.length) { var newConfig = tsConfigFiles[iNew]; var oldConfig = oldConfigFiles[iOld]; if (oldConfig < newConfig) { this.closeConfiguredProjectReferencedFromExternalProject(oldConfig); iOld++; } else if (oldConfig > newConfig) { iNew++; } else { // record existing config files so avoid extra add-refs (exisingConfigFiles || (exisingConfigFiles = [])).push(oldConfig); iOld++; iNew++; } } for (var i = iOld; i < oldConfigFiles.length; i++) { // projects for all remaining old config files should be closed this.closeConfiguredProjectReferencedFromExternalProject(oldConfigFiles[i]); } } } if (tsConfigFiles) { // store the list of tsconfig files that belong to the external project this.externalProjectToConfiguredProjectMap.set(proj.projectFileName, tsConfigFiles); for (var _b = 0, tsConfigFiles_1 = tsConfigFiles; _b < tsConfigFiles_1.length; _b++) { var tsconfigFile = tsConfigFiles_1[_b]; var project = this.findConfiguredProjectByProjectName(tsconfigFile); if (!project) { // errors are stored in the project project = this.createConfiguredProject(tsconfigFile); } if (project && !ts.contains(exisingConfigFiles, tsconfigFile)) { // keep project alive even if no documents are opened - its lifetime is bound to the lifetime of containing external project project.addExternalProjectReference(); } } } else { // no config files - remove the item from the collection this.externalProjectToConfiguredProjectMap.delete(proj.projectFileName); this.createExternalProject(proj.projectFileName, rootFiles, proj.options, proj.typeAcquisition, excludedFiles); } if (!suppressRefreshOfInferredProjects) { this.ensureProjectStructuresUptoDate(/*refreshInferredProjects*/ true); } }; /** Makes a filename safe to insert in a RegExp */ ProjectService.filenameEscapeRegexp = /[-\/\\^$*+?.()|[\]{}]/g; return ProjectService; }()); server.ProjectService = ProjectService; })(server = ts.server || (ts.server = {})); })(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. // /// /* @internal */ var debugObjectHost = (function () { return this; })(); // We need to use 'null' to interface with the managed side. /* tslint:disable:no-null-keyword */ /* tslint:disable:no-in-operator */ /* @internal */ var ts; (function (ts) { function logInternalError(logger, err) { if (logger) { logger.log("*INTERNAL ERROR* - Exception in typescript services: " + err.message); } } var ScriptSnapshotShimAdapter = /** @class */ (function () { function ScriptSnapshotShimAdapter(scriptSnapshotShim) { this.scriptSnapshotShim = scriptSnapshotShim; } ScriptSnapshotShimAdapter.prototype.getText = function (start, end) { return this.scriptSnapshotShim.getText(start, end); }; ScriptSnapshotShimAdapter.prototype.getLength = function () { return this.scriptSnapshotShim.getLength(); }; ScriptSnapshotShimAdapter.prototype.getChangeRange = function (oldSnapshot) { var oldSnapshotShim = oldSnapshot; var encoded = this.scriptSnapshotShim.getChangeRange(oldSnapshotShim.scriptSnapshotShim); if (encoded === null) { return null; } var decoded = JSON.parse(encoded); return ts.createTextChangeRange(ts.createTextSpan(decoded.span.start, decoded.span.length), decoded.newLength); }; ScriptSnapshotShimAdapter.prototype.dispose = function () { // if scriptSnapshotShim is a COM object then property check becomes method call with no arguments // 'in' does not have this effect if ("dispose" in this.scriptSnapshotShim) { this.scriptSnapshotShim.dispose(); } }; return ScriptSnapshotShimAdapter; }()); var LanguageServiceShimHostAdapter = /** @class */ (function () { function LanguageServiceShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; this.loggingEnabled = false; this.tracingEnabled = false; // if shimHost is a COM object then property check will become method call with no arguments. // 'in' does not have this effect. if ("getModuleResolutionsForFile" in this.shimHost) { this.resolveModuleNames = function (moduleNames, containingFile) { var resolutionsInFile = JSON.parse(_this.shimHost.getModuleResolutionsForFile(containingFile)); return ts.map(moduleNames, function (name) { var result = ts.getProperty(resolutionsInFile, name); return result ? { resolvedFileName: result, extension: ts.extensionFromPath(result), isExternalLibraryImport: false } : undefined; }); }; } if ("directoryExists" in this.shimHost) { this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); }; } if ("getTypeReferenceDirectiveResolutionsForFile" in this.shimHost) { this.resolveTypeReferenceDirectives = function (typeDirectiveNames, containingFile) { var typeDirectivesForFile = JSON.parse(_this.shimHost.getTypeReferenceDirectiveResolutionsForFile(containingFile)); return ts.map(typeDirectiveNames, function (name) { return ts.getProperty(typeDirectivesForFile, name); }); }; } } LanguageServiceShimHostAdapter.prototype.log = function (s) { if (this.loggingEnabled) { this.shimHost.log(s); } }; LanguageServiceShimHostAdapter.prototype.trace = function (s) { if (this.tracingEnabled) { this.shimHost.trace(s); } }; LanguageServiceShimHostAdapter.prototype.error = function (s) { this.shimHost.error(s); }; LanguageServiceShimHostAdapter.prototype.getProjectVersion = function () { if (!this.shimHost.getProjectVersion) { // shimmed host does not support getProjectVersion return undefined; } return this.shimHost.getProjectVersion(); }; LanguageServiceShimHostAdapter.prototype.getTypeRootsVersion = function () { if (!this.shimHost.getTypeRootsVersion) { return 0; } return this.shimHost.getTypeRootsVersion(); }; LanguageServiceShimHostAdapter.prototype.useCaseSensitiveFileNames = function () { return this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false; }; LanguageServiceShimHostAdapter.prototype.getCompilationSettings = function () { var settingsJson = this.shimHost.getCompilationSettings(); if (settingsJson === null || settingsJson === "") { throw Error("LanguageServiceShimHostAdapter.getCompilationSettings: empty compilationSettings"); } var compilerOptions = JSON.parse(settingsJson); // permit language service to handle all files (filtering should be performed on the host side) compilerOptions.allowNonTsExtensions = true; return compilerOptions; }; LanguageServiceShimHostAdapter.prototype.getScriptFileNames = function () { var encoded = this.shimHost.getScriptFileNames(); return this.files = JSON.parse(encoded); }; LanguageServiceShimHostAdapter.prototype.getScriptSnapshot = function (fileName) { var scriptSnapshot = this.shimHost.getScriptSnapshot(fileName); return scriptSnapshot && new ScriptSnapshotShimAdapter(scriptSnapshot); }; LanguageServiceShimHostAdapter.prototype.getScriptKind = function (fileName) { if ("getScriptKind" in this.shimHost) { return this.shimHost.getScriptKind(fileName); } else { return 0 /* Unknown */; } }; LanguageServiceShimHostAdapter.prototype.getScriptVersion = function (fileName) { return this.shimHost.getScriptVersion(fileName); }; LanguageServiceShimHostAdapter.prototype.getLocalizedDiagnosticMessages = function () { var diagnosticMessagesJson = this.shimHost.getLocalizedDiagnosticMessages(); if (diagnosticMessagesJson === null || diagnosticMessagesJson === "") { return null; } try { return JSON.parse(diagnosticMessagesJson); } catch (e) { this.log(e.description || "diagnosticMessages.generated.json has invalid JSON format"); return null; } }; LanguageServiceShimHostAdapter.prototype.getCancellationToken = function () { var hostCancellationToken = this.shimHost.getCancellationToken(); return new ts.ThrottledCancellationToken(hostCancellationToken); }; LanguageServiceShimHostAdapter.prototype.getCurrentDirectory = function () { return this.shimHost.getCurrentDirectory(); }; LanguageServiceShimHostAdapter.prototype.getDirectories = function (path) { return JSON.parse(this.shimHost.getDirectories(path)); }; LanguageServiceShimHostAdapter.prototype.getDefaultLibFileName = function (options) { return this.shimHost.getDefaultLibFileName(JSON.stringify(options)); }; LanguageServiceShimHostAdapter.prototype.readDirectory = function (path, extensions, exclude, include, depth) { var pattern = ts.getFileMatcherPatterns(path, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); return JSON.parse(this.shimHost.readDirectory(path, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth)); }; LanguageServiceShimHostAdapter.prototype.readFile = function (path, encoding) { return this.shimHost.readFile(path, encoding); }; LanguageServiceShimHostAdapter.prototype.fileExists = function (path) { return this.shimHost.fileExists(path); }; return LanguageServiceShimHostAdapter; }()); ts.LanguageServiceShimHostAdapter = LanguageServiceShimHostAdapter; var CoreServicesShimHostAdapter = /** @class */ (function () { function CoreServicesShimHostAdapter(shimHost) { var _this = this; this.shimHost = shimHost; this.useCaseSensitiveFileNames = this.shimHost.useCaseSensitiveFileNames ? this.shimHost.useCaseSensitiveFileNames() : false; if ("directoryExists" in this.shimHost) { this.directoryExists = function (directoryName) { return _this.shimHost.directoryExists(directoryName); }; } if ("realpath" in this.shimHost) { this.realpath = function (path) { return _this.shimHost.realpath(path); }; } } CoreServicesShimHostAdapter.prototype.readDirectory = function (rootDir, extensions, exclude, include, depth) { var pattern = ts.getFileMatcherPatterns(rootDir, exclude, include, this.shimHost.useCaseSensitiveFileNames(), this.shimHost.getCurrentDirectory()); return JSON.parse(this.shimHost.readDirectory(rootDir, JSON.stringify(extensions), JSON.stringify(pattern.basePaths), pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern, depth)); }; CoreServicesShimHostAdapter.prototype.fileExists = function (fileName) { return this.shimHost.fileExists(fileName); }; CoreServicesShimHostAdapter.prototype.readFile = function (fileName) { return this.shimHost.readFile(fileName); }; CoreServicesShimHostAdapter.prototype.getDirectories = function (path) { return JSON.parse(this.shimHost.getDirectories(path)); }; return CoreServicesShimHostAdapter; }()); ts.CoreServicesShimHostAdapter = CoreServicesShimHostAdapter; function simpleForwardCall(logger, actionDescription, action, logPerformance) { var start; if (logPerformance) { logger.log(actionDescription); start = ts.timestamp(); } var result = action(); if (logPerformance) { var end = ts.timestamp(); logger.log(actionDescription + " completed in " + (end - start) + " msec"); if (ts.isString(result)) { var str = result; if (str.length > 128) { str = str.substring(0, 128) + "..."; } logger.log(" result.length=" + str.length + ", result='" + JSON.stringify(str) + "'"); } } return result; } function forwardJSONCall(logger, actionDescription, action, logPerformance) { return forwardCall(logger, actionDescription, /*returnJson*/ true, action, logPerformance); } function forwardCall(logger, actionDescription, returnJson, action, logPerformance) { try { var result = simpleForwardCall(logger, actionDescription, action, logPerformance); return returnJson ? JSON.stringify({ result: result }) : result; } catch (err) { if (err instanceof ts.OperationCanceledException) { return JSON.stringify({ canceled: true }); } logInternalError(logger, err); err.description = actionDescription; return JSON.stringify({ error: err }); } } var ShimBase = /** @class */ (function () { function ShimBase(factory) { this.factory = factory; factory.registerShim(this); } ShimBase.prototype.dispose = function (_dummy) { this.factory.unregisterShim(this); }; return ShimBase; }()); function realizeDiagnostics(diagnostics, newLine) { return diagnostics.map(function (d) { return realizeDiagnostic(d, newLine); }); } ts.realizeDiagnostics = realizeDiagnostics; function realizeDiagnostic(diagnostic, newLine) { return { message: ts.flattenDiagnosticMessageText(diagnostic.messageText, newLine), start: diagnostic.start, length: diagnostic.length, /// TODO: no need for the tolowerCase call category: ts.DiagnosticCategory[diagnostic.category].toLowerCase(), code: diagnostic.code }; } var LanguageServiceShimObject = /** @class */ (function (_super) { __extends(LanguageServiceShimObject, _super); function LanguageServiceShimObject(factory, host, languageService) { var _this = _super.call(this, factory) || this; _this.host = host; _this.languageService = languageService; _this.logPerformance = false; _this.logger = _this.host; return _this; } LanguageServiceShimObject.prototype.forwardJSONCall = function (actionDescription, action) { return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); }; /// DISPOSE /** * Ensure (almost) deterministic release of internal Javascript resources when * some external native objects holds onto us (e.g. Com/Interop). */ LanguageServiceShimObject.prototype.dispose = function (dummy) { this.logger.log("dispose()"); this.languageService.dispose(); this.languageService = null; // force a GC if (debugObjectHost && debugObjectHost.CollectGarbage) { debugObjectHost.CollectGarbage(); this.logger.log("CollectGarbage()"); } this.logger = null; _super.prototype.dispose.call(this, dummy); }; /// REFRESH /** * Update the list of scripts known to the compiler */ LanguageServiceShimObject.prototype.refresh = function (throwOnError) { this.forwardJSONCall("refresh(" + throwOnError + ")", function () { return null; }); }; LanguageServiceShimObject.prototype.cleanupSemanticCache = function () { var _this = this; this.forwardJSONCall("cleanupSemanticCache()", function () { _this.languageService.cleanupSemanticCache(); return null; }); }; LanguageServiceShimObject.prototype.realizeDiagnostics = function (diagnostics) { var newLine = ts.getNewLineOrDefaultFromHost(this.host); return ts.realizeDiagnostics(diagnostics, newLine); }; LanguageServiceShimObject.prototype.getSyntacticClassifications = function (fileName, start, length) { var _this = this; return this.forwardJSONCall("getSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSyntacticClassifications(fileName, ts.createTextSpan(start, length)); }); }; LanguageServiceShimObject.prototype.getSemanticClassifications = function (fileName, start, length) { var _this = this; return this.forwardJSONCall("getSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", function () { return _this.languageService.getSemanticClassifications(fileName, ts.createTextSpan(start, length)); }); }; LanguageServiceShimObject.prototype.getEncodedSyntacticClassifications = function (fileName, start, length) { var _this = this; return this.forwardJSONCall("getEncodedSyntacticClassifications('" + fileName + "', " + start + ", " + length + ")", // directly serialize the spans out to a string. This is much faster to decode // on the managed side versus a full JSON array. function () { return convertClassifications(_this.languageService.getEncodedSyntacticClassifications(fileName, ts.createTextSpan(start, length))); }); }; LanguageServiceShimObject.prototype.getEncodedSemanticClassifications = function (fileName, start, length) { var _this = this; return this.forwardJSONCall("getEncodedSemanticClassifications('" + fileName + "', " + start + ", " + length + ")", // directly serialize the spans out to a string. This is much faster to decode // on the managed side versus a full JSON array. function () { return convertClassifications(_this.languageService.getEncodedSemanticClassifications(fileName, ts.createTextSpan(start, length))); }); }; LanguageServiceShimObject.prototype.getSyntacticDiagnostics = function (fileName) { var _this = this; return this.forwardJSONCall("getSyntacticDiagnostics('" + fileName + "')", function () { var diagnostics = _this.languageService.getSyntacticDiagnostics(fileName); return _this.realizeDiagnostics(diagnostics); }); }; LanguageServiceShimObject.prototype.getSemanticDiagnostics = function (fileName) { var _this = this; return this.forwardJSONCall("getSemanticDiagnostics('" + fileName + "')", function () { var diagnostics = _this.languageService.getSemanticDiagnostics(fileName); return _this.realizeDiagnostics(diagnostics); }); }; LanguageServiceShimObject.prototype.getCompilerOptionsDiagnostics = function () { var _this = this; return this.forwardJSONCall("getCompilerOptionsDiagnostics()", function () { var diagnostics = _this.languageService.getCompilerOptionsDiagnostics(); return _this.realizeDiagnostics(diagnostics); }); }; /// QUICKINFO /** * Computes a string representation of the type at the requested position * in the active file. */ LanguageServiceShimObject.prototype.getQuickInfoAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getQuickInfoAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getQuickInfoAtPosition(fileName, position); }); }; /// NAMEORDOTTEDNAMESPAN /** * Computes span information of the name or dotted name at the requested position * in the active file. */ LanguageServiceShimObject.prototype.getNameOrDottedNameSpan = function (fileName, startPos, endPos) { var _this = this; return this.forwardJSONCall("getNameOrDottedNameSpan('" + fileName + "', " + startPos + ", " + endPos + ")", function () { return _this.languageService.getNameOrDottedNameSpan(fileName, startPos, endPos); }); }; /** * STATEMENTSPAN * Computes span information of statement at the requested position in the active file. */ LanguageServiceShimObject.prototype.getBreakpointStatementAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getBreakpointStatementAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBreakpointStatementAtPosition(fileName, position); }); }; /// SIGNATUREHELP LanguageServiceShimObject.prototype.getSignatureHelpItems = function (fileName, position) { var _this = this; return this.forwardJSONCall("getSignatureHelpItems('" + fileName + "', " + position + ")", function () { return _this.languageService.getSignatureHelpItems(fileName, position); }); }; /// GOTO DEFINITION /** * Computes the definition location and file for the symbol * at the requested position. */ LanguageServiceShimObject.prototype.getDefinitionAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAtPosition(fileName, position); }); }; /** * Computes the definition location and file for the symbol * at the requested position. */ LanguageServiceShimObject.prototype.getDefinitionAndBoundSpan = function (fileName, position) { var _this = this; return this.forwardJSONCall("getDefinitionAndBoundSpan('" + fileName + "', " + position + ")", function () { return _this.languageService.getDefinitionAndBoundSpan(fileName, position); }); }; /// GOTO Type /** * Computes the definition location of the type of the symbol * at the requested position. */ LanguageServiceShimObject.prototype.getTypeDefinitionAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getTypeDefinitionAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getTypeDefinitionAtPosition(fileName, position); }); }; /// GOTO Implementation /** * Computes the implementation location of the symbol * at the requested position. */ LanguageServiceShimObject.prototype.getImplementationAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getImplementationAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getImplementationAtPosition(fileName, position); }); }; LanguageServiceShimObject.prototype.getRenameInfo = function (fileName, position) { var _this = this; return this.forwardJSONCall("getRenameInfo('" + fileName + "', " + position + ")", function () { return _this.languageService.getRenameInfo(fileName, position); }); }; LanguageServiceShimObject.prototype.findRenameLocations = function (fileName, position, findInStrings, findInComments) { var _this = this; return this.forwardJSONCall("findRenameLocations('" + fileName + "', " + position + ", " + findInStrings + ", " + findInComments + ")", function () { return _this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments); }); }; /// GET BRACE MATCHING LanguageServiceShimObject.prototype.getBraceMatchingAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getBraceMatchingAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getBraceMatchingAtPosition(fileName, position); }); }; LanguageServiceShimObject.prototype.isValidBraceCompletionAtPosition = function (fileName, position, openingBrace) { var _this = this; return this.forwardJSONCall("isValidBraceCompletionAtPosition('" + fileName + "', " + position + ", " + openingBrace + ")", function () { return _this.languageService.isValidBraceCompletionAtPosition(fileName, position, openingBrace); }); }; LanguageServiceShimObject.prototype.getSpanOfEnclosingComment = function (fileName, position, onlyMultiLine) { var _this = this; return this.forwardJSONCall("getSpanOfEnclosingComment('" + fileName + "', " + position + ")", function () { return _this.languageService.getSpanOfEnclosingComment(fileName, position, onlyMultiLine); }); }; /// GET SMART INDENT LanguageServiceShimObject.prototype.getIndentationAtPosition = function (fileName, position, options /*Services.EditorOptions*/) { var _this = this; return this.forwardJSONCall("getIndentationAtPosition('" + fileName + "', " + position + ")", function () { var localOptions = JSON.parse(options); return _this.languageService.getIndentationAtPosition(fileName, position, localOptions); }); }; /// GET REFERENCES LanguageServiceShimObject.prototype.getReferencesAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getReferencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getReferencesAtPosition(fileName, position); }); }; LanguageServiceShimObject.prototype.findReferences = function (fileName, position) { var _this = this; return this.forwardJSONCall("findReferences('" + fileName + "', " + position + ")", function () { return _this.languageService.findReferences(fileName, position); }); }; LanguageServiceShimObject.prototype.getOccurrencesAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getOccurrencesAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getOccurrencesAtPosition(fileName, position); }); }; LanguageServiceShimObject.prototype.getDocumentHighlights = function (fileName, position, filesToSearch) { var _this = this; return this.forwardJSONCall("getDocumentHighlights('" + fileName + "', " + position + ")", function () { var results = _this.languageService.getDocumentHighlights(fileName, position, JSON.parse(filesToSearch)); // workaround for VS document highlighting issue - keep only items from the initial file var normalizedName = ts.normalizeSlashes(fileName).toLowerCase(); return ts.filter(results, function (r) { return ts.normalizeSlashes(r.fileName).toLowerCase() === normalizedName; }); }); }; /// COMPLETION LISTS /** * Get a string based representation of the completions * to provide at the given source position and providing a member completion * list if requested. */ LanguageServiceShimObject.prototype.getCompletionsAtPosition = function (fileName, position, options) { var _this = this; return this.forwardJSONCall("getCompletionsAtPosition('" + fileName + "', " + position + ", " + options + ")", function () { return _this.languageService.getCompletionsAtPosition(fileName, position, options); }); }; /** Get a string based representation of a completion list entry details */ LanguageServiceShimObject.prototype.getCompletionEntryDetails = function (fileName, position, entryName, options /*Services.FormatCodeOptions*/, source) { var _this = this; return this.forwardJSONCall("getCompletionEntryDetails('" + fileName + "', " + position + ", '" + entryName + "')", function () { var localOptions = JSON.parse(options); return _this.languageService.getCompletionEntryDetails(fileName, position, entryName, localOptions, source); }); }; LanguageServiceShimObject.prototype.getFormattingEditsForRange = function (fileName, start, end, options /*Services.FormatCodeOptions*/) { var _this = this; return this.forwardJSONCall("getFormattingEditsForRange('" + fileName + "', " + start + ", " + end + ")", function () { var localOptions = JSON.parse(options); return _this.languageService.getFormattingEditsForRange(fileName, start, end, localOptions); }); }; LanguageServiceShimObject.prototype.getFormattingEditsForDocument = function (fileName, options /*Services.FormatCodeOptions*/) { var _this = this; return this.forwardJSONCall("getFormattingEditsForDocument('" + fileName + "')", function () { var localOptions = JSON.parse(options); return _this.languageService.getFormattingEditsForDocument(fileName, localOptions); }); }; LanguageServiceShimObject.prototype.getFormattingEditsAfterKeystroke = function (fileName, position, key, options /*Services.FormatCodeOptions*/) { var _this = this; return this.forwardJSONCall("getFormattingEditsAfterKeystroke('" + fileName + "', " + position + ", '" + key + "')", function () { var localOptions = JSON.parse(options); return _this.languageService.getFormattingEditsAfterKeystroke(fileName, position, key, localOptions); }); }; LanguageServiceShimObject.prototype.getDocCommentTemplateAtPosition = function (fileName, position) { var _this = this; return this.forwardJSONCall("getDocCommentTemplateAtPosition('" + fileName + "', " + position + ")", function () { return _this.languageService.getDocCommentTemplateAtPosition(fileName, position); }); }; /// NAVIGATE TO /** Return a list of symbols that are interesting to navigate to */ LanguageServiceShimObject.prototype.getNavigateToItems = function (searchValue, maxResultCount, fileName) { var _this = this; return this.forwardJSONCall("getNavigateToItems('" + searchValue + "', " + maxResultCount + ", " + fileName + ")", function () { return _this.languageService.getNavigateToItems(searchValue, maxResultCount, fileName); }); }; LanguageServiceShimObject.prototype.getNavigationBarItems = function (fileName) { var _this = this; return this.forwardJSONCall("getNavigationBarItems('" + fileName + "')", function () { return _this.languageService.getNavigationBarItems(fileName); }); }; LanguageServiceShimObject.prototype.getNavigationTree = function (fileName) { var _this = this; return this.forwardJSONCall("getNavigationTree('" + fileName + "')", function () { return _this.languageService.getNavigationTree(fileName); }); }; LanguageServiceShimObject.prototype.getOutliningSpans = function (fileName) { var _this = this; return this.forwardJSONCall("getOutliningSpans('" + fileName + "')", function () { return _this.languageService.getOutliningSpans(fileName); }); }; LanguageServiceShimObject.prototype.getTodoComments = function (fileName, descriptors) { var _this = this; return this.forwardJSONCall("getTodoComments('" + fileName + "')", function () { return _this.languageService.getTodoComments(fileName, JSON.parse(descriptors)); }); }; /// Emit LanguageServiceShimObject.prototype.getEmitOutput = function (fileName) { var _this = this; return this.forwardJSONCall("getEmitOutput('" + fileName + "')", function () { return _this.languageService.getEmitOutput(fileName); }); }; LanguageServiceShimObject.prototype.getEmitOutputObject = function (fileName) { var _this = this; return forwardCall(this.logger, "getEmitOutput('" + fileName + "')", /*returnJson*/ false, function () { return _this.languageService.getEmitOutput(fileName); }, this.logPerformance); }; return LanguageServiceShimObject; }(ShimBase)); function convertClassifications(classifications) { return { spans: classifications.spans.join(","), endOfLineState: classifications.endOfLineState }; } var ClassifierShimObject = /** @class */ (function (_super) { __extends(ClassifierShimObject, _super); function ClassifierShimObject(factory, logger) { var _this = _super.call(this, factory) || this; _this.logger = logger; _this.logPerformance = false; _this.classifier = ts.createClassifier(); return _this; } ClassifierShimObject.prototype.getEncodedLexicalClassifications = function (text, lexState, syntacticClassifierAbsent) { var _this = this; return forwardJSONCall(this.logger, "getEncodedLexicalClassifications", function () { return convertClassifications(_this.classifier.getEncodedLexicalClassifications(text, lexState, syntacticClassifierAbsent)); }, this.logPerformance); }; /// COLORIZATION ClassifierShimObject.prototype.getClassificationsForLine = function (text, lexState, classifyKeywordsInGenerics) { var classification = this.classifier.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics); var result = ""; for (var _i = 0, _a = classification.entries; _i < _a.length; _i++) { var item = _a[_i]; result += item.length + "\n"; result += item.classification + "\n"; } result += classification.finalLexState; return result; }; return ClassifierShimObject; }(ShimBase)); var CoreServicesShimObject = /** @class */ (function (_super) { __extends(CoreServicesShimObject, _super); function CoreServicesShimObject(factory, logger, host) { var _this = _super.call(this, factory) || this; _this.logger = logger; _this.host = host; _this.logPerformance = false; return _this; } CoreServicesShimObject.prototype.forwardJSONCall = function (actionDescription, action) { return forwardJSONCall(this.logger, actionDescription, action, this.logPerformance); }; CoreServicesShimObject.prototype.resolveModuleName = function (fileName, moduleName, compilerOptionsJson) { var _this = this; return this.forwardJSONCall("resolveModuleName('" + fileName + "')", function () { var compilerOptions = JSON.parse(compilerOptionsJson); var result = ts.resolveModuleName(moduleName, ts.normalizeSlashes(fileName), compilerOptions, _this.host); var resolvedFileName = result.resolvedModule ? result.resolvedModule.resolvedFileName : undefined; if (result.resolvedModule && result.resolvedModule.extension !== ".ts" /* Ts */ && result.resolvedModule.extension !== ".tsx" /* Tsx */ && result.resolvedModule.extension !== ".d.ts" /* Dts */) { resolvedFileName = undefined; } return { resolvedFileName: resolvedFileName, failedLookupLocations: result.failedLookupLocations }; }); }; CoreServicesShimObject.prototype.resolveTypeReferenceDirective = function (fileName, typeReferenceDirective, compilerOptionsJson) { var _this = this; return this.forwardJSONCall("resolveTypeReferenceDirective(" + fileName + ")", function () { var compilerOptions = JSON.parse(compilerOptionsJson); var result = ts.resolveTypeReferenceDirective(typeReferenceDirective, ts.normalizeSlashes(fileName), compilerOptions, _this.host); return { resolvedFileName: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.resolvedFileName : undefined, primary: result.resolvedTypeReferenceDirective ? result.resolvedTypeReferenceDirective.primary : true, failedLookupLocations: result.failedLookupLocations }; }); }; CoreServicesShimObject.prototype.getPreProcessedFileInfo = function (fileName, sourceTextSnapshot) { var _this = this; return this.forwardJSONCall("getPreProcessedFileInfo('" + fileName + "')", function () { // for now treat files as JavaScript var result = ts.preProcessFile(sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()), /* readImportFiles */ true, /* detectJavaScriptImports */ true); return { referencedFiles: _this.convertFileReferences(result.referencedFiles), importedFiles: _this.convertFileReferences(result.importedFiles), ambientExternalModules: result.ambientExternalModules, isLibFile: result.isLibFile, typeReferenceDirectives: _this.convertFileReferences(result.typeReferenceDirectives) }; }); }; CoreServicesShimObject.prototype.getAutomaticTypeDirectiveNames = function (compilerOptionsJson) { var _this = this; return this.forwardJSONCall("getAutomaticTypeDirectiveNames('" + compilerOptionsJson + "')", function () { var compilerOptions = JSON.parse(compilerOptionsJson); return ts.getAutomaticTypeDirectiveNames(compilerOptions, _this.host); }); }; CoreServicesShimObject.prototype.convertFileReferences = function (refs) { if (!refs) { return undefined; } var result = []; for (var _i = 0, refs_2 = refs; _i < refs_2.length; _i++) { var ref = refs_2[_i]; result.push({ path: ts.normalizeSlashes(ref.fileName), position: ref.pos, length: ref.end - ref.pos }); } return result; }; CoreServicesShimObject.prototype.getTSConfigFileInfo = function (fileName, sourceTextSnapshot) { var _this = this; return this.forwardJSONCall("getTSConfigFileInfo('" + fileName + "')", function () { var text = sourceTextSnapshot.getText(0, sourceTextSnapshot.getLength()); var result = ts.parseJsonText(fileName, text); var normalizedFileName = ts.normalizeSlashes(fileName); var configFile = ts.parseJsonSourceFileConfigFileContent(result, _this.host, ts.getDirectoryPath(normalizedFileName), /*existingOptions*/ {}, normalizedFileName); return { options: configFile.options, typeAcquisition: configFile.typeAcquisition, files: configFile.fileNames, raw: configFile.raw, errors: realizeDiagnostics(result.parseDiagnostics.concat(configFile.errors), "\r\n") }; }); }; CoreServicesShimObject.prototype.getDefaultCompilationSettings = function () { return this.forwardJSONCall("getDefaultCompilationSettings()", function () { return ts.getDefaultCompilerOptions(); }); }; CoreServicesShimObject.prototype.discoverTypings = function (discoverTypingsJson) { var _this = this; var getCanonicalFileName = ts.createGetCanonicalFileName(/*useCaseSensitivefileNames:*/ false); return this.forwardJSONCall("discoverTypings()", function () { var info = JSON.parse(discoverTypingsJson); if (_this.safeList === undefined) { _this.safeList = ts.JsTyping.loadSafeList(_this.host, ts.toPath(info.safeListPath, info.safeListPath, getCanonicalFileName)); } return ts.JsTyping.discoverTypings(_this.host, function (msg) { return _this.logger.log(msg); }, info.fileNames, ts.toPath(info.projectRootPath, info.projectRootPath, getCanonicalFileName), _this.safeList, info.packageNameToTypingLocation, info.typeAcquisition, info.unresolvedImports); }); }; return CoreServicesShimObject; }(ShimBase)); var TypeScriptServicesFactory = /** @class */ (function () { function TypeScriptServicesFactory() { this._shims = []; } /* * Returns script API version. */ TypeScriptServicesFactory.prototype.getServicesVersion = function () { return ts.servicesVersion; }; TypeScriptServicesFactory.prototype.createLanguageServiceShim = function (host) { try { if (this.documentRegistry === undefined) { this.documentRegistry = ts.createDocumentRegistry(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames(), host.getCurrentDirectory()); } var hostAdapter = new LanguageServiceShimHostAdapter(host); var languageService = ts.createLanguageService(hostAdapter, this.documentRegistry); return new LanguageServiceShimObject(this, host, languageService); } catch (err) { logInternalError(host, err); throw err; } }; TypeScriptServicesFactory.prototype.createClassifierShim = function (logger) { try { return new ClassifierShimObject(this, logger); } catch (err) { logInternalError(logger, err); throw err; } }; TypeScriptServicesFactory.prototype.createCoreServicesShim = function (host) { try { var adapter = new CoreServicesShimHostAdapter(host); return new CoreServicesShimObject(this, host, adapter); } catch (err) { logInternalError(host, err); throw err; } }; TypeScriptServicesFactory.prototype.close = function () { // Forget all the registered shims ts.clear(this._shims); this.documentRegistry = undefined; }; TypeScriptServicesFactory.prototype.registerShim = function (shim) { this._shims.push(shim); }; TypeScriptServicesFactory.prototype.unregisterShim = function (shim) { for (var i = 0; i < this._shims.length; i++) { if (this._shims[i] === shim) { delete this._shims[i]; return; } } throw new Error("Invalid operation"); }; return TypeScriptServicesFactory; }()); ts.TypeScriptServicesFactory = TypeScriptServicesFactory; if (typeof module !== "undefined" && module.exports) { module.exports = ts; } })(ts || (ts = {})); /* tslint:enable:no-in-operator */ /* tslint:enable:no-null */ /// TODO: this is used by VS, clean this up on both sides of the interface /* @internal */ var TypeScript; (function (TypeScript) { var Services; (function (Services) { Services.TypeScriptServicesFactory = ts.TypeScriptServicesFactory; })(Services = TypeScript.Services || (TypeScript.Services = {})); })(TypeScript || (TypeScript = {})); // 'toolsVersion' gets consumed by the managed side, so it's not unused. // TODO: it should be moved into a namespace though. /* @internal */ var toolsVersion = ts.versionMajorMinor;