util.js 58 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const ts = require("typescript");
  4. const node_1 = require("../typeguard/node");
  5. const _3_2_1 = require("../typeguard/3.2");
  6. const type_1 = require("./type");
  7. function getChildOfKind(node, kind, sourceFile) {
  8. for (const child of node.getChildren(sourceFile))
  9. if (child.kind === kind)
  10. return child;
  11. }
  12. exports.getChildOfKind = getChildOfKind;
  13. function isTokenKind(kind) {
  14. return kind >= ts.SyntaxKind.FirstToken && kind <= ts.SyntaxKind.LastToken;
  15. }
  16. exports.isTokenKind = isTokenKind;
  17. function isNodeKind(kind) {
  18. return kind >= ts.SyntaxKind.FirstNode;
  19. }
  20. exports.isNodeKind = isNodeKind;
  21. function isAssignmentKind(kind) {
  22. return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
  23. }
  24. exports.isAssignmentKind = isAssignmentKind;
  25. function isTypeNodeKind(kind) {
  26. return kind >= ts.SyntaxKind.FirstTypeNode && kind <= ts.SyntaxKind.LastTypeNode;
  27. }
  28. exports.isTypeNodeKind = isTypeNodeKind;
  29. function isJsDocKind(kind) {
  30. return kind >= ts.SyntaxKind.FirstJSDocNode && kind <= ts.SyntaxKind.LastJSDocNode;
  31. }
  32. exports.isJsDocKind = isJsDocKind;
  33. function isKeywordKind(kind) {
  34. return kind >= ts.SyntaxKind.FirstKeyword && kind <= ts.SyntaxKind.LastKeyword;
  35. }
  36. exports.isKeywordKind = isKeywordKind;
  37. function isThisParameter(parameter) {
  38. return parameter.name.kind === ts.SyntaxKind.Identifier && parameter.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword;
  39. }
  40. exports.isThisParameter = isThisParameter;
  41. function getModifier(node, kind) {
  42. if (node.modifiers !== undefined)
  43. for (const modifier of node.modifiers)
  44. if (modifier.kind === kind)
  45. return modifier;
  46. }
  47. exports.getModifier = getModifier;
  48. function hasModifier(modifiers, ...kinds) {
  49. if (modifiers === undefined)
  50. return false;
  51. for (const modifier of modifiers)
  52. if (kinds.includes(modifier.kind))
  53. return true;
  54. return false;
  55. }
  56. exports.hasModifier = hasModifier;
  57. function isParameterProperty(node) {
  58. return hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ReadonlyKeyword);
  59. }
  60. exports.isParameterProperty = isParameterProperty;
  61. function hasAccessModifier(node) {
  62. return hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword);
  63. }
  64. exports.hasAccessModifier = hasAccessModifier;
  65. function isFlagSet(obj, flag) {
  66. return (obj.flags & flag) !== 0;
  67. }
  68. exports.isNodeFlagSet = isFlagSet;
  69. exports.isTypeFlagSet = isFlagSet;
  70. exports.isSymbolFlagSet = isFlagSet;
  71. function isObjectFlagSet(objectType, flag) {
  72. return (objectType.objectFlags & flag) !== 0;
  73. }
  74. exports.isObjectFlagSet = isObjectFlagSet;
  75. function isModifierFlagSet(node, flag) {
  76. return (ts.getCombinedModifierFlags(node) & flag) !== 0;
  77. }
  78. exports.isModifierFlagSet = isModifierFlagSet;
  79. function getPreviousStatement(statement) {
  80. const parent = statement.parent;
  81. if (node_1.isBlockLike(parent)) {
  82. const index = parent.statements.indexOf(statement);
  83. if (index > 0)
  84. return parent.statements[index - 1];
  85. }
  86. }
  87. exports.getPreviousStatement = getPreviousStatement;
  88. function getNextStatement(statement) {
  89. const parent = statement.parent;
  90. if (node_1.isBlockLike(parent)) {
  91. const index = parent.statements.indexOf(statement);
  92. if (index < parent.statements.length)
  93. return parent.statements[index + 1];
  94. }
  95. }
  96. exports.getNextStatement = getNextStatement;
  97. function getPreviousToken(node, sourceFile) {
  98. let parent = node.parent;
  99. while (parent !== undefined && parent.pos === node.pos)
  100. parent = parent.parent;
  101. if (parent === undefined)
  102. return;
  103. outer: while (true) {
  104. const children = parent.getChildren(sourceFile);
  105. for (let i = children.length - 1; i >= 0; --i) {
  106. const child = children[i];
  107. if (child.pos < node.pos && child.kind !== ts.SyntaxKind.JSDocComment) {
  108. if (isTokenKind(child.kind))
  109. return child;
  110. parent = child;
  111. continue outer;
  112. }
  113. }
  114. return;
  115. }
  116. }
  117. exports.getPreviousToken = getPreviousToken;
  118. function getNextToken(node, sourceFile = node.getSourceFile()) {
  119. if (node.kind === ts.SyntaxKind.SourceFile || node.kind === ts.SyntaxKind.EndOfFileToken)
  120. return;
  121. const end = node.end;
  122. node = node.parent;
  123. while (node.end === end) {
  124. if (node.parent === undefined)
  125. return node.endOfFileToken;
  126. node = node.parent;
  127. }
  128. return getTokenAtPositionWorker(node, end, sourceFile, false);
  129. }
  130. exports.getNextToken = getNextToken;
  131. function getTokenAtPosition(parent, pos, sourceFile, allowJsDoc) {
  132. if (pos < parent.pos || pos >= parent.end)
  133. return;
  134. if (isTokenKind(parent.kind))
  135. return parent;
  136. if (sourceFile === undefined)
  137. sourceFile = parent.getSourceFile();
  138. return getTokenAtPositionWorker(parent, pos, sourceFile, allowJsDoc === true);
  139. }
  140. exports.getTokenAtPosition = getTokenAtPosition;
  141. function getTokenAtPositionWorker(node, pos, sourceFile, allowJsDoc) {
  142. outer: while (true) {
  143. for (const child of node.getChildren(sourceFile)) {
  144. if (child.end > pos && (allowJsDoc || child.kind !== ts.SyntaxKind.JSDocComment)) {
  145. if (isTokenKind(child.kind))
  146. return child;
  147. node = child;
  148. continue outer;
  149. }
  150. }
  151. return;
  152. }
  153. }
  154. function getCommentAtPosition(sourceFile, pos, parent = sourceFile) {
  155. const token = getTokenAtPosition(parent, pos, sourceFile);
  156. if (token === undefined || token.kind === ts.SyntaxKind.JsxText || pos >= token.end - (ts.tokenToString(token.kind) || '').length)
  157. return;
  158. const startPos = token.pos === 0
  159. ? (ts.getShebang(sourceFile.text) || '').length
  160. : token.pos;
  161. return startPos !== 0 && ts.forEachTrailingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos) ||
  162. ts.forEachLeadingCommentRange(sourceFile.text, startPos, commentAtPositionCallback, pos);
  163. }
  164. exports.getCommentAtPosition = getCommentAtPosition;
  165. function commentAtPositionCallback(pos, end, kind, _nl, at) {
  166. return at >= pos && at < end ? { pos, end, kind } : undefined;
  167. }
  168. function isPositionInComment(sourceFile, pos, parent) {
  169. return getCommentAtPosition(sourceFile, pos, parent) !== undefined;
  170. }
  171. exports.isPositionInComment = isPositionInComment;
  172. function commentText(sourceText, comment) {
  173. return sourceText.substring(comment.pos + 2, comment.kind === ts.SyntaxKind.SingleLineCommentTrivia ? comment.end : comment.end - 2);
  174. }
  175. exports.commentText = commentText;
  176. function getWrappedNodeAtPosition(wrap, pos) {
  177. if (wrap.node.pos > pos || wrap.node.end <= pos)
  178. return;
  179. outer: while (true) {
  180. for (const child of wrap.children) {
  181. if (child.node.pos > pos)
  182. return wrap;
  183. if (child.node.end > pos) {
  184. wrap = child;
  185. continue outer;
  186. }
  187. }
  188. return wrap;
  189. }
  190. }
  191. exports.getWrappedNodeAtPosition = getWrappedNodeAtPosition;
  192. function getPropertyName(propertyName) {
  193. if (propertyName.kind === ts.SyntaxKind.ComputedPropertyName) {
  194. if (!node_1.isLiteralExpression(propertyName.expression))
  195. return;
  196. if (_3_2_1.isBigIntLiteral(propertyName.expression))
  197. return propertyName.expression.text.slice(0, -1);
  198. return propertyName.expression.text;
  199. }
  200. return propertyName.text;
  201. }
  202. exports.getPropertyName = getPropertyName;
  203. function forEachDestructuringIdentifier(pattern, fn) {
  204. for (const element of pattern.elements) {
  205. if (element.kind !== ts.SyntaxKind.BindingElement)
  206. continue;
  207. let result;
  208. if (element.name.kind === ts.SyntaxKind.Identifier) {
  209. result = fn(element);
  210. }
  211. else {
  212. result = forEachDestructuringIdentifier(element.name, fn);
  213. }
  214. if (result)
  215. return result;
  216. }
  217. }
  218. exports.forEachDestructuringIdentifier = forEachDestructuringIdentifier;
  219. function forEachDeclaredVariable(declarationList, cb) {
  220. for (const declaration of declarationList.declarations) {
  221. let result;
  222. if (declaration.name.kind === ts.SyntaxKind.Identifier) {
  223. result = cb(declaration);
  224. }
  225. else {
  226. result = forEachDestructuringIdentifier(declaration.name, cb);
  227. }
  228. if (result)
  229. return result;
  230. }
  231. }
  232. exports.forEachDeclaredVariable = forEachDeclaredVariable;
  233. var VariableDeclarationKind;
  234. (function (VariableDeclarationKind) {
  235. VariableDeclarationKind[VariableDeclarationKind["Var"] = 0] = "Var";
  236. VariableDeclarationKind[VariableDeclarationKind["Let"] = 1] = "Let";
  237. VariableDeclarationKind[VariableDeclarationKind["Const"] = 2] = "Const";
  238. })(VariableDeclarationKind = exports.VariableDeclarationKind || (exports.VariableDeclarationKind = {}));
  239. function getVariableDeclarationKind(declarationList) {
  240. if (declarationList.flags & ts.NodeFlags.Let)
  241. return 1;
  242. if (declarationList.flags & ts.NodeFlags.Const)
  243. return 2;
  244. return 0;
  245. }
  246. exports.getVariableDeclarationKind = getVariableDeclarationKind;
  247. function isBlockScopedVariableDeclarationList(declarationList) {
  248. return (declarationList.flags & ts.NodeFlags.BlockScoped) !== 0;
  249. }
  250. exports.isBlockScopedVariableDeclarationList = isBlockScopedVariableDeclarationList;
  251. function isBlockScopedVariableDeclaration(declaration) {
  252. const parent = declaration.parent;
  253. return parent.kind === ts.SyntaxKind.CatchClause ||
  254. isBlockScopedVariableDeclarationList(parent);
  255. }
  256. exports.isBlockScopedVariableDeclaration = isBlockScopedVariableDeclaration;
  257. function isBlockScopedDeclarationStatement(statement) {
  258. switch (statement.kind) {
  259. case ts.SyntaxKind.VariableStatement:
  260. return isBlockScopedVariableDeclarationList(statement.declarationList);
  261. case ts.SyntaxKind.ClassDeclaration:
  262. case ts.SyntaxKind.EnumDeclaration:
  263. case ts.SyntaxKind.InterfaceDeclaration:
  264. case ts.SyntaxKind.TypeAliasDeclaration:
  265. return true;
  266. default:
  267. return false;
  268. }
  269. }
  270. exports.isBlockScopedDeclarationStatement = isBlockScopedDeclarationStatement;
  271. function isInSingleStatementContext(statement) {
  272. switch (statement.parent.kind) {
  273. case ts.SyntaxKind.ForStatement:
  274. case ts.SyntaxKind.ForInStatement:
  275. case ts.SyntaxKind.ForOfStatement:
  276. case ts.SyntaxKind.WhileStatement:
  277. case ts.SyntaxKind.DoStatement:
  278. case ts.SyntaxKind.IfStatement:
  279. case ts.SyntaxKind.WithStatement:
  280. case ts.SyntaxKind.LabeledStatement:
  281. return true;
  282. default:
  283. return false;
  284. }
  285. }
  286. exports.isInSingleStatementContext = isInSingleStatementContext;
  287. var ScopeBoundary;
  288. (function (ScopeBoundary) {
  289. ScopeBoundary[ScopeBoundary["None"] = 0] = "None";
  290. ScopeBoundary[ScopeBoundary["Function"] = 1] = "Function";
  291. ScopeBoundary[ScopeBoundary["Block"] = 2] = "Block";
  292. ScopeBoundary[ScopeBoundary["Type"] = 4] = "Type";
  293. ScopeBoundary[ScopeBoundary["ConditionalType"] = 8] = "ConditionalType";
  294. })(ScopeBoundary = exports.ScopeBoundary || (exports.ScopeBoundary = {}));
  295. var ScopeBoundarySelector;
  296. (function (ScopeBoundarySelector) {
  297. ScopeBoundarySelector[ScopeBoundarySelector["Function"] = 1] = "Function";
  298. ScopeBoundarySelector[ScopeBoundarySelector["Block"] = 3] = "Block";
  299. ScopeBoundarySelector[ScopeBoundarySelector["Type"] = 7] = "Type";
  300. ScopeBoundarySelector[ScopeBoundarySelector["InferType"] = 8] = "InferType";
  301. })(ScopeBoundarySelector = exports.ScopeBoundarySelector || (exports.ScopeBoundarySelector = {}));
  302. function isScopeBoundary(node) {
  303. return isFunctionScopeBoundary(node) || isBlockScopeBoundary(node) || isTypeScopeBoundary(node);
  304. }
  305. exports.isScopeBoundary = isScopeBoundary;
  306. function isTypeScopeBoundary(node) {
  307. switch (node.kind) {
  308. case ts.SyntaxKind.InterfaceDeclaration:
  309. case ts.SyntaxKind.TypeAliasDeclaration:
  310. case ts.SyntaxKind.MappedType:
  311. return 4;
  312. case ts.SyntaxKind.ConditionalType:
  313. return 8;
  314. default:
  315. return 0;
  316. }
  317. }
  318. exports.isTypeScopeBoundary = isTypeScopeBoundary;
  319. function isFunctionScopeBoundary(node) {
  320. switch (node.kind) {
  321. case ts.SyntaxKind.FunctionExpression:
  322. case ts.SyntaxKind.ArrowFunction:
  323. case ts.SyntaxKind.Constructor:
  324. case ts.SyntaxKind.ModuleDeclaration:
  325. case ts.SyntaxKind.ClassDeclaration:
  326. case ts.SyntaxKind.ClassExpression:
  327. case ts.SyntaxKind.EnumDeclaration:
  328. case ts.SyntaxKind.MethodDeclaration:
  329. case ts.SyntaxKind.FunctionDeclaration:
  330. case ts.SyntaxKind.GetAccessor:
  331. case ts.SyntaxKind.SetAccessor:
  332. case ts.SyntaxKind.MethodSignature:
  333. case ts.SyntaxKind.CallSignature:
  334. case ts.SyntaxKind.ConstructSignature:
  335. case ts.SyntaxKind.ConstructorType:
  336. case ts.SyntaxKind.FunctionType:
  337. return 1;
  338. case ts.SyntaxKind.SourceFile:
  339. return ts.isExternalModule(node) ? 1 : 0;
  340. default:
  341. return 0;
  342. }
  343. }
  344. exports.isFunctionScopeBoundary = isFunctionScopeBoundary;
  345. function isBlockScopeBoundary(node) {
  346. switch (node.kind) {
  347. case ts.SyntaxKind.Block:
  348. const parent = node.parent;
  349. return parent.kind !== ts.SyntaxKind.CatchClause &&
  350. (parent.kind === ts.SyntaxKind.SourceFile ||
  351. !isFunctionScopeBoundary(parent))
  352. ? 2
  353. : 0;
  354. case ts.SyntaxKind.ForStatement:
  355. case ts.SyntaxKind.ForInStatement:
  356. case ts.SyntaxKind.ForOfStatement:
  357. case ts.SyntaxKind.CaseBlock:
  358. case ts.SyntaxKind.CatchClause:
  359. case ts.SyntaxKind.WithStatement:
  360. return 2;
  361. default:
  362. return 0;
  363. }
  364. }
  365. exports.isBlockScopeBoundary = isBlockScopeBoundary;
  366. function hasOwnThisReference(node) {
  367. switch (node.kind) {
  368. case ts.SyntaxKind.ClassDeclaration:
  369. case ts.SyntaxKind.ClassExpression:
  370. case ts.SyntaxKind.FunctionExpression:
  371. return true;
  372. case ts.SyntaxKind.FunctionDeclaration:
  373. return node.body !== undefined;
  374. case ts.SyntaxKind.MethodDeclaration:
  375. case ts.SyntaxKind.GetAccessor:
  376. case ts.SyntaxKind.SetAccessor:
  377. return node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression;
  378. default:
  379. return false;
  380. }
  381. }
  382. exports.hasOwnThisReference = hasOwnThisReference;
  383. function isFunctionWithBody(node) {
  384. switch (node.kind) {
  385. case ts.SyntaxKind.GetAccessor:
  386. case ts.SyntaxKind.SetAccessor:
  387. case ts.SyntaxKind.FunctionDeclaration:
  388. case ts.SyntaxKind.MethodDeclaration:
  389. case ts.SyntaxKind.Constructor:
  390. return node.body !== undefined;
  391. case ts.SyntaxKind.FunctionExpression:
  392. case ts.SyntaxKind.ArrowFunction:
  393. return true;
  394. default:
  395. return false;
  396. }
  397. }
  398. exports.isFunctionWithBody = isFunctionWithBody;
  399. function forEachToken(node, cb, sourceFile = node.getSourceFile()) {
  400. return (function iterate(child) {
  401. if (isTokenKind(child.kind))
  402. return cb(child);
  403. if (child.kind !== ts.SyntaxKind.JSDocComment)
  404. return child.getChildren(sourceFile).forEach(iterate);
  405. })(node);
  406. }
  407. exports.forEachToken = forEachToken;
  408. function forEachTokenWithTrivia(node, cb, sourceFile = node.getSourceFile()) {
  409. const fullText = sourceFile.text;
  410. const scanner = ts.createScanner(sourceFile.languageVersion, false, sourceFile.languageVariant, fullText);
  411. return forEachToken(node, (token) => {
  412. const tokenStart = token.kind === ts.SyntaxKind.JsxText || token.pos === token.end ? token.pos : token.getStart(sourceFile);
  413. if (tokenStart !== token.pos) {
  414. scanner.setTextPos(token.pos);
  415. let kind = scanner.scan();
  416. let pos = scanner.getTokenPos();
  417. while (pos < tokenStart) {
  418. const textPos = scanner.getTextPos();
  419. cb(fullText, kind, { pos, end: textPos }, token.parent);
  420. if (textPos === tokenStart)
  421. break;
  422. kind = scanner.scan();
  423. pos = scanner.getTokenPos();
  424. }
  425. }
  426. return cb(fullText, token.kind, { end: token.end, pos: tokenStart }, token.parent);
  427. }, sourceFile);
  428. }
  429. exports.forEachTokenWithTrivia = forEachTokenWithTrivia;
  430. function forEachComment(node, cb, sourceFile = node.getSourceFile()) {
  431. const fullText = sourceFile.text;
  432. const notJsx = sourceFile.languageVariant !== ts.LanguageVariant.JSX;
  433. return forEachToken(node, (token) => {
  434. if (token.pos === token.end)
  435. return;
  436. if (token.kind !== ts.SyntaxKind.JsxText)
  437. ts.forEachLeadingCommentRange(fullText, token.pos === 0 ? (ts.getShebang(fullText) || '').length : token.pos, commentCallback);
  438. if (notJsx || canHaveTrailingTrivia(token))
  439. return ts.forEachTrailingCommentRange(fullText, token.end, commentCallback);
  440. }, sourceFile);
  441. function commentCallback(pos, end, kind) {
  442. cb(fullText, { pos, end, kind });
  443. }
  444. }
  445. exports.forEachComment = forEachComment;
  446. function canHaveTrailingTrivia(token) {
  447. switch (token.kind) {
  448. case ts.SyntaxKind.CloseBraceToken:
  449. return token.parent.kind !== ts.SyntaxKind.JsxExpression || !isJsxElementOrFragment(token.parent.parent);
  450. case ts.SyntaxKind.GreaterThanToken:
  451. switch (token.parent.kind) {
  452. case ts.SyntaxKind.JsxOpeningElement:
  453. return token.end !== token.parent.end;
  454. case ts.SyntaxKind.JsxOpeningFragment:
  455. return false;
  456. case ts.SyntaxKind.JsxSelfClosingElement:
  457. return token.end !== token.parent.end ||
  458. !isJsxElementOrFragment(token.parent.parent);
  459. case ts.SyntaxKind.JsxClosingElement:
  460. case ts.SyntaxKind.JsxClosingFragment:
  461. return !isJsxElementOrFragment(token.parent.parent.parent);
  462. }
  463. }
  464. return true;
  465. }
  466. function isJsxElementOrFragment(node) {
  467. return node.kind === ts.SyntaxKind.JsxElement || node.kind === ts.SyntaxKind.JsxFragment;
  468. }
  469. function getLineRanges(sourceFile) {
  470. const lineStarts = sourceFile.getLineStarts();
  471. const result = [];
  472. const length = lineStarts.length;
  473. const sourceText = sourceFile.text;
  474. let pos = 0;
  475. for (let i = 1; i < length; ++i) {
  476. const end = lineStarts[i];
  477. let lineEnd = end;
  478. for (; lineEnd > pos; --lineEnd)
  479. if (!ts.isLineBreak(sourceText.charCodeAt(lineEnd - 1)))
  480. break;
  481. result.push({
  482. pos,
  483. end,
  484. contentLength: lineEnd - pos,
  485. });
  486. pos = end;
  487. }
  488. result.push({
  489. pos,
  490. end: sourceFile.end,
  491. contentLength: sourceFile.end - pos,
  492. });
  493. return result;
  494. }
  495. exports.getLineRanges = getLineRanges;
  496. function getLineBreakStyle(sourceFile) {
  497. const lineStarts = sourceFile.getLineStarts();
  498. return lineStarts.length === 1 || lineStarts[1] < 2 || sourceFile.text[lineStarts[1] - 2] !== '\r'
  499. ? '\n'
  500. : '\r\n';
  501. }
  502. exports.getLineBreakStyle = getLineBreakStyle;
  503. let cachedScanner;
  504. function scanToken(text, languageVersion) {
  505. if (cachedScanner === undefined) {
  506. cachedScanner = ts.createScanner(languageVersion, false, undefined, text);
  507. }
  508. else {
  509. cachedScanner.setScriptTarget(languageVersion);
  510. cachedScanner.setText(text);
  511. }
  512. cachedScanner.scan();
  513. return cachedScanner;
  514. }
  515. function isValidIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {
  516. const scan = scanToken(text, languageVersion);
  517. return scan.isIdentifier() && scan.getTextPos() === text.length && scan.getTokenPos() === 0;
  518. }
  519. exports.isValidIdentifier = isValidIdentifier;
  520. function charSize(ch) {
  521. return ch >= 0x10000 ? 2 : 1;
  522. }
  523. function isValidPropertyAccess(text, languageVersion = ts.ScriptTarget.Latest) {
  524. if (text.length === 0)
  525. return false;
  526. let ch = text.codePointAt(0);
  527. if (!ts.isIdentifierStart(ch, languageVersion))
  528. return false;
  529. for (let i = charSize(ch); i < text.length; i += charSize(ch)) {
  530. ch = text.codePointAt(i);
  531. if (!ts.isIdentifierPart(ch, languageVersion))
  532. return false;
  533. }
  534. return true;
  535. }
  536. exports.isValidPropertyAccess = isValidPropertyAccess;
  537. function isValidPropertyName(text, languageVersion = ts.ScriptTarget.Latest) {
  538. if (isValidPropertyAccess(text, languageVersion))
  539. return true;
  540. const scan = scanToken(text, languageVersion);
  541. return scan.getTextPos() === text.length &&
  542. scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTokenValue() === text;
  543. }
  544. exports.isValidPropertyName = isValidPropertyName;
  545. function isValidNumericLiteral(text, languageVersion = ts.ScriptTarget.Latest) {
  546. const scan = scanToken(text, languageVersion);
  547. return scan.getToken() === ts.SyntaxKind.NumericLiteral && scan.getTextPos() === text.length && scan.getTokenPos() === 0;
  548. }
  549. exports.isValidNumericLiteral = isValidNumericLiteral;
  550. function isValidJsxIdentifier(text, languageVersion = ts.ScriptTarget.Latest) {
  551. if (text.length === 0)
  552. return false;
  553. let ch = text.codePointAt(0);
  554. if (!ts.isIdentifierStart(ch, languageVersion))
  555. return false;
  556. for (let i = charSize(ch); i < text.length; i += charSize(ch)) {
  557. ch = text.codePointAt(i);
  558. if (!ts.isIdentifierPart(ch, languageVersion) && ch !== 45)
  559. return false;
  560. }
  561. return true;
  562. }
  563. exports.isValidJsxIdentifier = isValidJsxIdentifier;
  564. function isNumericPropertyName(name) {
  565. return String(+name) === name;
  566. }
  567. exports.isNumericPropertyName = isNumericPropertyName;
  568. function isSameLine(sourceFile, pos1, pos2) {
  569. return ts.getLineAndCharacterOfPosition(sourceFile, pos1).line === ts.getLineAndCharacterOfPosition(sourceFile, pos2).line;
  570. }
  571. exports.isSameLine = isSameLine;
  572. var SideEffectOptions;
  573. (function (SideEffectOptions) {
  574. SideEffectOptions[SideEffectOptions["None"] = 0] = "None";
  575. SideEffectOptions[SideEffectOptions["TaggedTemplate"] = 1] = "TaggedTemplate";
  576. SideEffectOptions[SideEffectOptions["Constructor"] = 2] = "Constructor";
  577. SideEffectOptions[SideEffectOptions["JsxElement"] = 4] = "JsxElement";
  578. })(SideEffectOptions = exports.SideEffectOptions || (exports.SideEffectOptions = {}));
  579. function hasSideEffects(node, options) {
  580. switch (node.kind) {
  581. case ts.SyntaxKind.CallExpression:
  582. case ts.SyntaxKind.PostfixUnaryExpression:
  583. case ts.SyntaxKind.AwaitExpression:
  584. case ts.SyntaxKind.YieldExpression:
  585. case ts.SyntaxKind.DeleteExpression:
  586. return true;
  587. case ts.SyntaxKind.TypeAssertionExpression:
  588. case ts.SyntaxKind.AsExpression:
  589. case ts.SyntaxKind.ParenthesizedExpression:
  590. case ts.SyntaxKind.NonNullExpression:
  591. case ts.SyntaxKind.VoidExpression:
  592. case ts.SyntaxKind.TypeOfExpression:
  593. case ts.SyntaxKind.PropertyAccessExpression:
  594. case ts.SyntaxKind.SpreadElement:
  595. case ts.SyntaxKind.PartiallyEmittedExpression:
  596. return hasSideEffects(node.expression, options);
  597. case ts.SyntaxKind.BinaryExpression:
  598. return isAssignmentKind(node.operatorToken.kind) ||
  599. hasSideEffects(node.left, options) ||
  600. hasSideEffects(node.right, options);
  601. case ts.SyntaxKind.PrefixUnaryExpression:
  602. switch (node.operator) {
  603. case ts.SyntaxKind.PlusPlusToken:
  604. case ts.SyntaxKind.MinusMinusToken:
  605. return true;
  606. default:
  607. return hasSideEffects(node.operand, options);
  608. }
  609. case ts.SyntaxKind.ElementAccessExpression:
  610. return hasSideEffects(node.expression, options) ||
  611. node.argumentExpression !== undefined &&
  612. hasSideEffects(node.argumentExpression, options);
  613. case ts.SyntaxKind.ConditionalExpression:
  614. return hasSideEffects(node.condition, options) ||
  615. hasSideEffects(node.whenTrue, options) ||
  616. hasSideEffects(node.whenFalse, options);
  617. case ts.SyntaxKind.NewExpression:
  618. if (options & 2 || hasSideEffects(node.expression, options))
  619. return true;
  620. if (node.arguments !== undefined)
  621. for (const child of node.arguments)
  622. if (hasSideEffects(child, options))
  623. return true;
  624. return false;
  625. case ts.SyntaxKind.TaggedTemplateExpression:
  626. if (options & 1 || hasSideEffects(node.tag, options))
  627. return true;
  628. if (node.template.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral)
  629. return false;
  630. node = node.template;
  631. case ts.SyntaxKind.TemplateExpression:
  632. for (const child of node.templateSpans)
  633. if (hasSideEffects(child.expression, options))
  634. return true;
  635. return false;
  636. case ts.SyntaxKind.ClassExpression:
  637. return classExpressionHasSideEffects(node, options);
  638. case ts.SyntaxKind.ArrayLiteralExpression:
  639. for (const child of node.elements)
  640. if (hasSideEffects(child, options))
  641. return true;
  642. return false;
  643. case ts.SyntaxKind.ObjectLiteralExpression:
  644. for (const child of node.properties) {
  645. if (child.name !== undefined && child.name.kind === ts.SyntaxKind.ComputedPropertyName &&
  646. hasSideEffects(child.name.expression, options))
  647. return true;
  648. switch (child.kind) {
  649. case ts.SyntaxKind.PropertyAssignment:
  650. if (hasSideEffects(child.initializer, options))
  651. return true;
  652. break;
  653. case ts.SyntaxKind.SpreadAssignment:
  654. if (hasSideEffects(child.expression, options))
  655. return true;
  656. }
  657. }
  658. return false;
  659. case ts.SyntaxKind.JsxExpression:
  660. return node.expression !== undefined && hasSideEffects(node.expression, options);
  661. case ts.SyntaxKind.JsxElement:
  662. case ts.SyntaxKind.JsxFragment:
  663. for (const child of node.children)
  664. if (child.kind !== ts.SyntaxKind.JsxText && hasSideEffects(child, options))
  665. return true;
  666. if (node.kind === ts.SyntaxKind.JsxFragment)
  667. return false;
  668. node = node.openingElement;
  669. case ts.SyntaxKind.JsxSelfClosingElement:
  670. case ts.SyntaxKind.JsxOpeningElement:
  671. if (options & 4)
  672. return true;
  673. for (const child of node.attributes.properties) {
  674. if (child.kind === ts.SyntaxKind.JsxSpreadAttribute) {
  675. if (hasSideEffects(child.expression, options))
  676. return true;
  677. }
  678. else if (child.initializer !== undefined && hasSideEffects(child.initializer, options)) {
  679. return true;
  680. }
  681. }
  682. return false;
  683. case ts.SyntaxKind.CommaListExpression:
  684. for (const child of node.elements)
  685. if (hasSideEffects(child, options))
  686. return true;
  687. return false;
  688. default:
  689. return false;
  690. }
  691. }
  692. exports.hasSideEffects = hasSideEffects;
  693. function classExpressionHasSideEffects(node, options) {
  694. if (node.heritageClauses !== undefined && node.heritageClauses[0].token === ts.SyntaxKind.ExtendsKeyword)
  695. for (const base of node.heritageClauses[0].types)
  696. if (hasSideEffects(base.expression, options))
  697. return true;
  698. for (const child of node.members)
  699. if (child.name !== undefined && child.name.kind === ts.SyntaxKind.ComputedPropertyName &&
  700. hasSideEffects(child.name.expression, options) ||
  701. node_1.isPropertyDeclaration(child) && child.initializer !== undefined &&
  702. hasSideEffects(child.initializer, options))
  703. return true;
  704. return false;
  705. }
  706. function getDeclarationOfBindingElement(node) {
  707. let parent = node.parent.parent;
  708. while (parent.kind === ts.SyntaxKind.BindingElement)
  709. parent = parent.parent.parent;
  710. return parent;
  711. }
  712. exports.getDeclarationOfBindingElement = getDeclarationOfBindingElement;
  713. function isExpressionValueUsed(node) {
  714. while (true) {
  715. const parent = node.parent;
  716. switch (parent.kind) {
  717. case ts.SyntaxKind.CallExpression:
  718. case ts.SyntaxKind.NewExpression:
  719. case ts.SyntaxKind.ElementAccessExpression:
  720. case ts.SyntaxKind.WhileStatement:
  721. case ts.SyntaxKind.DoStatement:
  722. case ts.SyntaxKind.WithStatement:
  723. case ts.SyntaxKind.ThrowStatement:
  724. case ts.SyntaxKind.ReturnStatement:
  725. case ts.SyntaxKind.JsxExpression:
  726. case ts.SyntaxKind.JsxSpreadAttribute:
  727. case ts.SyntaxKind.JsxElement:
  728. case ts.SyntaxKind.JsxFragment:
  729. case ts.SyntaxKind.JsxSelfClosingElement:
  730. case ts.SyntaxKind.ComputedPropertyName:
  731. case ts.SyntaxKind.ArrowFunction:
  732. case ts.SyntaxKind.ExportSpecifier:
  733. case ts.SyntaxKind.ExportAssignment:
  734. case ts.SyntaxKind.ImportDeclaration:
  735. case ts.SyntaxKind.ExternalModuleReference:
  736. case ts.SyntaxKind.Decorator:
  737. case ts.SyntaxKind.TaggedTemplateExpression:
  738. case ts.SyntaxKind.TemplateSpan:
  739. case ts.SyntaxKind.ExpressionWithTypeArguments:
  740. case ts.SyntaxKind.TypeOfExpression:
  741. case ts.SyntaxKind.AwaitExpression:
  742. case ts.SyntaxKind.YieldExpression:
  743. case ts.SyntaxKind.LiteralType:
  744. case ts.SyntaxKind.JsxAttributes:
  745. case ts.SyntaxKind.JsxOpeningElement:
  746. case ts.SyntaxKind.JsxClosingElement:
  747. case ts.SyntaxKind.IfStatement:
  748. case ts.SyntaxKind.CaseClause:
  749. case ts.SyntaxKind.SwitchStatement:
  750. return true;
  751. case ts.SyntaxKind.PropertyAccessExpression:
  752. return parent.expression === node;
  753. case ts.SyntaxKind.QualifiedName:
  754. return parent.left === node;
  755. case ts.SyntaxKind.ShorthandPropertyAssignment:
  756. return parent.objectAssignmentInitializer === node ||
  757. !isInDestructuringAssignment(parent);
  758. case ts.SyntaxKind.PropertyAssignment:
  759. return parent.initializer === node && !isInDestructuringAssignment(parent);
  760. case ts.SyntaxKind.SpreadAssignment:
  761. case ts.SyntaxKind.SpreadElement:
  762. case ts.SyntaxKind.ArrayLiteralExpression:
  763. return !isInDestructuringAssignment(parent);
  764. case ts.SyntaxKind.ParenthesizedExpression:
  765. case ts.SyntaxKind.AsExpression:
  766. case ts.SyntaxKind.TypeAssertionExpression:
  767. case ts.SyntaxKind.PostfixUnaryExpression:
  768. case ts.SyntaxKind.PrefixUnaryExpression:
  769. case ts.SyntaxKind.NonNullExpression:
  770. node = parent;
  771. break;
  772. case ts.SyntaxKind.ForStatement:
  773. return parent.condition === node;
  774. case ts.SyntaxKind.ForInStatement:
  775. case ts.SyntaxKind.ForOfStatement:
  776. return parent.expression === node;
  777. case ts.SyntaxKind.ConditionalExpression:
  778. if (parent.condition === node)
  779. return true;
  780. node = parent;
  781. break;
  782. case ts.SyntaxKind.PropertyDeclaration:
  783. case ts.SyntaxKind.BindingElement:
  784. case ts.SyntaxKind.VariableDeclaration:
  785. case ts.SyntaxKind.Parameter:
  786. case ts.SyntaxKind.EnumMember:
  787. return parent.initializer === node;
  788. case ts.SyntaxKind.ImportEqualsDeclaration:
  789. return parent.moduleReference === node;
  790. case ts.SyntaxKind.CommaListExpression:
  791. if (parent.elements[parent.elements.length - 1] !== node)
  792. return false;
  793. node = parent;
  794. break;
  795. case ts.SyntaxKind.BinaryExpression:
  796. if (parent.right === node) {
  797. if (parent.operatorToken.kind === ts.SyntaxKind.CommaToken) {
  798. node = parent;
  799. break;
  800. }
  801. return true;
  802. }
  803. switch (parent.operatorToken.kind) {
  804. case ts.SyntaxKind.CommaToken:
  805. case ts.SyntaxKind.EqualsToken:
  806. return false;
  807. case ts.SyntaxKind.EqualsEqualsEqualsToken:
  808. case ts.SyntaxKind.EqualsEqualsToken:
  809. case ts.SyntaxKind.ExclamationEqualsEqualsToken:
  810. case ts.SyntaxKind.ExclamationEqualsToken:
  811. case ts.SyntaxKind.InstanceOfKeyword:
  812. case ts.SyntaxKind.PlusToken:
  813. case ts.SyntaxKind.MinusToken:
  814. case ts.SyntaxKind.AsteriskToken:
  815. case ts.SyntaxKind.SlashToken:
  816. case ts.SyntaxKind.PercentToken:
  817. case ts.SyntaxKind.AsteriskAsteriskToken:
  818. case ts.SyntaxKind.GreaterThanToken:
  819. case ts.SyntaxKind.GreaterThanGreaterThanToken:
  820. case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
  821. case ts.SyntaxKind.GreaterThanEqualsToken:
  822. case ts.SyntaxKind.LessThanToken:
  823. case ts.SyntaxKind.LessThanLessThanToken:
  824. case ts.SyntaxKind.LessThanEqualsToken:
  825. case ts.SyntaxKind.AmpersandToken:
  826. case ts.SyntaxKind.BarToken:
  827. case ts.SyntaxKind.CaretToken:
  828. case ts.SyntaxKind.BarBarToken:
  829. case ts.SyntaxKind.AmpersandAmpersandToken:
  830. case ts.SyntaxKind.InKeyword:
  831. return true;
  832. default:
  833. node = parent;
  834. }
  835. break;
  836. default:
  837. return false;
  838. }
  839. }
  840. }
  841. exports.isExpressionValueUsed = isExpressionValueUsed;
  842. function isInDestructuringAssignment(node) {
  843. switch (node.kind) {
  844. case ts.SyntaxKind.ShorthandPropertyAssignment:
  845. if (node.objectAssignmentInitializer !== undefined)
  846. return true;
  847. case ts.SyntaxKind.PropertyAssignment:
  848. case ts.SyntaxKind.SpreadAssignment:
  849. node = node.parent;
  850. break;
  851. case ts.SyntaxKind.SpreadElement:
  852. if (node.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)
  853. return false;
  854. node = node.parent;
  855. }
  856. while (true) {
  857. switch (node.parent.kind) {
  858. case ts.SyntaxKind.BinaryExpression:
  859. return node.parent.left === node &&
  860. node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken;
  861. case ts.SyntaxKind.ForOfStatement:
  862. return node.parent.initializer === node;
  863. case ts.SyntaxKind.ArrayLiteralExpression:
  864. case ts.SyntaxKind.ObjectLiteralExpression:
  865. node = node.parent;
  866. break;
  867. case ts.SyntaxKind.SpreadAssignment:
  868. case ts.SyntaxKind.PropertyAssignment:
  869. node = node.parent.parent;
  870. break;
  871. case ts.SyntaxKind.SpreadElement:
  872. if (node.parent.parent.kind !== ts.SyntaxKind.ArrayLiteralExpression)
  873. return false;
  874. node = node.parent.parent;
  875. break;
  876. default:
  877. return false;
  878. }
  879. }
  880. }
  881. var AccessKind;
  882. (function (AccessKind) {
  883. AccessKind[AccessKind["None"] = 0] = "None";
  884. AccessKind[AccessKind["Read"] = 1] = "Read";
  885. AccessKind[AccessKind["Write"] = 2] = "Write";
  886. AccessKind[AccessKind["Delete"] = 4] = "Delete";
  887. AccessKind[AccessKind["ReadWrite"] = 3] = "ReadWrite";
  888. AccessKind[AccessKind["Modification"] = 6] = "Modification";
  889. })(AccessKind = exports.AccessKind || (exports.AccessKind = {}));
  890. function getAccessKind(node) {
  891. const parent = node.parent;
  892. switch (parent.kind) {
  893. case ts.SyntaxKind.DeleteExpression:
  894. return 4;
  895. case ts.SyntaxKind.PostfixUnaryExpression:
  896. return 3;
  897. case ts.SyntaxKind.PrefixUnaryExpression:
  898. return parent.operator === ts.SyntaxKind.PlusPlusToken ||
  899. parent.operator === ts.SyntaxKind.MinusMinusToken
  900. ? 3
  901. : 1;
  902. case ts.SyntaxKind.BinaryExpression:
  903. return parent.right === node
  904. ? 1
  905. : !isAssignmentKind(parent.operatorToken.kind)
  906. ? 1
  907. : parent.operatorToken.kind === ts.SyntaxKind.EqualsToken
  908. ? 2
  909. : 3;
  910. case ts.SyntaxKind.ShorthandPropertyAssignment:
  911. return parent.objectAssignmentInitializer === node
  912. ? 1
  913. : isInDestructuringAssignment(parent)
  914. ? 2
  915. : 1;
  916. case ts.SyntaxKind.PropertyAssignment:
  917. return parent.name === node
  918. ? 0
  919. : isInDestructuringAssignment(parent)
  920. ? 2
  921. : 1;
  922. case ts.SyntaxKind.ArrayLiteralExpression:
  923. case ts.SyntaxKind.SpreadElement:
  924. case ts.SyntaxKind.SpreadAssignment:
  925. return isInDestructuringAssignment(parent)
  926. ? 2
  927. : 1;
  928. case ts.SyntaxKind.ParenthesizedExpression:
  929. case ts.SyntaxKind.NonNullExpression:
  930. case ts.SyntaxKind.TypeAssertionExpression:
  931. case ts.SyntaxKind.AsExpression:
  932. return getAccessKind(parent);
  933. case ts.SyntaxKind.ForOfStatement:
  934. case ts.SyntaxKind.ForInStatement:
  935. return parent.initializer === node
  936. ? 2
  937. : 1;
  938. case ts.SyntaxKind.ExpressionWithTypeArguments:
  939. return parent.parent.token === ts.SyntaxKind.ExtendsKeyword &&
  940. parent.parent.parent.kind !== ts.SyntaxKind.InterfaceDeclaration
  941. ? 1
  942. : 0;
  943. case ts.SyntaxKind.ComputedPropertyName:
  944. case ts.SyntaxKind.ExpressionStatement:
  945. case ts.SyntaxKind.TypeOfExpression:
  946. case ts.SyntaxKind.ElementAccessExpression:
  947. case ts.SyntaxKind.ForStatement:
  948. case ts.SyntaxKind.IfStatement:
  949. case ts.SyntaxKind.DoStatement:
  950. case ts.SyntaxKind.WhileStatement:
  951. case ts.SyntaxKind.SwitchStatement:
  952. case ts.SyntaxKind.WithStatement:
  953. case ts.SyntaxKind.ThrowStatement:
  954. case ts.SyntaxKind.CallExpression:
  955. case ts.SyntaxKind.NewExpression:
  956. case ts.SyntaxKind.TaggedTemplateExpression:
  957. case ts.SyntaxKind.JsxExpression:
  958. case ts.SyntaxKind.Decorator:
  959. case ts.SyntaxKind.TemplateSpan:
  960. case ts.SyntaxKind.JsxOpeningElement:
  961. case ts.SyntaxKind.JsxSelfClosingElement:
  962. case ts.SyntaxKind.JsxSpreadAttribute:
  963. case ts.SyntaxKind.VoidExpression:
  964. case ts.SyntaxKind.ReturnStatement:
  965. case ts.SyntaxKind.AwaitExpression:
  966. case ts.SyntaxKind.YieldExpression:
  967. case ts.SyntaxKind.ConditionalExpression:
  968. case ts.SyntaxKind.CaseClause:
  969. case ts.SyntaxKind.JsxElement:
  970. return 1;
  971. case ts.SyntaxKind.ArrowFunction:
  972. return parent.body === node
  973. ? 1
  974. : 2;
  975. case ts.SyntaxKind.PropertyDeclaration:
  976. case ts.SyntaxKind.VariableDeclaration:
  977. case ts.SyntaxKind.Parameter:
  978. case ts.SyntaxKind.EnumMember:
  979. case ts.SyntaxKind.BindingElement:
  980. case ts.SyntaxKind.JsxAttribute:
  981. return parent.initializer === node
  982. ? 1
  983. : 0;
  984. case ts.SyntaxKind.PropertyAccessExpression:
  985. return parent.expression === node
  986. ? 1
  987. : 0;
  988. case ts.SyntaxKind.ExportAssignment:
  989. return parent.isExportEquals
  990. ? 1
  991. : 0;
  992. }
  993. return 0;
  994. }
  995. exports.getAccessKind = getAccessKind;
  996. function isReassignmentTarget(node) {
  997. return (getAccessKind(node) & 2) !== 0;
  998. }
  999. exports.isReassignmentTarget = isReassignmentTarget;
  1000. function canHaveJsDoc(node) {
  1001. const kind = node.kind;
  1002. switch (kind) {
  1003. case ts.SyntaxKind.Parameter:
  1004. case ts.SyntaxKind.CallSignature:
  1005. case ts.SyntaxKind.ConstructSignature:
  1006. case ts.SyntaxKind.MethodSignature:
  1007. case ts.SyntaxKind.PropertySignature:
  1008. case ts.SyntaxKind.ArrowFunction:
  1009. case ts.SyntaxKind.ParenthesizedExpression:
  1010. case ts.SyntaxKind.SpreadAssignment:
  1011. case ts.SyntaxKind.ShorthandPropertyAssignment:
  1012. case ts.SyntaxKind.PropertyAssignment:
  1013. case ts.SyntaxKind.FunctionExpression:
  1014. case ts.SyntaxKind.FunctionDeclaration:
  1015. case ts.SyntaxKind.LabeledStatement:
  1016. case ts.SyntaxKind.ExpressionStatement:
  1017. case ts.SyntaxKind.VariableStatement:
  1018. case ts.SyntaxKind.Constructor:
  1019. case ts.SyntaxKind.MethodDeclaration:
  1020. case ts.SyntaxKind.PropertyDeclaration:
  1021. case ts.SyntaxKind.GetAccessor:
  1022. case ts.SyntaxKind.SetAccessor:
  1023. case ts.SyntaxKind.ClassDeclaration:
  1024. case ts.SyntaxKind.ClassExpression:
  1025. case ts.SyntaxKind.InterfaceDeclaration:
  1026. case ts.SyntaxKind.TypeAliasDeclaration:
  1027. case ts.SyntaxKind.EnumMember:
  1028. case ts.SyntaxKind.EnumDeclaration:
  1029. case ts.SyntaxKind.ModuleDeclaration:
  1030. case ts.SyntaxKind.ImportEqualsDeclaration:
  1031. case ts.SyntaxKind.IndexSignature:
  1032. case ts.SyntaxKind.FunctionType:
  1033. case ts.SyntaxKind.ConstructorType:
  1034. case ts.SyntaxKind.JSDocFunctionType:
  1035. case ts.SyntaxKind.EndOfFileToken:
  1036. case ts.SyntaxKind.ExportDeclaration:
  1037. return true;
  1038. default:
  1039. return false;
  1040. }
  1041. }
  1042. exports.canHaveJsDoc = canHaveJsDoc;
  1043. function getJsDoc(node, sourceFile) {
  1044. if (node.kind === ts.SyntaxKind.EndOfFileToken)
  1045. return parseJsDocWorker(node, sourceFile || node.parent);
  1046. const result = [];
  1047. for (const child of node.getChildren(sourceFile)) {
  1048. if (!node_1.isJsDoc(child))
  1049. break;
  1050. result.push(child);
  1051. }
  1052. return result;
  1053. }
  1054. exports.getJsDoc = getJsDoc;
  1055. function parseJsDocOfNode(node, considerTrailingComments, sourceFile = node.getSourceFile()) {
  1056. if (canHaveJsDoc(node) && node.kind !== ts.SyntaxKind.EndOfFileToken) {
  1057. const result = getJsDoc(node, sourceFile);
  1058. if (result.length !== 0 || !considerTrailingComments)
  1059. return result;
  1060. }
  1061. return parseJsDocWorker(node, sourceFile, considerTrailingComments);
  1062. }
  1063. exports.parseJsDocOfNode = parseJsDocOfNode;
  1064. function parseJsDocWorker(node, sourceFile, considerTrailingComments) {
  1065. const nodeStart = node.getStart(sourceFile);
  1066. const start = ts[considerTrailingComments && isSameLine(sourceFile, node.pos, nodeStart)
  1067. ? 'forEachTrailingCommentRange'
  1068. : 'forEachLeadingCommentRange'](sourceFile.text, node.pos, (pos, _end, kind) => kind === ts.SyntaxKind.MultiLineCommentTrivia && sourceFile.text[pos + 2] === '*' ? { pos } : undefined);
  1069. if (start === undefined)
  1070. return [];
  1071. const startPos = start.pos;
  1072. const text = sourceFile.text.slice(startPos, nodeStart);
  1073. const newSourceFile = ts.createSourceFile('jsdoc.ts', `${text}var a;`, sourceFile.languageVersion);
  1074. const result = getJsDoc(newSourceFile.statements[0], newSourceFile);
  1075. for (const doc of result)
  1076. updateNode(doc, node);
  1077. return result;
  1078. function updateNode(n, parent) {
  1079. n.pos += startPos;
  1080. n.end += startPos;
  1081. n.parent = parent;
  1082. return ts.forEachChild(n, (child) => updateNode(child, n), (children) => {
  1083. children.pos += startPos;
  1084. children.end += startPos;
  1085. for (const child of children)
  1086. updateNode(child, n);
  1087. });
  1088. }
  1089. }
  1090. var ImportKind;
  1091. (function (ImportKind) {
  1092. ImportKind[ImportKind["ImportDeclaration"] = 1] = "ImportDeclaration";
  1093. ImportKind[ImportKind["ImportEquals"] = 2] = "ImportEquals";
  1094. ImportKind[ImportKind["ExportFrom"] = 4] = "ExportFrom";
  1095. ImportKind[ImportKind["DynamicImport"] = 8] = "DynamicImport";
  1096. ImportKind[ImportKind["Require"] = 16] = "Require";
  1097. ImportKind[ImportKind["ImportType"] = 32] = "ImportType";
  1098. ImportKind[ImportKind["All"] = 63] = "All";
  1099. ImportKind[ImportKind["AllImports"] = 59] = "AllImports";
  1100. ImportKind[ImportKind["AllStaticImports"] = 3] = "AllStaticImports";
  1101. ImportKind[ImportKind["AllImportExpressions"] = 24] = "AllImportExpressions";
  1102. ImportKind[ImportKind["AllRequireLike"] = 18] = "AllRequireLike";
  1103. ImportKind[ImportKind["AllNestedImports"] = 56] = "AllNestedImports";
  1104. ImportKind[ImportKind["AllTopLevelImports"] = 7] = "AllTopLevelImports";
  1105. })(ImportKind = exports.ImportKind || (exports.ImportKind = {}));
  1106. function findImports(sourceFile, kinds) {
  1107. const result = [];
  1108. for (const node of findImportLikeNodes(sourceFile, kinds)) {
  1109. switch (node.kind) {
  1110. case ts.SyntaxKind.ImportDeclaration:
  1111. addIfTextualLiteral(node.moduleSpecifier);
  1112. break;
  1113. case ts.SyntaxKind.ImportEqualsDeclaration:
  1114. addIfTextualLiteral(node.moduleReference.expression);
  1115. break;
  1116. case ts.SyntaxKind.ExportDeclaration:
  1117. addIfTextualLiteral(node.moduleSpecifier);
  1118. break;
  1119. case ts.SyntaxKind.CallExpression:
  1120. addIfTextualLiteral(node.arguments[0]);
  1121. break;
  1122. case ts.SyntaxKind.ImportType:
  1123. if (node_1.isLiteralTypeNode(node.argument))
  1124. addIfTextualLiteral(node.argument.literal);
  1125. break;
  1126. default:
  1127. throw new Error('unexpected node');
  1128. }
  1129. }
  1130. return result;
  1131. function addIfTextualLiteral(node) {
  1132. if (node_1.isTextualLiteral(node))
  1133. result.push(node);
  1134. }
  1135. }
  1136. exports.findImports = findImports;
  1137. function findImportLikeNodes(sourceFile, kinds) {
  1138. return new ImportFinder(sourceFile, kinds).find();
  1139. }
  1140. exports.findImportLikeNodes = findImportLikeNodes;
  1141. class ImportFinder {
  1142. constructor(_sourceFile, _options) {
  1143. this._sourceFile = _sourceFile;
  1144. this._options = _options;
  1145. this._result = [];
  1146. }
  1147. find() {
  1148. if (this._sourceFile.isDeclarationFile)
  1149. this._options &= ~24;
  1150. if (this._options & 7)
  1151. this._findImports(this._sourceFile.statements);
  1152. if (this._options & 56)
  1153. this._findNestedImports();
  1154. return this._result;
  1155. }
  1156. _findImports(statements) {
  1157. for (const statement of statements) {
  1158. if (node_1.isImportDeclaration(statement)) {
  1159. if (this._options & 1)
  1160. this._result.push(statement);
  1161. }
  1162. else if (node_1.isImportEqualsDeclaration(statement)) {
  1163. if (this._options & 2 &&
  1164. statement.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference)
  1165. this._result.push(statement);
  1166. }
  1167. else if (node_1.isExportDeclaration(statement)) {
  1168. if (statement.moduleSpecifier !== undefined && this._options & 4)
  1169. this._result.push(statement);
  1170. }
  1171. else if (node_1.isModuleDeclaration(statement)) {
  1172. this._findImportsInModule(statement);
  1173. }
  1174. }
  1175. }
  1176. _findImportsInModule(declaration) {
  1177. if (declaration.body === undefined)
  1178. return;
  1179. if (declaration.body.kind === ts.SyntaxKind.ModuleDeclaration)
  1180. return this._findImportsInModule(declaration.body);
  1181. this._findImports(declaration.body.statements);
  1182. }
  1183. _findNestedImports() {
  1184. let re;
  1185. if ((this._options & 56) === 16) {
  1186. re = /\brequire\s*[</(]/g;
  1187. }
  1188. else if (this._options & 16) {
  1189. re = /\b(?:import|require)\s*[</(]/g;
  1190. }
  1191. else {
  1192. re = /\bimport\s*[</(]/g;
  1193. }
  1194. const isJavaScriptFile = (this._sourceFile.flags & ts.NodeFlags.JavaScriptFile) !== 0;
  1195. for (let match = re.exec(this._sourceFile.text); match !== null; match = re.exec(this._sourceFile.text)) {
  1196. const token = getTokenAtPositionWorker(this._sourceFile, match.index, this._sourceFile, match[0][0] === 'i' && isJavaScriptFile);
  1197. if (token.kind === ts.SyntaxKind.ImportKeyword) {
  1198. if (token.end - 'import'.length !== match.index)
  1199. continue;
  1200. switch (token.parent.kind) {
  1201. case ts.SyntaxKind.ImportType:
  1202. this._result.push(token.parent);
  1203. break;
  1204. case ts.SyntaxKind.CallExpression:
  1205. if (token.parent.arguments.length === 1)
  1206. this._result.push(token.parent);
  1207. }
  1208. }
  1209. else if (token.kind === ts.SyntaxKind.Identifier &&
  1210. token.end - 'require'.length === match.index &&
  1211. token.parent.kind === ts.SyntaxKind.CallExpression &&
  1212. token.parent.expression === token &&
  1213. token.parent.arguments.length === 1) {
  1214. this._result.push(token.parent);
  1215. }
  1216. }
  1217. }
  1218. }
  1219. function isStatementInAmbientContext(node) {
  1220. while (node.flags & ts.NodeFlags.NestedNamespace)
  1221. node = node.parent;
  1222. return hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword) || isAmbientModuleBlock(node.parent);
  1223. }
  1224. exports.isStatementInAmbientContext = isStatementInAmbientContext;
  1225. function isAmbientModuleBlock(node) {
  1226. while (node.kind === ts.SyntaxKind.ModuleBlock) {
  1227. do
  1228. node = node.parent;
  1229. while (node.flags & ts.NodeFlags.NestedNamespace);
  1230. if (hasModifier(node.modifiers, ts.SyntaxKind.DeclareKeyword))
  1231. return true;
  1232. node = node.parent;
  1233. }
  1234. return false;
  1235. }
  1236. exports.isAmbientModuleBlock = isAmbientModuleBlock;
  1237. function getIIFE(func) {
  1238. let node = func.parent;
  1239. while (node.kind === ts.SyntaxKind.ParenthesizedExpression)
  1240. node = node.parent;
  1241. return node_1.isCallExpression(node) && func.end <= node.expression.end ? node : undefined;
  1242. }
  1243. exports.getIIFE = getIIFE;
  1244. function isStrictCompilerOptionEnabled(options, option) {
  1245. return (options.strict ? options[option] !== false : options[option] === true) &&
  1246. (option !== 'strictPropertyInitialization' || isStrictCompilerOptionEnabled(options, 'strictNullChecks'));
  1247. }
  1248. exports.isStrictCompilerOptionEnabled = isStrictCompilerOptionEnabled;
  1249. function isCompilerOptionEnabled(options, option) {
  1250. switch (option) {
  1251. case 'stripInternal':
  1252. return options.stripInternal === true && isCompilerOptionEnabled(options, 'declaration');
  1253. case 'declaration':
  1254. return options.declaration || isCompilerOptionEnabled(options, 'composite');
  1255. case 'incremental':
  1256. return options.incremental === undefined ? isCompilerOptionEnabled(options, 'composite') : options.incremental;
  1257. case 'skipDefaultLibCheck':
  1258. return options.skipDefaultLibCheck || isCompilerOptionEnabled(options, 'skipLibCheck');
  1259. case 'suppressImplicitAnyIndexErrors':
  1260. return options.suppressImplicitAnyIndexErrors === true && isCompilerOptionEnabled(options, 'noImplicitAny');
  1261. case 'allowSyntheticDefaultImports':
  1262. return options.allowSyntheticDefaultImports !== undefined
  1263. ? options.allowSyntheticDefaultImports
  1264. : isCompilerOptionEnabled(options, 'esModuleInterop') || options.module === ts.ModuleKind.System;
  1265. case 'noImplicitAny':
  1266. case 'noImplicitThis':
  1267. case 'strictNullChecks':
  1268. case 'strictFunctionTypes':
  1269. case 'strictPropertyInitialization':
  1270. case 'alwaysStrict':
  1271. case 'strictBindCallApply':
  1272. return isStrictCompilerOptionEnabled(options, option);
  1273. }
  1274. return options[option] === true;
  1275. }
  1276. exports.isCompilerOptionEnabled = isCompilerOptionEnabled;
  1277. function isAmbientModule(node) {
  1278. return node.name.kind === ts.SyntaxKind.StringLiteral || (node.flags & ts.NodeFlags.GlobalAugmentation) !== 0;
  1279. }
  1280. exports.isAmbientModule = isAmbientModule;
  1281. function getCheckJsDirective(source) {
  1282. let directive;
  1283. ts.forEachLeadingCommentRange(source, (ts.getShebang(source) || '').length, (pos, end, kind) => {
  1284. if (kind === ts.SyntaxKind.SingleLineCommentTrivia) {
  1285. const text = source.slice(pos, end);
  1286. const match = /^\/{2,3}\s*@ts-(no)?check(?:\s|$)/i.exec(text);
  1287. if (match !== null)
  1288. directive = { pos, end, enabled: match[1] === undefined };
  1289. }
  1290. });
  1291. return directive;
  1292. }
  1293. exports.getCheckJsDirective = getCheckJsDirective;
  1294. function isConstAssertion(node) {
  1295. return node_1.isTypeReferenceNode(node.type) &&
  1296. node.type.typeName.kind === ts.SyntaxKind.Identifier &&
  1297. node.type.typeName.escapedText === 'const';
  1298. }
  1299. exports.isConstAssertion = isConstAssertion;
  1300. function isInConstContext(node) {
  1301. let current = node;
  1302. while (true) {
  1303. const parent = current.parent;
  1304. outer: switch (parent.kind) {
  1305. case ts.SyntaxKind.TypeAssertionExpression:
  1306. case ts.SyntaxKind.AsExpression:
  1307. return isConstAssertion(parent);
  1308. case ts.SyntaxKind.PrefixUnaryExpression:
  1309. if (current.kind !== ts.SyntaxKind.NumericLiteral)
  1310. return false;
  1311. switch (parent.operator) {
  1312. case ts.SyntaxKind.PlusToken:
  1313. case ts.SyntaxKind.MinusToken:
  1314. current = parent;
  1315. break outer;
  1316. default:
  1317. return false;
  1318. }
  1319. case ts.SyntaxKind.PropertyAssignment:
  1320. if (parent.initializer !== current)
  1321. return false;
  1322. current = parent.parent;
  1323. break;
  1324. case ts.SyntaxKind.ShorthandPropertyAssignment:
  1325. current = parent.parent;
  1326. break;
  1327. case ts.SyntaxKind.ParenthesizedExpression:
  1328. case ts.SyntaxKind.ArrayLiteralExpression:
  1329. case ts.SyntaxKind.ObjectLiteralExpression:
  1330. current = parent;
  1331. break;
  1332. default:
  1333. return false;
  1334. }
  1335. }
  1336. }
  1337. exports.isInConstContext = isInConstContext;
  1338. function isReadonlyAssignmentDeclaration(node, checker) {
  1339. if (!isBindableObjectDefinePropertyCall(node))
  1340. return false;
  1341. const descriptorType = checker.getTypeAtLocation(node.arguments[2]);
  1342. if (descriptorType.getProperty('value') === undefined)
  1343. return descriptorType.getProperty('set') === undefined;
  1344. const writableProp = descriptorType.getProperty('writable');
  1345. if (writableProp === undefined)
  1346. return false;
  1347. const writableType = writableProp.valueDeclaration !== undefined && node_1.isPropertyAssignment(writableProp.valueDeclaration)
  1348. ? checker.getTypeAtLocation(writableProp.valueDeclaration.initializer)
  1349. : checker.getTypeOfSymbolAtLocation(writableProp, node.arguments[2]);
  1350. return type_1.isBooleanLiteralType(writableType, false);
  1351. }
  1352. exports.isReadonlyAssignmentDeclaration = isReadonlyAssignmentDeclaration;
  1353. function isBindableObjectDefinePropertyCall(node) {
  1354. return node.arguments.length === 3 &&
  1355. node_1.isEntityNameExpression(node.arguments[0]) &&
  1356. node_1.isNumericOrStringLikeLiteral(node.arguments[1]) &&
  1357. node_1.isPropertyAccessExpression(node.expression) &&
  1358. node.expression.name.escapedText === 'defineProperty' &&
  1359. node_1.isIdentifier(node.expression.expression) &&
  1360. node.expression.expression.escapedText === 'Object';
  1361. }
  1362. exports.isBindableObjectDefinePropertyCall = isBindableObjectDefinePropertyCall;
  1363. function isWellKnownSymbolLiterally(node) {
  1364. return ts.isPropertyAccessExpression(node) &&
  1365. ts.isIdentifier(node.expression) &&
  1366. node.expression.escapedText === 'Symbol';
  1367. }
  1368. exports.isWellKnownSymbolLiterally = isWellKnownSymbolLiterally;
  1369. function getPropertyNameOfWellKnownSymbol(node) {
  1370. return {
  1371. displayName: `[Symbol.${node.name.text}]`,
  1372. symbolName: ('__@' + node.name.text),
  1373. };
  1374. }
  1375. exports.getPropertyNameOfWellKnownSymbol = getPropertyNameOfWellKnownSymbol;
  1376. function getLateBoundPropertyNames(node, checker) {
  1377. const result = {
  1378. known: true,
  1379. names: [],
  1380. };
  1381. node = unwrapParentheses(node);
  1382. if (isWellKnownSymbolLiterally(node)) {
  1383. result.names.push(getPropertyNameOfWellKnownSymbol(node));
  1384. }
  1385. else {
  1386. const type = checker.getTypeAtLocation(node);
  1387. for (const key of type_1.unionTypeParts(checker.getBaseConstraintOfType(type) || type)) {
  1388. const propertyName = type_1.getPropertyNameFromType(key);
  1389. if (propertyName) {
  1390. result.names.push(propertyName);
  1391. }
  1392. else {
  1393. result.known = false;
  1394. }
  1395. }
  1396. }
  1397. return result;
  1398. }
  1399. exports.getLateBoundPropertyNames = getLateBoundPropertyNames;
  1400. function getLateBoundPropertyNamesOfPropertyName(node, checker) {
  1401. const staticName = getPropertyName(node);
  1402. return staticName !== undefined
  1403. ? { known: true, names: [{ displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) }] }
  1404. : getLateBoundPropertyNames(node.expression, checker);
  1405. }
  1406. exports.getLateBoundPropertyNamesOfPropertyName = getLateBoundPropertyNamesOfPropertyName;
  1407. function getSingleLateBoundPropertyNameOfPropertyName(node, checker) {
  1408. const staticName = getPropertyName(node);
  1409. if (staticName !== undefined)
  1410. return { displayName: staticName, symbolName: ts.escapeLeadingUnderscores(staticName) };
  1411. const { expression } = node;
  1412. return isWellKnownSymbolLiterally(expression)
  1413. ? getPropertyNameOfWellKnownSymbol(expression)
  1414. : type_1.getPropertyNameFromType(checker.getTypeAtLocation(expression));
  1415. }
  1416. exports.getSingleLateBoundPropertyNameOfPropertyName = getSingleLateBoundPropertyNameOfPropertyName;
  1417. function unwrapParentheses(node) {
  1418. while (node.kind === ts.SyntaxKind.ParenthesizedExpression)
  1419. node = node.expression;
  1420. return node;
  1421. }
  1422. exports.unwrapParentheses = unwrapParentheses;