ast.ts 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. import { isString } from '@vue/shared'
  2. import { ForParseResult } from './transforms/vFor'
  3. import {
  4. RENDER_SLOT,
  5. CREATE_SLOTS,
  6. RENDER_LIST,
  7. OPEN_BLOCK,
  8. CREATE_BLOCK,
  9. FRAGMENT,
  10. CREATE_VNODE,
  11. WITH_DIRECTIVES
  12. } from './runtimeHelpers'
  13. import { PropsExpression } from './transforms/transformElement'
  14. import { ImportItem, TransformContext } from './transform'
  15. // Vue template is a platform-agnostic superset of HTML (syntax only).
  16. // More namespaces like SVG and MathML are declared by platform specific
  17. // compilers.
  18. export type Namespace = number
  19. export const enum Namespaces {
  20. HTML
  21. }
  22. export const enum NodeTypes {
  23. ROOT,
  24. ELEMENT,
  25. TEXT,
  26. COMMENT,
  27. SIMPLE_EXPRESSION,
  28. INTERPOLATION,
  29. ATTRIBUTE,
  30. DIRECTIVE,
  31. // containers
  32. COMPOUND_EXPRESSION,
  33. IF,
  34. IF_BRANCH,
  35. FOR,
  36. TEXT_CALL,
  37. // codegen
  38. VNODE_CALL,
  39. JS_CALL_EXPRESSION,
  40. JS_OBJECT_EXPRESSION,
  41. JS_PROPERTY,
  42. JS_ARRAY_EXPRESSION,
  43. JS_FUNCTION_EXPRESSION,
  44. JS_CONDITIONAL_EXPRESSION,
  45. JS_CACHE_EXPRESSION,
  46. // ssr codegen
  47. JS_BLOCK_STATEMENT,
  48. JS_TEMPLATE_LITERAL,
  49. JS_IF_STATEMENT,
  50. JS_ASSIGNMENT_EXPRESSION,
  51. JS_SEQUENCE_EXPRESSION,
  52. JS_RETURN_STATEMENT
  53. }
  54. export const enum ElementTypes {
  55. ELEMENT,
  56. COMPONENT,
  57. SLOT,
  58. TEMPLATE
  59. }
  60. export interface Node {
  61. type: NodeTypes
  62. loc: SourceLocation
  63. }
  64. // The node's range. The `start` is inclusive and `end` is exclusive.
  65. // [start, end)
  66. export interface SourceLocation {
  67. start: Position
  68. end: Position
  69. source: string
  70. }
  71. export interface Position {
  72. offset: number // from start of file
  73. line: number
  74. column: number
  75. }
  76. export type ParentNode = RootNode | ElementNode | IfBranchNode | ForNode
  77. export type ExpressionNode = SimpleExpressionNode | CompoundExpressionNode
  78. export type TemplateChildNode =
  79. | ElementNode
  80. | InterpolationNode
  81. | CompoundExpressionNode
  82. | TextNode
  83. | CommentNode
  84. | IfNode
  85. | IfBranchNode
  86. | ForNode
  87. | TextCallNode
  88. export interface RootNode extends Node {
  89. type: NodeTypes.ROOT
  90. children: TemplateChildNode[]
  91. helpers: symbol[]
  92. components: string[]
  93. directives: string[]
  94. hoists: JSChildNode[]
  95. imports: ImportItem[]
  96. cached: number
  97. temps: number
  98. ssrHelpers?: symbol[]
  99. codegenNode?: TemplateChildNode | JSChildNode | BlockStatement | undefined
  100. }
  101. export type ElementNode =
  102. | PlainElementNode
  103. | ComponentNode
  104. | SlotOutletNode
  105. | TemplateNode
  106. export interface BaseElementNode extends Node {
  107. type: NodeTypes.ELEMENT
  108. ns: Namespace
  109. tag: string
  110. tagType: ElementTypes
  111. isSelfClosing: boolean
  112. props: Array<AttributeNode | DirectiveNode>
  113. children: TemplateChildNode[]
  114. }
  115. export interface PlainElementNode extends BaseElementNode {
  116. tagType: ElementTypes.ELEMENT
  117. codegenNode:
  118. | VNodeCall
  119. | SimpleExpressionNode // when hoisted
  120. | CacheExpression // when cached by v-once
  121. | undefined
  122. ssrCodegenNode?: TemplateLiteral
  123. }
  124. export interface ComponentNode extends BaseElementNode {
  125. tagType: ElementTypes.COMPONENT
  126. codegenNode:
  127. | VNodeCall
  128. | CacheExpression // when cached by v-once
  129. | undefined
  130. ssrCodegenNode?: CallExpression
  131. }
  132. export interface SlotOutletNode extends BaseElementNode {
  133. tagType: ElementTypes.SLOT
  134. codegenNode:
  135. | RenderSlotCall
  136. | CacheExpression // when cached by v-once
  137. | undefined
  138. ssrCodegenNode?: CallExpression
  139. }
  140. export interface TemplateNode extends BaseElementNode {
  141. tagType: ElementTypes.TEMPLATE
  142. // TemplateNode is a container type that always gets compiled away
  143. codegenNode: undefined
  144. }
  145. export interface TextNode extends Node {
  146. type: NodeTypes.TEXT
  147. content: string
  148. }
  149. export interface CommentNode extends Node {
  150. type: NodeTypes.COMMENT
  151. content: string
  152. }
  153. export interface AttributeNode extends Node {
  154. type: NodeTypes.ATTRIBUTE
  155. name: string
  156. value: TextNode | undefined
  157. }
  158. export interface DirectiveNode extends Node {
  159. type: NodeTypes.DIRECTIVE
  160. name: string
  161. exp: ExpressionNode | undefined
  162. arg: ExpressionNode | undefined
  163. modifiers: string[]
  164. // optional property to cache the expression parse result for v-for
  165. parseResult?: ForParseResult
  166. }
  167. export interface SimpleExpressionNode extends Node {
  168. type: NodeTypes.SIMPLE_EXPRESSION
  169. content: string
  170. isStatic: boolean
  171. isConstant: boolean
  172. // an expression parsed as the params of a function will track
  173. // the identifiers declared inside the function body.
  174. identifiers?: string[]
  175. }
  176. export interface InterpolationNode extends Node {
  177. type: NodeTypes.INTERPOLATION
  178. content: ExpressionNode
  179. }
  180. export interface CompoundExpressionNode extends Node {
  181. type: NodeTypes.COMPOUND_EXPRESSION
  182. children: (
  183. | SimpleExpressionNode
  184. | CompoundExpressionNode
  185. | InterpolationNode
  186. | TextNode
  187. | string
  188. | symbol)[]
  189. // an expression parsed as the params of a function will track
  190. // the identifiers declared inside the function body.
  191. identifiers?: string[]
  192. }
  193. export interface IfNode extends Node {
  194. type: NodeTypes.IF
  195. branches: IfBranchNode[]
  196. codegenNode?: IfConditionalExpression
  197. }
  198. export interface IfBranchNode extends Node {
  199. type: NodeTypes.IF_BRANCH
  200. condition: ExpressionNode | undefined // else
  201. children: TemplateChildNode[]
  202. }
  203. export interface ForNode extends Node {
  204. type: NodeTypes.FOR
  205. source: ExpressionNode
  206. valueAlias: ExpressionNode | undefined
  207. keyAlias: ExpressionNode | undefined
  208. objectIndexAlias: ExpressionNode | undefined
  209. parseResult: ForParseResult
  210. children: TemplateChildNode[]
  211. codegenNode?: ForCodegenNode
  212. }
  213. export interface TextCallNode extends Node {
  214. type: NodeTypes.TEXT_CALL
  215. content: TextNode | InterpolationNode | CompoundExpressionNode
  216. codegenNode: CallExpression | SimpleExpressionNode // when hoisted
  217. }
  218. export type TemplateTextChildNode =
  219. | TextNode
  220. | InterpolationNode
  221. | CompoundExpressionNode
  222. export interface VNodeCall extends Node {
  223. type: NodeTypes.VNODE_CALL
  224. tag: string | symbol | CallExpression
  225. props: PropsExpression | undefined
  226. children:
  227. | TemplateChildNode[] // multiple children
  228. | TemplateTextChildNode // single text child
  229. | SlotsExpression // component slots
  230. | ForRenderListExpression // v-for fragment call
  231. | undefined
  232. patchFlag: string | undefined
  233. dynamicProps: string | undefined
  234. directives: DirectiveArguments | undefined
  235. isBlock: boolean
  236. isForBlock: boolean
  237. }
  238. // JS Node Types ---------------------------------------------------------------
  239. // We also include a number of JavaScript AST nodes for code generation.
  240. // The AST is an intentionally minimal subset just to meet the exact needs of
  241. // Vue render function generation.
  242. export type JSChildNode =
  243. | VNodeCall
  244. | CallExpression
  245. | ObjectExpression
  246. | ArrayExpression
  247. | ExpressionNode
  248. | FunctionExpression
  249. | ConditionalExpression
  250. | CacheExpression
  251. | AssignmentExpression
  252. | SequenceExpression
  253. export interface CallExpression extends Node {
  254. type: NodeTypes.JS_CALL_EXPRESSION
  255. callee: string | symbol
  256. arguments: (
  257. | string
  258. | symbol
  259. | JSChildNode
  260. | SSRCodegenNode
  261. | TemplateChildNode
  262. | TemplateChildNode[])[]
  263. }
  264. export interface ObjectExpression extends Node {
  265. type: NodeTypes.JS_OBJECT_EXPRESSION
  266. properties: Array<Property>
  267. }
  268. export interface Property extends Node {
  269. type: NodeTypes.JS_PROPERTY
  270. key: ExpressionNode
  271. value: JSChildNode
  272. }
  273. export interface ArrayExpression extends Node {
  274. type: NodeTypes.JS_ARRAY_EXPRESSION
  275. elements: Array<string | JSChildNode>
  276. }
  277. export interface FunctionExpression extends Node {
  278. type: NodeTypes.JS_FUNCTION_EXPRESSION
  279. params: ExpressionNode | string | (ExpressionNode | string)[] | undefined
  280. returns?: TemplateChildNode | TemplateChildNode[] | JSChildNode
  281. body?: BlockStatement | IfStatement
  282. newline: boolean
  283. // so that codegen knows it needs to generate ScopeId wrapper
  284. isSlot: boolean
  285. }
  286. export interface ConditionalExpression extends Node {
  287. type: NodeTypes.JS_CONDITIONAL_EXPRESSION
  288. test: JSChildNode
  289. consequent: JSChildNode
  290. alternate: JSChildNode
  291. newline: boolean
  292. }
  293. export interface CacheExpression extends Node {
  294. type: NodeTypes.JS_CACHE_EXPRESSION
  295. index: number
  296. value: JSChildNode
  297. isVNode: boolean
  298. }
  299. // SSR-specific Node Types -----------------------------------------------------
  300. export type SSRCodegenNode =
  301. | BlockStatement
  302. | TemplateLiteral
  303. | IfStatement
  304. | AssignmentExpression
  305. | ReturnStatement
  306. | SequenceExpression
  307. export interface BlockStatement extends Node {
  308. type: NodeTypes.JS_BLOCK_STATEMENT
  309. body: (JSChildNode | IfStatement)[]
  310. }
  311. export interface TemplateLiteral extends Node {
  312. type: NodeTypes.JS_TEMPLATE_LITERAL
  313. elements: (string | JSChildNode)[]
  314. }
  315. export interface IfStatement extends Node {
  316. type: NodeTypes.JS_IF_STATEMENT
  317. test: ExpressionNode
  318. consequent: BlockStatement
  319. alternate: IfStatement | BlockStatement | ReturnStatement | undefined
  320. }
  321. export interface AssignmentExpression extends Node {
  322. type: NodeTypes.JS_ASSIGNMENT_EXPRESSION
  323. left: SimpleExpressionNode
  324. right: JSChildNode
  325. }
  326. export interface SequenceExpression extends Node {
  327. type: NodeTypes.JS_SEQUENCE_EXPRESSION
  328. expressions: JSChildNode[]
  329. }
  330. export interface ReturnStatement extends Node {
  331. type: NodeTypes.JS_RETURN_STATEMENT
  332. returns: TemplateChildNode | TemplateChildNode[] | JSChildNode
  333. }
  334. // Codegen Node Types ----------------------------------------------------------
  335. export interface DirectiveArguments extends ArrayExpression {
  336. elements: DirectiveArgumentNode[]
  337. }
  338. export interface DirectiveArgumentNode extends ArrayExpression {
  339. elements: // dir, exp, arg, modifiers
  340. | [string]
  341. | [string, ExpressionNode]
  342. | [string, ExpressionNode, ExpressionNode]
  343. | [string, ExpressionNode, ExpressionNode, ObjectExpression]
  344. }
  345. // renderSlot(...)
  346. export interface RenderSlotCall extends CallExpression {
  347. callee: typeof RENDER_SLOT
  348. arguments: // $slots, name, props, fallback
  349. | [string, string | ExpressionNode]
  350. | [string, string | ExpressionNode, PropsExpression]
  351. | [
  352. string,
  353. string | ExpressionNode,
  354. PropsExpression | '{}',
  355. TemplateChildNode[]
  356. ]
  357. }
  358. export type SlotsExpression = SlotsObjectExpression | DynamicSlotsExpression
  359. // { foo: () => [...] }
  360. export interface SlotsObjectExpression extends ObjectExpression {
  361. properties: SlotsObjectProperty[]
  362. }
  363. export interface SlotsObjectProperty extends Property {
  364. value: SlotFunctionExpression
  365. }
  366. export interface SlotFunctionExpression extends FunctionExpression {
  367. returns: TemplateChildNode[]
  368. }
  369. // createSlots({ ... }, [
  370. // foo ? () => [] : undefined,
  371. // renderList(list, i => () => [i])
  372. // ])
  373. export interface DynamicSlotsExpression extends CallExpression {
  374. callee: typeof CREATE_SLOTS
  375. arguments: [SlotsObjectExpression, DynamicSlotEntries]
  376. }
  377. export interface DynamicSlotEntries extends ArrayExpression {
  378. elements: (ConditionalDynamicSlotNode | ListDynamicSlotNode)[]
  379. }
  380. export interface ConditionalDynamicSlotNode extends ConditionalExpression {
  381. consequent: DynamicSlotNode
  382. alternate: DynamicSlotNode | SimpleExpressionNode
  383. }
  384. export interface ListDynamicSlotNode extends CallExpression {
  385. callee: typeof RENDER_LIST
  386. arguments: [ExpressionNode, ListDynamicSlotIterator]
  387. }
  388. export interface ListDynamicSlotIterator extends FunctionExpression {
  389. returns: DynamicSlotNode
  390. }
  391. export interface DynamicSlotNode extends ObjectExpression {
  392. properties: [Property, DynamicSlotFnProperty]
  393. }
  394. export interface DynamicSlotFnProperty extends Property {
  395. value: SlotFunctionExpression
  396. }
  397. export type BlockCodegenNode = VNodeCall | RenderSlotCall
  398. export interface IfConditionalExpression extends ConditionalExpression {
  399. consequent: BlockCodegenNode
  400. alternate: BlockCodegenNode | IfConditionalExpression
  401. }
  402. export interface ForCodegenNode extends VNodeCall {
  403. isBlock: true
  404. tag: typeof FRAGMENT
  405. props: undefined
  406. children: ForRenderListExpression
  407. patchFlag: string
  408. isForBlock: true
  409. }
  410. export interface ForRenderListExpression extends CallExpression {
  411. callee: typeof RENDER_LIST
  412. arguments: [ExpressionNode, ForIteratorExpression]
  413. }
  414. export interface ForIteratorExpression extends FunctionExpression {
  415. returns: BlockCodegenNode
  416. }
  417. // AST Utilities ---------------------------------------------------------------
  418. // Some expressions, e.g. sequence and conditional expressions, are never
  419. // associated with template nodes, so their source locations are just a stub.
  420. // Container types like CompoundExpression also don't need a real location.
  421. export const locStub: SourceLocation = {
  422. source: '',
  423. start: { line: 1, column: 1, offset: 0 },
  424. end: { line: 1, column: 1, offset: 0 }
  425. }
  426. export function createRoot(
  427. children: TemplateChildNode[],
  428. loc = locStub
  429. ): RootNode {
  430. return {
  431. type: NodeTypes.ROOT,
  432. children,
  433. helpers: [],
  434. components: [],
  435. directives: [],
  436. hoists: [],
  437. imports: [],
  438. cached: 0,
  439. temps: 0,
  440. codegenNode: undefined,
  441. loc
  442. }
  443. }
  444. export function createVNodeCall(
  445. context: TransformContext | null,
  446. tag: VNodeCall['tag'],
  447. props?: VNodeCall['props'],
  448. children?: VNodeCall['children'],
  449. patchFlag?: VNodeCall['patchFlag'],
  450. dynamicProps?: VNodeCall['dynamicProps'],
  451. directives?: VNodeCall['directives'],
  452. isBlock: VNodeCall['isBlock'] = false,
  453. isForBlock: VNodeCall['isForBlock'] = false,
  454. loc = locStub
  455. ): VNodeCall {
  456. if (context) {
  457. if (isBlock) {
  458. context.helper(OPEN_BLOCK)
  459. context.helper(CREATE_BLOCK)
  460. } else {
  461. context.helper(CREATE_VNODE)
  462. }
  463. if (directives) {
  464. context.helper(WITH_DIRECTIVES)
  465. }
  466. }
  467. return {
  468. type: NodeTypes.VNODE_CALL,
  469. tag,
  470. props,
  471. children,
  472. patchFlag,
  473. dynamicProps,
  474. directives,
  475. isBlock,
  476. isForBlock,
  477. loc
  478. }
  479. }
  480. export function createArrayExpression(
  481. elements: ArrayExpression['elements'],
  482. loc: SourceLocation = locStub
  483. ): ArrayExpression {
  484. return {
  485. type: NodeTypes.JS_ARRAY_EXPRESSION,
  486. loc,
  487. elements
  488. }
  489. }
  490. export function createObjectExpression(
  491. properties: ObjectExpression['properties'],
  492. loc: SourceLocation = locStub
  493. ): ObjectExpression {
  494. return {
  495. type: NodeTypes.JS_OBJECT_EXPRESSION,
  496. loc,
  497. properties
  498. }
  499. }
  500. export function createObjectProperty(
  501. key: Property['key'] | string,
  502. value: Property['value']
  503. ): Property {
  504. return {
  505. type: NodeTypes.JS_PROPERTY,
  506. loc: locStub,
  507. key: isString(key) ? createSimpleExpression(key, true) : key,
  508. value
  509. }
  510. }
  511. export function createSimpleExpression(
  512. content: SimpleExpressionNode['content'],
  513. isStatic: SimpleExpressionNode['isStatic'],
  514. loc: SourceLocation = locStub,
  515. isConstant: boolean = false
  516. ): SimpleExpressionNode {
  517. return {
  518. type: NodeTypes.SIMPLE_EXPRESSION,
  519. loc,
  520. isConstant,
  521. content,
  522. isStatic
  523. }
  524. }
  525. export function createInterpolation(
  526. content: InterpolationNode['content'] | string,
  527. loc: SourceLocation
  528. ): InterpolationNode {
  529. return {
  530. type: NodeTypes.INTERPOLATION,
  531. loc,
  532. content: isString(content)
  533. ? createSimpleExpression(content, false, loc)
  534. : content
  535. }
  536. }
  537. export function createCompoundExpression(
  538. children: CompoundExpressionNode['children'],
  539. loc: SourceLocation = locStub
  540. ): CompoundExpressionNode {
  541. return {
  542. type: NodeTypes.COMPOUND_EXPRESSION,
  543. loc,
  544. children
  545. }
  546. }
  547. type InferCodegenNodeType<T> = T extends typeof RENDER_SLOT
  548. ? RenderSlotCall
  549. : CallExpression
  550. export function createCallExpression<T extends CallExpression['callee']>(
  551. callee: T,
  552. args: CallExpression['arguments'] = [],
  553. loc: SourceLocation = locStub
  554. ): InferCodegenNodeType<T> {
  555. return {
  556. type: NodeTypes.JS_CALL_EXPRESSION,
  557. loc,
  558. callee,
  559. arguments: args
  560. } as any
  561. }
  562. export function createFunctionExpression(
  563. params: FunctionExpression['params'],
  564. returns: FunctionExpression['returns'] = undefined,
  565. newline: boolean = false,
  566. isSlot: boolean = false,
  567. loc: SourceLocation = locStub
  568. ): FunctionExpression {
  569. return {
  570. type: NodeTypes.JS_FUNCTION_EXPRESSION,
  571. params,
  572. returns,
  573. newline,
  574. isSlot,
  575. loc
  576. }
  577. }
  578. export function createConditionalExpression(
  579. test: ConditionalExpression['test'],
  580. consequent: ConditionalExpression['consequent'],
  581. alternate: ConditionalExpression['alternate'],
  582. newline = true
  583. ): ConditionalExpression {
  584. return {
  585. type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
  586. test,
  587. consequent,
  588. alternate,
  589. newline,
  590. loc: locStub
  591. }
  592. }
  593. export function createCacheExpression(
  594. index: number,
  595. value: JSChildNode,
  596. isVNode: boolean = false
  597. ): CacheExpression {
  598. return {
  599. type: NodeTypes.JS_CACHE_EXPRESSION,
  600. index,
  601. value,
  602. isVNode,
  603. loc: locStub
  604. }
  605. }
  606. export function createBlockStatement(
  607. body: BlockStatement['body']
  608. ): BlockStatement {
  609. return {
  610. type: NodeTypes.JS_BLOCK_STATEMENT,
  611. body,
  612. loc: locStub
  613. }
  614. }
  615. export function createTemplateLiteral(
  616. elements: TemplateLiteral['elements']
  617. ): TemplateLiteral {
  618. return {
  619. type: NodeTypes.JS_TEMPLATE_LITERAL,
  620. elements,
  621. loc: locStub
  622. }
  623. }
  624. export function createIfStatement(
  625. test: IfStatement['test'],
  626. consequent: IfStatement['consequent'],
  627. alternate?: IfStatement['alternate']
  628. ): IfStatement {
  629. return {
  630. type: NodeTypes.JS_IF_STATEMENT,
  631. test,
  632. consequent,
  633. alternate,
  634. loc: locStub
  635. }
  636. }
  637. export function createAssignmentExpression(
  638. left: AssignmentExpression['left'],
  639. right: AssignmentExpression['right']
  640. ): AssignmentExpression {
  641. return {
  642. type: NodeTypes.JS_ASSIGNMENT_EXPRESSION,
  643. left,
  644. right,
  645. loc: locStub
  646. }
  647. }
  648. export function createSequenceExpression(
  649. expressions: SequenceExpression['expressions']
  650. ): SequenceExpression {
  651. return {
  652. type: NodeTypes.JS_SEQUENCE_EXPRESSION,
  653. expressions,
  654. loc: locStub
  655. }
  656. }
  657. export function createReturnStatement(
  658. returns: ReturnStatement['returns']
  659. ): ReturnStatement {
  660. return {
  661. type: NodeTypes.JS_RETURN_STATEMENT,
  662. returns,
  663. loc: locStub
  664. }
  665. }