flow.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = function (instance) {
  6. // plain function return types: function name(): string {}
  7. instance.extend("parseFunctionBody", function (inner) {
  8. return function (node, allowExpression) {
  9. if (this.match(_types.types.colon) && !allowExpression) {
  10. // if allowExpression is true then we're parsing an arrow function and if
  11. // there's a return type then it's been handled elsewhere
  12. node.returnType = this.flowParseTypeAnnotation();
  13. }
  14. return inner.call(this, node, allowExpression);
  15. };
  16. });
  17. // interfaces
  18. instance.extend("parseStatement", function (inner) {
  19. return function (declaration, topLevel) {
  20. // strict mode handling of `interface` since it's a reserved word
  21. if (this.state.strict && this.match(_types.types.name) && this.state.value === "interface") {
  22. var node = this.startNode();
  23. this.next();
  24. return this.flowParseInterface(node);
  25. } else {
  26. return inner.call(this, declaration, topLevel);
  27. }
  28. };
  29. });
  30. // declares, interfaces and type aliases
  31. instance.extend("parseExpressionStatement", function (inner) {
  32. return function (node, expr) {
  33. if (expr.type === "Identifier") {
  34. if (expr.name === "declare") {
  35. if (this.match(_types.types._class) || this.match(_types.types.name) || this.match(_types.types._function) || this.match(_types.types._var)) {
  36. return this.flowParseDeclare(node);
  37. }
  38. } else if (this.match(_types.types.name)) {
  39. if (expr.name === "interface") {
  40. return this.flowParseInterface(node);
  41. } else if (expr.name === "type") {
  42. return this.flowParseTypeAlias(node);
  43. }
  44. }
  45. }
  46. return inner.call(this, node, expr);
  47. };
  48. });
  49. // export type
  50. instance.extend("shouldParseExportDeclaration", function (inner) {
  51. return function () {
  52. return this.isContextual("type") || this.isContextual("interface") || inner.call(this);
  53. };
  54. });
  55. instance.extend("parseConditional", function (inner) {
  56. return function (expr, noIn, startPos, startLoc, refNeedsArrowPos) {
  57. // only do the expensive clone if there is a question mark
  58. // and if we come from inside parens
  59. if (refNeedsArrowPos && this.match(_types.types.question)) {
  60. var state = this.state.clone();
  61. try {
  62. return inner.call(this, expr, noIn, startPos, startLoc);
  63. } catch (err) {
  64. if (err instanceof SyntaxError) {
  65. this.state = state;
  66. refNeedsArrowPos.start = err.pos || this.state.start;
  67. return expr;
  68. } else {
  69. throw err;
  70. }
  71. }
  72. }
  73. return inner.call(this, expr, noIn, startPos, startLoc);
  74. };
  75. });
  76. instance.extend("parseParenItem", function (inner) {
  77. return function (node, startLoc, startPos) {
  78. node = inner.call(this, node, startLoc, startPos);
  79. if (this.eat(_types.types.question)) {
  80. node.optional = true;
  81. }
  82. if (this.match(_types.types.colon)) {
  83. var typeCastNode = this.startNodeAt(startLoc, startPos);
  84. typeCastNode.expression = node;
  85. typeCastNode.typeAnnotation = this.flowParseTypeAnnotation();
  86. return this.finishNode(typeCastNode, "TypeCastExpression");
  87. }
  88. return node;
  89. };
  90. });
  91. instance.extend("parseExport", function (inner) {
  92. return function (node) {
  93. node = inner.call(this, node);
  94. if (node.type === "ExportNamedDeclaration") {
  95. node.exportKind = node.exportKind || "value";
  96. }
  97. return node;
  98. };
  99. });
  100. instance.extend("parseExportDeclaration", function (inner) {
  101. return function (node) {
  102. if (this.isContextual("type")) {
  103. node.exportKind = "type";
  104. var declarationNode = this.startNode();
  105. this.next();
  106. if (this.match(_types.types.braceL)) {
  107. // export type { foo, bar };
  108. node.specifiers = this.parseExportSpecifiers();
  109. this.parseExportFrom(node);
  110. return null;
  111. } else {
  112. // export type Foo = Bar;
  113. return this.flowParseTypeAlias(declarationNode);
  114. }
  115. } else if (this.isContextual("interface")) {
  116. node.exportKind = "type";
  117. var _declarationNode = this.startNode();
  118. this.next();
  119. return this.flowParseInterface(_declarationNode);
  120. } else {
  121. return inner.call(this, node);
  122. }
  123. };
  124. });
  125. instance.extend("parseClassId", function (inner) {
  126. return function (node) {
  127. inner.apply(this, arguments);
  128. if (this.isRelational("<")) {
  129. node.typeParameters = this.flowParseTypeParameterDeclaration();
  130. }
  131. };
  132. });
  133. // don't consider `void` to be a keyword as then it'll use the void token type
  134. // and set startExpr
  135. instance.extend("isKeyword", function (inner) {
  136. return function (name) {
  137. if (this.state.inType && name === "void") {
  138. return false;
  139. } else {
  140. return inner.call(this, name);
  141. }
  142. };
  143. });
  144. // ensure that inside flow types, we bypass the jsx parser plugin
  145. instance.extend("readToken", function (inner) {
  146. return function (code) {
  147. if (this.state.inType && (code === 62 || code === 60)) {
  148. return this.finishOp(_types.types.relational, 1);
  149. } else {
  150. return inner.call(this, code);
  151. }
  152. };
  153. });
  154. // don't lex any token as a jsx one inside a flow type
  155. instance.extend("jsx_readToken", function (inner) {
  156. return function () {
  157. if (!this.state.inType) return inner.call(this);
  158. };
  159. });
  160. instance.extend("toAssignable", function (inner) {
  161. return function (node, isBinding) {
  162. if (node.type === "TypeCastExpression") {
  163. return inner.call(this, this.typeCastToParameter(node), isBinding);
  164. } else {
  165. return inner.call(this, node, isBinding);
  166. }
  167. };
  168. });
  169. // turn type casts that we found in function parameter head into type annotated params
  170. instance.extend("toAssignableList", function (inner) {
  171. return function (exprList, isBinding) {
  172. for (var i = 0; i < exprList.length; i++) {
  173. var expr = exprList[i];
  174. if (expr && expr.type === "TypeCastExpression") {
  175. exprList[i] = this.typeCastToParameter(expr);
  176. }
  177. }
  178. return inner.call(this, exprList, isBinding);
  179. };
  180. });
  181. // this is a list of nodes, from something like a call expression, we need to filter the
  182. // type casts that we've found that are illegal in this context
  183. instance.extend("toReferencedList", function () {
  184. return function (exprList) {
  185. for (var i = 0; i < exprList.length; i++) {
  186. var expr = exprList[i];
  187. if (expr && expr._exprListItem && expr.type === "TypeCastExpression") {
  188. this.raise(expr.start, "Unexpected type cast");
  189. }
  190. }
  191. return exprList;
  192. };
  193. });
  194. // parse an item inside a expression list eg. `(NODE, NODE)` where NODE represents
  195. // the position where this function is called
  196. instance.extend("parseExprListItem", function (inner) {
  197. return function (allowEmpty, refShorthandDefaultPos) {
  198. var container = this.startNode();
  199. var node = inner.call(this, allowEmpty, refShorthandDefaultPos);
  200. if (this.match(_types.types.colon)) {
  201. container._exprListItem = true;
  202. container.expression = node;
  203. container.typeAnnotation = this.flowParseTypeAnnotation();
  204. return this.finishNode(container, "TypeCastExpression");
  205. } else {
  206. return node;
  207. }
  208. };
  209. });
  210. instance.extend("checkLVal", function (inner) {
  211. return function (node) {
  212. if (node.type !== "TypeCastExpression") {
  213. return inner.apply(this, arguments);
  214. }
  215. };
  216. });
  217. // parse class property type annotations
  218. instance.extend("parseClassProperty", function (inner) {
  219. return function (node) {
  220. if (this.match(_types.types.colon)) {
  221. node.typeAnnotation = this.flowParseTypeAnnotation();
  222. }
  223. return inner.call(this, node);
  224. };
  225. });
  226. // determine whether or not we're currently in the position where a class property would appear
  227. instance.extend("isClassProperty", function (inner) {
  228. return function () {
  229. return this.match(_types.types.colon) || inner.call(this);
  230. };
  231. });
  232. // parse type parameters for class methods
  233. instance.extend("parseClassMethod", function () {
  234. return function (classBody, method, isGenerator, isAsync) {
  235. if (this.isRelational("<")) {
  236. method.typeParameters = this.flowParseTypeParameterDeclaration();
  237. }
  238. this.parseMethod(method, isGenerator, isAsync);
  239. classBody.body.push(this.finishNode(method, "ClassMethod"));
  240. };
  241. });
  242. // parse a the super class type parameters and implements
  243. instance.extend("parseClassSuper", function (inner) {
  244. return function (node, isStatement) {
  245. inner.call(this, node, isStatement);
  246. if (node.superClass && this.isRelational("<")) {
  247. node.superTypeParameters = this.flowParseTypeParameterInstantiation();
  248. }
  249. if (this.isContextual("implements")) {
  250. this.next();
  251. var implemented = node.implements = [];
  252. do {
  253. var _node = this.startNode();
  254. _node.id = this.parseIdentifier();
  255. if (this.isRelational("<")) {
  256. _node.typeParameters = this.flowParseTypeParameterInstantiation();
  257. } else {
  258. _node.typeParameters = null;
  259. }
  260. implemented.push(this.finishNode(_node, "ClassImplements"));
  261. } while (this.eat(_types.types.comma));
  262. }
  263. };
  264. });
  265. // parse type parameters for object method shorthand
  266. instance.extend("parseObjPropValue", function (inner) {
  267. return function (prop) {
  268. var typeParameters = void 0;
  269. // method shorthand
  270. if (this.isRelational("<")) {
  271. typeParameters = this.flowParseTypeParameterDeclaration();
  272. if (!this.match(_types.types.parenL)) this.unexpected();
  273. }
  274. inner.apply(this, arguments);
  275. // add typeParameters if we found them
  276. if (typeParameters) {
  277. (prop.value || prop).typeParameters = typeParameters;
  278. }
  279. };
  280. });
  281. instance.extend("parseAssignableListItemTypes", function () {
  282. return function (param) {
  283. if (this.eat(_types.types.question)) {
  284. param.optional = true;
  285. }
  286. if (this.match(_types.types.colon)) {
  287. param.typeAnnotation = this.flowParseTypeAnnotation();
  288. }
  289. this.finishNode(param, param.type);
  290. return param;
  291. };
  292. });
  293. // parse typeof and type imports
  294. instance.extend("parseImportSpecifiers", function (inner) {
  295. return function (node) {
  296. node.importKind = "value";
  297. var kind = null;
  298. if (this.match(_types.types._typeof)) {
  299. kind = "typeof";
  300. } else if (this.isContextual("type")) {
  301. kind = "type";
  302. }
  303. if (kind) {
  304. var lh = this.lookahead();
  305. if (lh.type === _types.types.name && lh.value !== "from" || lh.type === _types.types.braceL || lh.type === _types.types.star) {
  306. this.next();
  307. node.importKind = kind;
  308. }
  309. }
  310. inner.call(this, node);
  311. };
  312. });
  313. // parse function type parameters - function foo<T>() {}
  314. instance.extend("parseFunctionParams", function (inner) {
  315. return function (node) {
  316. if (this.isRelational("<")) {
  317. node.typeParameters = this.flowParseTypeParameterDeclaration();
  318. }
  319. inner.call(this, node);
  320. };
  321. });
  322. // parse flow type annotations on variable declarator heads - let foo: string = bar
  323. instance.extend("parseVarHead", function (inner) {
  324. return function (decl) {
  325. inner.call(this, decl);
  326. if (this.match(_types.types.colon)) {
  327. decl.id.typeAnnotation = this.flowParseTypeAnnotation();
  328. this.finishNode(decl.id, decl.id.type);
  329. }
  330. };
  331. });
  332. // parse the return type of an async arrow function - let foo = (async (): number => {});
  333. instance.extend("parseAsyncArrowFromCallExpression", function (inner) {
  334. return function (node, call) {
  335. if (this.match(_types.types.colon)) {
  336. node.returnType = this.flowParseTypeAnnotation();
  337. }
  338. return inner.call(this, node, call);
  339. };
  340. });
  341. // todo description
  342. instance.extend("shouldParseAsyncArrow", function (inner) {
  343. return function () {
  344. return this.match(_types.types.colon) || inner.call(this);
  345. };
  346. });
  347. // We need to support type parameter declarations for arrow functions. This
  348. // is tricky. There are three situations we need to handle
  349. //
  350. // 1. This is either JSX or an arrow function. We'll try JSX first. If that
  351. // fails, we'll try an arrow function. If that fails, we'll throw the JSX
  352. // error.
  353. // 2. This is an arrow function. We'll parse the type parameter declaration,
  354. // parse the rest, make sure the rest is an arrow function, and go from
  355. // there
  356. // 3. This is neither. Just call the inner function
  357. instance.extend("parseMaybeAssign", function (inner) {
  358. return function () {
  359. var jsxError = null;
  360. for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
  361. args[_key] = arguments[_key];
  362. }
  363. if (_types.types.jsxTagStart && this.match(_types.types.jsxTagStart)) {
  364. var state = this.state.clone();
  365. try {
  366. return inner.apply(this, args);
  367. } catch (err) {
  368. if (err instanceof SyntaxError) {
  369. this.state = state;
  370. jsxError = err;
  371. } else {
  372. throw err;
  373. }
  374. }
  375. }
  376. // Need to push something onto the context to stop
  377. // the JSX plugin from messing with the tokens
  378. this.state.context.push(_context.types.parenExpression);
  379. if (jsxError != null || this.isRelational("<")) {
  380. var arrowExpression = void 0;
  381. var typeParameters = void 0;
  382. try {
  383. typeParameters = this.flowParseTypeParameterDeclaration();
  384. arrowExpression = inner.apply(this, args);
  385. arrowExpression.typeParameters = typeParameters;
  386. } catch (err) {
  387. throw jsxError || err;
  388. }
  389. if (arrowExpression.type === "ArrowFunctionExpression") {
  390. return arrowExpression;
  391. } else if (jsxError != null) {
  392. throw jsxError;
  393. } else {
  394. this.raise(typeParameters.start, "Expected an arrow function after this type parameter declaration");
  395. }
  396. }
  397. this.state.context.pop();
  398. return inner.apply(this, args);
  399. };
  400. });
  401. // handle return types for arrow functions
  402. instance.extend("parseArrow", function (inner) {
  403. return function (node) {
  404. if (this.match(_types.types.colon)) {
  405. var state = this.state.clone();
  406. try {
  407. var returnType = this.flowParseTypeAnnotation();
  408. if (!this.match(_types.types.arrow)) this.unexpected();
  409. // assign after it is clear it is an arrow
  410. node.returnType = returnType;
  411. } catch (err) {
  412. if (err instanceof SyntaxError) {
  413. this.state = state;
  414. } else {
  415. throw err;
  416. }
  417. }
  418. }
  419. return inner.call(this, node);
  420. };
  421. });
  422. instance.extend("isClassMutatorStarter", function (inner) {
  423. return function () {
  424. if (this.isRelational("<")) {
  425. return true;
  426. } else {
  427. return inner.call(this);
  428. }
  429. };
  430. });
  431. };
  432. var _types = require("../tokenizer/types");
  433. var _context = require("../tokenizer/context");
  434. var _parser = require("../parser");
  435. var _parser2 = _interopRequireDefault(_parser);
  436. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  437. var pp = _parser2.default.prototype; /* eslint indent: 0 */
  438. /* eslint max-len: 0 */
  439. pp.flowParseTypeInitialiser = function (tok, allowLeadingPipeOrAnd) {
  440. var oldInType = this.state.inType;
  441. this.state.inType = true;
  442. this.expect(tok || _types.types.colon);
  443. if (allowLeadingPipeOrAnd) {
  444. if (this.match(_types.types.bitwiseAND) || this.match(_types.types.bitwiseOR)) {
  445. this.next();
  446. }
  447. }
  448. var type = this.flowParseType();
  449. this.state.inType = oldInType;
  450. return type;
  451. };
  452. pp.flowParseDeclareClass = function (node) {
  453. this.next();
  454. this.flowParseInterfaceish(node, true);
  455. return this.finishNode(node, "DeclareClass");
  456. };
  457. pp.flowParseDeclareFunction = function (node) {
  458. this.next();
  459. var id = node.id = this.parseIdentifier();
  460. var typeNode = this.startNode();
  461. var typeContainer = this.startNode();
  462. if (this.isRelational("<")) {
  463. typeNode.typeParameters = this.flowParseTypeParameterDeclaration();
  464. } else {
  465. typeNode.typeParameters = null;
  466. }
  467. this.expect(_types.types.parenL);
  468. var tmp = this.flowParseFunctionTypeParams();
  469. typeNode.params = tmp.params;
  470. typeNode.rest = tmp.rest;
  471. this.expect(_types.types.parenR);
  472. typeNode.returnType = this.flowParseTypeInitialiser();
  473. typeContainer.typeAnnotation = this.finishNode(typeNode, "FunctionTypeAnnotation");
  474. id.typeAnnotation = this.finishNode(typeContainer, "TypeAnnotation");
  475. this.finishNode(id, id.type);
  476. this.semicolon();
  477. return this.finishNode(node, "DeclareFunction");
  478. };
  479. pp.flowParseDeclare = function (node) {
  480. if (this.match(_types.types._class)) {
  481. return this.flowParseDeclareClass(node);
  482. } else if (this.match(_types.types._function)) {
  483. return this.flowParseDeclareFunction(node);
  484. } else if (this.match(_types.types._var)) {
  485. return this.flowParseDeclareVariable(node);
  486. } else if (this.isContextual("module")) {
  487. if (this.lookahead().type === _types.types.dot) {
  488. return this.flowParseDeclareModuleExports(node);
  489. } else {
  490. return this.flowParseDeclareModule(node);
  491. }
  492. } else if (this.isContextual("type")) {
  493. return this.flowParseDeclareTypeAlias(node);
  494. } else if (this.isContextual("interface")) {
  495. return this.flowParseDeclareInterface(node);
  496. } else {
  497. this.unexpected();
  498. }
  499. };
  500. pp.flowParseDeclareVariable = function (node) {
  501. this.next();
  502. node.id = this.flowParseTypeAnnotatableIdentifier();
  503. this.semicolon();
  504. return this.finishNode(node, "DeclareVariable");
  505. };
  506. pp.flowParseDeclareModule = function (node) {
  507. this.next();
  508. if (this.match(_types.types.string)) {
  509. node.id = this.parseExprAtom();
  510. } else {
  511. node.id = this.parseIdentifier();
  512. }
  513. var bodyNode = node.body = this.startNode();
  514. var body = bodyNode.body = [];
  515. this.expect(_types.types.braceL);
  516. while (!this.match(_types.types.braceR)) {
  517. var node2 = this.startNode();
  518. this.expectContextual("declare", "Unexpected token. Only declares are allowed inside declare module");
  519. body.push(this.flowParseDeclare(node2));
  520. }
  521. this.expect(_types.types.braceR);
  522. this.finishNode(bodyNode, "BlockStatement");
  523. return this.finishNode(node, "DeclareModule");
  524. };
  525. pp.flowParseDeclareModuleExports = function (node) {
  526. this.expectContextual("module");
  527. this.expect(_types.types.dot);
  528. this.expectContextual("exports");
  529. node.typeAnnotation = this.flowParseTypeAnnotation();
  530. return this.finishNode(node, "DeclareModuleExports");
  531. };
  532. pp.flowParseDeclareTypeAlias = function (node) {
  533. this.next();
  534. this.flowParseTypeAlias(node);
  535. return this.finishNode(node, "DeclareTypeAlias");
  536. };
  537. pp.flowParseDeclareInterface = function (node) {
  538. this.next();
  539. this.flowParseInterfaceish(node);
  540. return this.finishNode(node, "DeclareInterface");
  541. };
  542. // Interfaces
  543. pp.flowParseInterfaceish = function (node, allowStatic) {
  544. node.id = this.parseIdentifier();
  545. if (this.isRelational("<")) {
  546. node.typeParameters = this.flowParseTypeParameterDeclaration();
  547. } else {
  548. node.typeParameters = null;
  549. }
  550. node.extends = [];
  551. node.mixins = [];
  552. if (this.eat(_types.types._extends)) {
  553. do {
  554. node.extends.push(this.flowParseInterfaceExtends());
  555. } while (this.eat(_types.types.comma));
  556. }
  557. if (this.isContextual("mixins")) {
  558. this.next();
  559. do {
  560. node.mixins.push(this.flowParseInterfaceExtends());
  561. } while (this.eat(_types.types.comma));
  562. }
  563. node.body = this.flowParseObjectType(allowStatic);
  564. };
  565. pp.flowParseInterfaceExtends = function () {
  566. var node = this.startNode();
  567. node.id = this.flowParseQualifiedTypeIdentifier();
  568. if (this.isRelational("<")) {
  569. node.typeParameters = this.flowParseTypeParameterInstantiation();
  570. } else {
  571. node.typeParameters = null;
  572. }
  573. return this.finishNode(node, "InterfaceExtends");
  574. };
  575. pp.flowParseInterface = function (node) {
  576. this.flowParseInterfaceish(node, false);
  577. return this.finishNode(node, "InterfaceDeclaration");
  578. };
  579. // Type aliases
  580. pp.flowParseTypeAlias = function (node) {
  581. node.id = this.parseIdentifier();
  582. if (this.isRelational("<")) {
  583. node.typeParameters = this.flowParseTypeParameterDeclaration();
  584. } else {
  585. node.typeParameters = null;
  586. }
  587. node.right = this.flowParseTypeInitialiser(_types.types.eq,
  588. /*allowLeadingPipeOrAnd*/true);
  589. this.semicolon();
  590. return this.finishNode(node, "TypeAlias");
  591. };
  592. // Type annotations
  593. pp.flowParseTypeParameter = function () {
  594. var node = this.startNode();
  595. var variance = void 0;
  596. if (this.match(_types.types.plusMin)) {
  597. if (this.state.value === "+") {
  598. variance = "plus";
  599. } else if (this.state.value === "-") {
  600. variance = "minus";
  601. }
  602. this.eat(_types.types.plusMin);
  603. }
  604. var ident = this.flowParseTypeAnnotatableIdentifier(false, false);
  605. node.name = ident.name;
  606. node.variance = variance;
  607. node.bound = ident.typeAnnotation;
  608. if (this.match(_types.types.eq)) {
  609. this.eat(_types.types.eq);
  610. node.default = this.flowParseType();
  611. }
  612. return this.finishNode(node, "TypeParameter");
  613. };
  614. pp.flowParseTypeParameterDeclaration = function () {
  615. var oldInType = this.state.inType;
  616. var node = this.startNode();
  617. node.params = [];
  618. this.state.inType = true;
  619. if (this.isRelational("<") || this.match(_types.types.jsxTagStart)) {
  620. this.next();
  621. } else {
  622. this.unexpected();
  623. }
  624. do {
  625. node.params.push(this.flowParseTypeParameter());
  626. if (!this.isRelational(">")) {
  627. this.expect(_types.types.comma);
  628. }
  629. } while (!this.isRelational(">"));
  630. this.expectRelational(">");
  631. this.state.inType = oldInType;
  632. return this.finishNode(node, "TypeParameterDeclaration");
  633. };
  634. pp.flowParseTypeParameterInstantiation = function () {
  635. var node = this.startNode(),
  636. oldInType = this.state.inType;
  637. node.params = [];
  638. this.state.inType = true;
  639. this.expectRelational("<");
  640. while (!this.isRelational(">")) {
  641. node.params.push(this.flowParseType());
  642. if (!this.isRelational(">")) {
  643. this.expect(_types.types.comma);
  644. }
  645. }
  646. this.expectRelational(">");
  647. this.state.inType = oldInType;
  648. return this.finishNode(node, "TypeParameterInstantiation");
  649. };
  650. pp.flowParseObjectPropertyKey = function () {
  651. return this.match(_types.types.num) || this.match(_types.types.string) ? this.parseExprAtom() : this.parseIdentifier(true);
  652. };
  653. pp.flowParseObjectTypeIndexer = function (node, isStatic) {
  654. node.static = isStatic;
  655. this.expect(_types.types.bracketL);
  656. node.id = this.flowParseObjectPropertyKey();
  657. node.key = this.flowParseTypeInitialiser();
  658. this.expect(_types.types.bracketR);
  659. node.value = this.flowParseTypeInitialiser();
  660. this.flowObjectTypeSemicolon();
  661. return this.finishNode(node, "ObjectTypeIndexer");
  662. };
  663. pp.flowParseObjectTypeMethodish = function (node) {
  664. node.params = [];
  665. node.rest = null;
  666. node.typeParameters = null;
  667. if (this.isRelational("<")) {
  668. node.typeParameters = this.flowParseTypeParameterDeclaration();
  669. }
  670. this.expect(_types.types.parenL);
  671. while (this.match(_types.types.name)) {
  672. node.params.push(this.flowParseFunctionTypeParam());
  673. if (!this.match(_types.types.parenR)) {
  674. this.expect(_types.types.comma);
  675. }
  676. }
  677. if (this.eat(_types.types.ellipsis)) {
  678. node.rest = this.flowParseFunctionTypeParam();
  679. }
  680. this.expect(_types.types.parenR);
  681. node.returnType = this.flowParseTypeInitialiser();
  682. return this.finishNode(node, "FunctionTypeAnnotation");
  683. };
  684. pp.flowParseObjectTypeMethod = function (startPos, startLoc, isStatic, key) {
  685. var node = this.startNodeAt(startPos, startLoc);
  686. node.value = this.flowParseObjectTypeMethodish(this.startNodeAt(startPos, startLoc));
  687. node.static = isStatic;
  688. node.key = key;
  689. node.optional = false;
  690. this.flowObjectTypeSemicolon();
  691. return this.finishNode(node, "ObjectTypeProperty");
  692. };
  693. pp.flowParseObjectTypeCallProperty = function (node, isStatic) {
  694. var valueNode = this.startNode();
  695. node.static = isStatic;
  696. node.value = this.flowParseObjectTypeMethodish(valueNode);
  697. this.flowObjectTypeSemicolon();
  698. return this.finishNode(node, "ObjectTypeCallProperty");
  699. };
  700. pp.flowParseObjectType = function (allowStatic) {
  701. var nodeStart = this.startNode();
  702. var node = void 0;
  703. var propertyKey = void 0;
  704. var isStatic = void 0;
  705. nodeStart.callProperties = [];
  706. nodeStart.properties = [];
  707. nodeStart.indexers = [];
  708. this.expect(_types.types.braceL);
  709. while (!this.match(_types.types.braceR)) {
  710. var optional = false;
  711. var startPos = this.state.start,
  712. startLoc = this.state.startLoc;
  713. node = this.startNode();
  714. if (allowStatic && this.isContextual("static")) {
  715. this.next();
  716. isStatic = true;
  717. }
  718. if (this.match(_types.types.bracketL)) {
  719. nodeStart.indexers.push(this.flowParseObjectTypeIndexer(node, isStatic));
  720. } else if (this.match(_types.types.parenL) || this.isRelational("<")) {
  721. nodeStart.callProperties.push(this.flowParseObjectTypeCallProperty(node, allowStatic));
  722. } else {
  723. if (isStatic && this.match(_types.types.colon)) {
  724. propertyKey = this.parseIdentifier();
  725. } else {
  726. propertyKey = this.flowParseObjectPropertyKey();
  727. }
  728. if (this.isRelational("<") || this.match(_types.types.parenL)) {
  729. // This is a method property
  730. nodeStart.properties.push(this.flowParseObjectTypeMethod(startPos, startLoc, isStatic, propertyKey));
  731. } else {
  732. if (this.eat(_types.types.question)) {
  733. optional = true;
  734. }
  735. node.key = propertyKey;
  736. node.value = this.flowParseTypeInitialiser();
  737. node.optional = optional;
  738. node.static = isStatic;
  739. this.flowObjectTypeSemicolon();
  740. nodeStart.properties.push(this.finishNode(node, "ObjectTypeProperty"));
  741. }
  742. }
  743. }
  744. this.expect(_types.types.braceR);
  745. return this.finishNode(nodeStart, "ObjectTypeAnnotation");
  746. };
  747. pp.flowObjectTypeSemicolon = function () {
  748. if (!this.eat(_types.types.semi) && !this.eat(_types.types.comma) && !this.match(_types.types.braceR)) {
  749. this.unexpected();
  750. }
  751. };
  752. pp.flowParseQualifiedTypeIdentifier = function (startPos, startLoc, id) {
  753. startPos = startPos || this.state.start;
  754. startLoc = startLoc || this.state.startLoc;
  755. var node = id || this.parseIdentifier();
  756. while (this.eat(_types.types.dot)) {
  757. var node2 = this.startNodeAt(startPos, startLoc);
  758. node2.qualification = node;
  759. node2.id = this.parseIdentifier();
  760. node = this.finishNode(node2, "QualifiedTypeIdentifier");
  761. }
  762. return node;
  763. };
  764. pp.flowParseGenericType = function (startPos, startLoc, id) {
  765. var node = this.startNodeAt(startPos, startLoc);
  766. node.typeParameters = null;
  767. node.id = this.flowParseQualifiedTypeIdentifier(startPos, startLoc, id);
  768. if (this.isRelational("<")) {
  769. node.typeParameters = this.flowParseTypeParameterInstantiation();
  770. }
  771. return this.finishNode(node, "GenericTypeAnnotation");
  772. };
  773. pp.flowParseTypeofType = function () {
  774. var node = this.startNode();
  775. this.expect(_types.types._typeof);
  776. node.argument = this.flowParsePrimaryType();
  777. return this.finishNode(node, "TypeofTypeAnnotation");
  778. };
  779. pp.flowParseTupleType = function () {
  780. var node = this.startNode();
  781. node.types = [];
  782. this.expect(_types.types.bracketL);
  783. // We allow trailing commas
  784. while (this.state.pos < this.input.length && !this.match(_types.types.bracketR)) {
  785. node.types.push(this.flowParseType());
  786. if (this.match(_types.types.bracketR)) break;
  787. this.expect(_types.types.comma);
  788. }
  789. this.expect(_types.types.bracketR);
  790. return this.finishNode(node, "TupleTypeAnnotation");
  791. };
  792. pp.flowParseFunctionTypeParam = function () {
  793. var optional = false;
  794. var node = this.startNode();
  795. node.name = this.parseIdentifier();
  796. if (this.eat(_types.types.question)) {
  797. optional = true;
  798. }
  799. node.optional = optional;
  800. node.typeAnnotation = this.flowParseTypeInitialiser();
  801. return this.finishNode(node, "FunctionTypeParam");
  802. };
  803. pp.flowParseFunctionTypeParams = function () {
  804. var ret = { params: [], rest: null };
  805. while (this.match(_types.types.name)) {
  806. ret.params.push(this.flowParseFunctionTypeParam());
  807. if (!this.match(_types.types.parenR)) {
  808. this.expect(_types.types.comma);
  809. }
  810. }
  811. if (this.eat(_types.types.ellipsis)) {
  812. ret.rest = this.flowParseFunctionTypeParam();
  813. }
  814. return ret;
  815. };
  816. pp.flowIdentToTypeAnnotation = function (startPos, startLoc, node, id) {
  817. switch (id.name) {
  818. case "any":
  819. return this.finishNode(node, "AnyTypeAnnotation");
  820. case "void":
  821. return this.finishNode(node, "VoidTypeAnnotation");
  822. case "bool":
  823. case "boolean":
  824. return this.finishNode(node, "BooleanTypeAnnotation");
  825. case "mixed":
  826. return this.finishNode(node, "MixedTypeAnnotation");
  827. case "number":
  828. return this.finishNode(node, "NumberTypeAnnotation");
  829. case "string":
  830. return this.finishNode(node, "StringTypeAnnotation");
  831. default:
  832. return this.flowParseGenericType(startPos, startLoc, id);
  833. }
  834. };
  835. // The parsing of types roughly parallels the parsing of expressions, and
  836. // primary types are kind of like primary expressions...they're the
  837. // primitives with which other types are constructed.
  838. pp.flowParsePrimaryType = function () {
  839. var startPos = this.state.start,
  840. startLoc = this.state.startLoc;
  841. var node = this.startNode();
  842. var tmp = void 0;
  843. var type = void 0;
  844. var isGroupedType = false;
  845. switch (this.state.type) {
  846. case _types.types.name:
  847. return this.flowIdentToTypeAnnotation(startPos, startLoc, node, this.parseIdentifier());
  848. case _types.types.braceL:
  849. return this.flowParseObjectType();
  850. case _types.types.bracketL:
  851. return this.flowParseTupleType();
  852. case _types.types.relational:
  853. if (this.state.value === "<") {
  854. node.typeParameters = this.flowParseTypeParameterDeclaration();
  855. this.expect(_types.types.parenL);
  856. tmp = this.flowParseFunctionTypeParams();
  857. node.params = tmp.params;
  858. node.rest = tmp.rest;
  859. this.expect(_types.types.parenR);
  860. this.expect(_types.types.arrow);
  861. node.returnType = this.flowParseType();
  862. return this.finishNode(node, "FunctionTypeAnnotation");
  863. }
  864. break;
  865. case _types.types.parenL:
  866. this.next();
  867. // Check to see if this is actually a grouped type
  868. if (!this.match(_types.types.parenR) && !this.match(_types.types.ellipsis)) {
  869. if (this.match(_types.types.name)) {
  870. var token = this.lookahead().type;
  871. isGroupedType = token !== _types.types.question && token !== _types.types.colon;
  872. } else {
  873. isGroupedType = true;
  874. }
  875. }
  876. if (isGroupedType) {
  877. type = this.flowParseType();
  878. this.expect(_types.types.parenR);
  879. return type;
  880. }
  881. tmp = this.flowParseFunctionTypeParams();
  882. node.params = tmp.params;
  883. node.rest = tmp.rest;
  884. this.expect(_types.types.parenR);
  885. this.expect(_types.types.arrow);
  886. node.returnType = this.flowParseType();
  887. node.typeParameters = null;
  888. return this.finishNode(node, "FunctionTypeAnnotation");
  889. case _types.types.string:
  890. node.value = this.state.value;
  891. this.addExtra(node, "rawValue", node.value);
  892. this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end));
  893. this.next();
  894. return this.finishNode(node, "StringLiteralTypeAnnotation");
  895. case _types.types._true:case _types.types._false:
  896. node.value = this.match(_types.types._true);
  897. this.next();
  898. return this.finishNode(node, "BooleanLiteralTypeAnnotation");
  899. case _types.types.plusMin:
  900. if (this.state.value === "-") {
  901. this.next();
  902. if (!this.match(_types.types.num)) this.unexpected();
  903. node.value = -this.state.value;
  904. this.addExtra(node, "rawValue", node.value);
  905. this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end));
  906. this.next();
  907. return this.finishNode(node, "NumericLiteralTypeAnnotation");
  908. }
  909. case _types.types.num:
  910. node.value = this.state.value;
  911. this.addExtra(node, "rawValue", node.value);
  912. this.addExtra(node, "raw", this.input.slice(this.state.start, this.state.end));
  913. this.next();
  914. return this.finishNode(node, "NumericLiteralTypeAnnotation");
  915. case _types.types._null:
  916. node.value = this.match(_types.types._null);
  917. this.next();
  918. return this.finishNode(node, "NullLiteralTypeAnnotation");
  919. case _types.types._this:
  920. node.value = this.match(_types.types._this);
  921. this.next();
  922. return this.finishNode(node, "ThisTypeAnnotation");
  923. case _types.types.star:
  924. this.next();
  925. return this.finishNode(node, "ExistentialTypeParam");
  926. default:
  927. if (this.state.type.keyword === "typeof") {
  928. return this.flowParseTypeofType();
  929. }
  930. }
  931. this.unexpected();
  932. };
  933. pp.flowParsePostfixType = function () {
  934. var node = this.startNode();
  935. var type = node.elementType = this.flowParsePrimaryType();
  936. if (this.match(_types.types.bracketL)) {
  937. this.expect(_types.types.bracketL);
  938. this.expect(_types.types.bracketR);
  939. return this.finishNode(node, "ArrayTypeAnnotation");
  940. } else {
  941. return type;
  942. }
  943. };
  944. pp.flowParsePrefixType = function () {
  945. var node = this.startNode();
  946. if (this.eat(_types.types.question)) {
  947. node.typeAnnotation = this.flowParsePrefixType();
  948. return this.finishNode(node, "NullableTypeAnnotation");
  949. } else {
  950. return this.flowParsePostfixType();
  951. }
  952. };
  953. pp.flowParseIntersectionType = function () {
  954. var node = this.startNode();
  955. var type = this.flowParsePrefixType();
  956. node.types = [type];
  957. while (this.eat(_types.types.bitwiseAND)) {
  958. node.types.push(this.flowParsePrefixType());
  959. }
  960. return node.types.length === 1 ? type : this.finishNode(node, "IntersectionTypeAnnotation");
  961. };
  962. pp.flowParseUnionType = function () {
  963. var node = this.startNode();
  964. var type = this.flowParseIntersectionType();
  965. node.types = [type];
  966. while (this.eat(_types.types.bitwiseOR)) {
  967. node.types.push(this.flowParseIntersectionType());
  968. }
  969. return node.types.length === 1 ? type : this.finishNode(node, "UnionTypeAnnotation");
  970. };
  971. pp.flowParseType = function () {
  972. var oldInType = this.state.inType;
  973. this.state.inType = true;
  974. var type = this.flowParseUnionType();
  975. this.state.inType = oldInType;
  976. return type;
  977. };
  978. pp.flowParseTypeAnnotation = function () {
  979. var node = this.startNode();
  980. node.typeAnnotation = this.flowParseTypeInitialiser();
  981. return this.finishNode(node, "TypeAnnotation");
  982. };
  983. pp.flowParseTypeAnnotatableIdentifier = function (requireTypeAnnotation, canBeOptionalParam) {
  984. var ident = this.parseIdentifier();
  985. var isOptionalParam = false;
  986. if (canBeOptionalParam && this.eat(_types.types.question)) {
  987. this.expect(_types.types.question);
  988. isOptionalParam = true;
  989. }
  990. if (requireTypeAnnotation || this.match(_types.types.colon)) {
  991. ident.typeAnnotation = this.flowParseTypeAnnotation();
  992. this.finishNode(ident, ident.type);
  993. }
  994. if (isOptionalParam) {
  995. ident.optional = true;
  996. this.finishNode(ident, ident.type);
  997. }
  998. return ident;
  999. };
  1000. pp.typeCastToParameter = function (node) {
  1001. node.expression.typeAnnotation = node.typeAnnotation;
  1002. return this.finishNodeAt(node.expression, node.expression.type, node.typeAnnotation.end, node.typeAnnotation.loc.end);
  1003. };