BVB Source Codes

reactide Show statement.js Source code

Return Download reactide: download statement.js Source code - Download reactide Source code - Type:.js
  1. import {types as tt} from "./tokentype"
  2. import {Parser} from "./state"
  3. import {lineBreak, skipWhiteSpace} from "./whitespace"
  4. import {isIdentifierStart, isIdentifierChar} from "./identifier"
  5. import {DestructuringErrors} from "./parseutil"
  6.  
  7. const pp = Parser.prototype
  8.  
  9. // ### Statement parsing
  10.  
  11. // Parse a program. Initializes the parser, reads any number of
  12. // statements, and wraps them in a Program node.  Optionally takes a
  13. // `program` argument.  If present, the statements will be appended
  14. // to its body instead of creating a new node.
  15.  
  16. pp.parseTopLevel = function(node) {
  17.   let first = true
  18.   if (!node.body) node.body = []
  19.   while (this.type !== tt.eof) {
  20.     let stmt = this.parseStatement(true, true)
  21.     node.body.push(stmt)
  22.     if (first) {
  23.       if (this.isUseStrict(stmt)) this.setStrict(true)
  24.       first = false
  25.     }
  26.   }
  27.   this.next()
  28.   if (this.options.ecmaVersion >= 6) {
  29.     node.sourceType = this.options.sourceType
  30.   }
  31.   return this.finishNode(node, "Program")
  32. }
  33.  
  34. const loopLabel = {kind: "loop"}, switchLabel = {kind: "switch"}
  35.  
  36. pp.isLet = function() {
  37.   if (this.type !== tt.name || this.options.ecmaVersion < 6 || this.value != "let") return false
  38.   skipWhiteSpace.lastIndex = this.pos
  39.   let skip = skipWhiteSpace.exec(this.input)
  40.   let next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next)
  41.   if (nextCh === 91 || nextCh == 123) return true // '{' and '['
  42.   if (isIdentifierStart(nextCh, true)) {
  43.     for (var pos = next + 1; isIdentifierChar(this.input.charCodeAt(pos), true); ++pos) {}
  44.     let ident = this.input.slice(next, pos)
  45.     if (!this.isKeyword(ident)) return true
  46.   }
  47.   return false
  48. }
  49.  
  50. // Parse a single statement.
  51. //
  52. // If expecting a statement and finding a slash operator, parse a
  53. // regular expression literal. This is to handle cases like
  54. // `if (foo) /blah/.exec(foo)`, where looking at the previous token
  55. // does not help.
  56.  
  57. pp.parseStatement = function(declaration, topLevel) {
  58.   let starttype = this.type, node = this.startNode(), kind
  59.  
  60.   if (this.isLet()) {
  61.     starttype = tt._var
  62.     kind = "let"
  63.   }
  64.  
  65.   // Most types of statements are recognized by the keyword they
  66.   // start with. Many are trivial to parse, some require a bit of
  67.   // complexity.
  68.  
  69.   switch (starttype) {
  70.   case tt._break: case tt._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
  71.   case tt._debugger: return this.parseDebuggerStatement(node)
  72.   case tt._do: return this.parseDoStatement(node)
  73.   case tt._for: return this.parseForStatement(node)
  74.   case tt._function:
  75.     if (!declaration && this.options.ecmaVersion >= 6) this.unexpected()
  76.     return this.parseFunctionStatement(node)
  77.   case tt._class:
  78.     if (!declaration) this.unexpected()
  79.     return this.parseClass(node, true)
  80.   case tt._if: return this.parseIfStatement(node)
  81.   case tt._return: return this.parseReturnStatement(node)
  82.   case tt._switch: return this.parseSwitchStatement(node)
  83.   case tt._throw: return this.parseThrowStatement(node)
  84.   case tt._try: return this.parseTryStatement(node)
  85.   case tt._const: case tt._var:
  86.     kind = kind || this.value
  87.     if (!declaration && kind != "var") this.unexpected()
  88.     return this.parseVarStatement(node, kind)
  89.   case tt._while: return this.parseWhileStatement(node)
  90.   case tt._with: return this.parseWithStatement(node)
  91.   case tt.braceL: return this.parseBlock()
  92.   case tt.semi: return this.parseEmptyStatement(node)
  93.   case tt._export:
  94.   case tt._import:
  95.     if (!this.options.allowImportExportEverywhere) {
  96.       if (!topLevel)
  97.         this.raise(this.start, "'import' and 'export' may only appear at the top level")
  98.       if (!this.inModule)
  99.         this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'")
  100.     }
  101.     return starttype === tt._import ? this.parseImport(node) : this.parseExport(node)
  102.  
  103.     // If the statement does not start with a statement keyword or a
  104.     // brace, it's an ExpressionStatement or LabeledStatement. We
  105.     // simply start parsing an expression, and afterwards, if the
  106.     // next token is a colon and the expression was a simple
  107.     // Identifier node, we switch to interpreting it as a label.
  108.   default:
  109.     let maybeName = this.value, expr = this.parseExpression()
  110.     if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon))
  111.       return this.parseLabeledStatement(node, maybeName, expr)
  112.     else return this.parseExpressionStatement(node, expr)
  113.   }
  114. }
  115.  
  116. pp.parseBreakContinueStatement = function(node, keyword) {
  117.   let isBreak = keyword == "break"
  118.   this.next()
  119.   if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null
  120.   else if (this.type !== tt.name) this.unexpected()
  121.   else {
  122.     node.label = this.parseIdent()
  123.     this.semicolon()
  124.   }
  125.  
  126.   // Verify that there is an actual destination to break or
  127.   // continue to.
  128.   for (var i = 0; i < this.labels.length; ++i) {
  129.     let lab = this.labels[i]
  130.     if (node.label == null || lab.name === node.label.name) {
  131.       if (lab.kind != null && (isBreak || lab.kind === "loop")) break
  132.       if (node.label && isBreak) break
  133.     }
  134.   }
  135.   if (i === this.labels.length) this.raise(node.start, "Unsyntactic " + keyword)
  136.   return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
  137. }
  138.  
  139. pp.parseDebuggerStatement = function(node) {
  140.   this.next()
  141.   this.semicolon()
  142.   return this.finishNode(node, "DebuggerStatement")
  143. }
  144.  
  145. pp.parseDoStatement = function(node) {
  146.   this.next()
  147.   this.labels.push(loopLabel)
  148.   node.body = this.parseStatement(false)
  149.   this.labels.pop()
  150.   this.expect(tt._while)
  151.   node.test = this.parseParenExpression()
  152.   if (this.options.ecmaVersion >= 6)
  153.     this.eat(tt.semi)
  154.   else
  155.     this.semicolon()
  156.   return this.finishNode(node, "DoWhileStatement")
  157. }
  158.  
  159. // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
  160. // loop is non-trivial. Basically, we have to parse the init `var`
  161. // statement or expression, disallowing the `in` operator (see
  162. // the second parameter to `parseExpression`), and then check
  163. // whether the next token is `in` or `of`. When there is no init
  164. // part (semicolon immediately after the opening parenthesis), it
  165. // is a regular `for` loop.
  166.  
  167. pp.parseForStatement = function(node) {
  168.   this.next()
  169.   this.labels.push(loopLabel)
  170.   this.expect(tt.parenL)
  171.   if (this.type === tt.semi) return this.parseFor(node, null)
  172.   let isLet = this.isLet()
  173.   if (this.type === tt._var || this.type === tt._const || isLet) {
  174.     let init = this.startNode(), kind = isLet ? "let" : this.value
  175.     this.next()
  176.     this.parseVar(init, true, kind)
  177.     this.finishNode(init, "VariableDeclaration")
  178.     if ((this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init.declarations.length === 1 &&
  179.         !(kind !== "var" && init.declarations[0].init))
  180.       return this.parseForIn(node, init)
  181.     return this.parseFor(node, init)
  182.   }
  183.   let refDestructuringErrors = new DestructuringErrors
  184.   let init = this.parseExpression(true, refDestructuringErrors)
  185.   if (this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
  186.     this.checkPatternErrors(refDestructuringErrors, true)
  187.     this.toAssignable(init)
  188.     this.checkLVal(init)
  189.     return this.parseForIn(node, init)
  190.   } else {
  191.     this.checkExpressionErrors(refDestructuringErrors, true)
  192.   }
  193.   return this.parseFor(node, init)
  194. }
  195.  
  196. pp.parseFunctionStatement = function(node) {
  197.   this.next()
  198.   return this.parseFunction(node, true)
  199. }
  200.  
  201. pp.parseIfStatement = function(node) {
  202.   this.next()
  203.   node.test = this.parseParenExpression()
  204.   node.consequent = this.parseStatement(false)
  205.   node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null
  206.   return this.finishNode(node, "IfStatement")
  207. }
  208.  
  209. pp.parseReturnStatement = function(node) {
  210.   if (!this.inFunction && !this.options.allowReturnOutsideFunction)
  211.     this.raise(this.start, "'return' outside of function")
  212.   this.next()
  213.  
  214.   // In `return` (and `break`/`continue`), the keywords with
  215.   // optional arguments, we eagerly look for a semicolon or the
  216.   // possibility to insert one.
  217.  
  218.   if (this.eat(tt.semi) || this.insertSemicolon()) node.argument = null
  219.   else { node.argument = this.parseExpression(); this.semicolon() }
  220.   return this.finishNode(node, "ReturnStatement")
  221. }
  222.  
  223. pp.parseSwitchStatement = function(node) {
  224.   this.next()
  225.   node.discriminant = this.parseParenExpression()
  226.   node.cases = []
  227.   this.expect(tt.braceL)
  228.   this.labels.push(switchLabel)
  229.  
  230.   // Statements under must be grouped (by label) in SwitchCase
  231.   // nodes. `cur` is used to keep the node that we are currently
  232.   // adding statements to.
  233.  
  234.   for (var cur, sawDefault = false; this.type != tt.braceR;) {
  235.     if (this.type === tt._case || this.type === tt._default) {
  236.       let isCase = this.type === tt._case
  237.       if (cur) this.finishNode(cur, "SwitchCase")
  238.       node.cases.push(cur = this.startNode())
  239.       cur.consequent = []
  240.       this.next()
  241.       if (isCase) {
  242.         cur.test = this.parseExpression()
  243.       } else {
  244.         if (sawDefault) this.raiseRecoverable(this.lastTokStart, "Multiple default clauses")
  245.         sawDefault = true
  246.         cur.test = null
  247.       }
  248.       this.expect(tt.colon)
  249.     } else {
  250.       if (!cur) this.unexpected()
  251.       cur.consequent.push(this.parseStatement(true))
  252.     }
  253.   }
  254.   if (cur) this.finishNode(cur, "SwitchCase")
  255.   this.next() // Closing brace
  256.   this.labels.pop()
  257.   return this.finishNode(node, "SwitchStatement")
  258. }
  259.  
  260. pp.parseThrowStatement = function(node) {
  261.   this.next()
  262.   if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
  263.     this.raise(this.lastTokEnd, "Illegal newline after throw")
  264.   node.argument = this.parseExpression()
  265.   this.semicolon()
  266.   return this.finishNode(node, "ThrowStatement")
  267. }
  268.  
  269. // Reused empty array added for node fields that are always empty.
  270.  
  271. const empty = []
  272.  
  273. pp.parseTryStatement = function(node) {
  274.   this.next()
  275.   node.block = this.parseBlock()
  276.   node.handler = null
  277.   if (this.type === tt._catch) {
  278.     let clause = this.startNode()
  279.     this.next()
  280.     this.expect(tt.parenL)
  281.     clause.param = this.parseBindingAtom()
  282.     this.checkLVal(clause.param, true)
  283.     this.expect(tt.parenR)
  284.     clause.body = this.parseBlock()
  285.     node.handler = this.finishNode(clause, "CatchClause")
  286.   }
  287.   node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null
  288.   if (!node.handler && !node.finalizer)
  289.     this.raise(node.start, "Missing catch or finally clause")
  290.   return this.finishNode(node, "TryStatement")
  291. }
  292.  
  293. pp.parseVarStatement = function(node, kind) {
  294.   this.next()
  295.   this.parseVar(node, false, kind)
  296.   this.semicolon()
  297.   return this.finishNode(node, "VariableDeclaration")
  298. }
  299.  
  300. pp.parseWhileStatement = function(node) {
  301.   this.next()
  302.   node.test = this.parseParenExpression()
  303.   this.labels.push(loopLabel)
  304.   node.body = this.parseStatement(false)
  305.   this.labels.pop()
  306.   return this.finishNode(node, "WhileStatement")
  307. }
  308.  
  309. pp.parseWithStatement = function(node) {
  310.   if (this.strict) this.raise(this.start, "'with' in strict mode")
  311.   this.next()
  312.   node.object = this.parseParenExpression()
  313.   node.body = this.parseStatement(false)
  314.   return this.finishNode(node, "WithStatement")
  315. }
  316.  
  317. pp.parseEmptyStatement = function(node) {
  318.   this.next()
  319.   return this.finishNode(node, "EmptyStatement")
  320. }
  321.  
  322. pp.parseLabeledStatement = function(node, maybeName, expr) {
  323.   for (let i = 0; i < this.labels.length; ++i)
  324.     if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared")
  325.   let kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null
  326.   for (let i = this.labels.length - 1; i >= 0; i--) {
  327.     let label = this.labels[i]
  328.     if (label.statementStart == node.start) {
  329.       label.statementStart = this.start
  330.       label.kind = kind
  331.     } else break
  332.   }
  333.   this.labels.push({name: maybeName, kind: kind, statementStart: this.start})
  334.   node.body = this.parseStatement(true)
  335.   this.labels.pop()
  336.   node.label = expr
  337.   return this.finishNode(node, "LabeledStatement")
  338. }
  339.  
  340. pp.parseExpressionStatement = function(node, expr) {
  341.   node.expression = expr
  342.   this.semicolon()
  343.   return this.finishNode(node, "ExpressionStatement")
  344. }
  345.  
  346. // Parse a semicolon-enclosed block of statements, handling `"use
  347. // strict"` declarations when `allowStrict` is true (used for
  348. // function bodies).
  349.  
  350. pp.parseBlock = function(allowStrict) {
  351.   let node = this.startNode(), first = true, oldStrict
  352.   node.body = []
  353.   this.expect(tt.braceL)
  354.   while (!this.eat(tt.braceR)) {
  355.     let stmt = this.parseStatement(true)
  356.     node.body.push(stmt)
  357.     if (first && allowStrict && this.isUseStrict(stmt)) {
  358.       oldStrict = this.strict
  359.       this.setStrict(this.strict = true)
  360.     }
  361.     first = false
  362.   }
  363.   if (oldStrict === false) this.setStrict(false)
  364.   return this.finishNode(node, "BlockStatement")
  365. }
  366.  
  367. // Parse a regular `for` loop. The disambiguation code in
  368. // `parseStatement` will already have parsed the init statement or
  369. // expression.
  370.  
  371. pp.parseFor = function(node, init) {
  372.   node.init = init
  373.   this.expect(tt.semi)
  374.   node.test = this.type === tt.semi ? null : this.parseExpression()
  375.   this.expect(tt.semi)
  376.   node.update = this.type === tt.parenR ? null : this.parseExpression()
  377.   this.expect(tt.parenR)
  378.   node.body = this.parseStatement(false)
  379.   this.labels.pop()
  380.   return this.finishNode(node, "ForStatement")
  381. }
  382.  
  383. // Parse a `for`/`in` and `for`/`of` loop, which are almost
  384. // same from parser's perspective.
  385.  
  386. pp.parseForIn = function(node, init) {
  387.   let type = this.type === tt._in ? "ForInStatement" : "ForOfStatement"
  388.   this.next()
  389.   node.left = init
  390.   node.right = this.parseExpression()
  391.   this.expect(tt.parenR)
  392.   node.body = this.parseStatement(false)
  393.   this.labels.pop()
  394.   return this.finishNode(node, type)
  395. }
  396.  
  397. // Parse a list of variable declarations.
  398.  
  399. pp.parseVar = function(node, isFor, kind) {
  400.   node.declarations = []
  401.   node.kind = kind
  402.   for (;;) {
  403.     let decl = this.startNode()
  404.     this.parseVarId(decl)
  405.     if (this.eat(tt.eq)) {
  406.       decl.init = this.parseMaybeAssign(isFor)
  407.     } else if (kind === "const" && !(this.type === tt._in || (this.options.ecmaVersion >= 6 && this.isContextual("of")))) {
  408.       this.unexpected()
  409.     } else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
  410.       this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value")
  411.     } else {
  412.       decl.init = null
  413.     }
  414.     node.declarations.push(this.finishNode(decl, "VariableDeclarator"))
  415.     if (!this.eat(tt.comma)) break
  416.   }
  417.   return node
  418. }
  419.  
  420. pp.parseVarId = function(decl) {
  421.   decl.id = this.parseBindingAtom()
  422.   this.checkLVal(decl.id, true)
  423. }
  424.  
  425. // Parse a function declaration or literal (depending on the
  426. // `isStatement` parameter).
  427.  
  428. pp.parseFunction = function(node, isStatement, allowExpressionBody) {
  429.   this.initFunction(node)
  430.   if (this.options.ecmaVersion >= 6)
  431.     node.generator = this.eat(tt.star)
  432.   var oldInGen = this.inGenerator
  433.   this.inGenerator = node.generator
  434.   if (isStatement || this.type === tt.name)
  435.     node.id = this.parseIdent()
  436.   this.parseFunctionParams(node)
  437.   this.parseFunctionBody(node, allowExpressionBody)
  438.   this.inGenerator = oldInGen
  439.   return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
  440. }
  441.  
  442. pp.parseFunctionParams = function(node) {
  443.   this.expect(tt.parenL)
  444.   node.params = this.parseBindingList(tt.parenR, false, false, true)
  445. }
  446.  
  447. // Parse a class declaration or literal (depending on the
  448. // `isStatement` parameter).
  449.  
  450. pp.parseClass = function(node, isStatement) {
  451.   this.next()
  452.   this.parseClassId(node, isStatement)
  453.   this.parseClassSuper(node)
  454.   let classBody = this.startNode()
  455.   let hadConstructor = false
  456.   classBody.body = []
  457.   this.expect(tt.braceL)
  458.   while (!this.eat(tt.braceR)) {
  459.     if (this.eat(tt.semi)) continue
  460.     let method = this.startNode()
  461.     let isGenerator = this.eat(tt.star)
  462.     let isMaybeStatic = this.type === tt.name && this.value === "static"
  463.     this.parsePropertyName(method)
  464.     method.static = isMaybeStatic && this.type !== tt.parenL
  465.     if (method.static) {
  466.       if (isGenerator) this.unexpected()
  467.       isGenerator = this.eat(tt.star)
  468.       this.parsePropertyName(method)
  469.     }
  470.     method.kind = "method"
  471.     let isGetSet = false
  472.     if (!method.computed) {
  473.       let {key} = method
  474.       if (!isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
  475.         isGetSet = true
  476.         method.kind = key.name
  477.         key = this.parsePropertyName(method)
  478.       }
  479.       if (!method.static && (key.type === "Identifier" && key.name === "constructor" ||
  480.           key.type === "Literal" && key.value === "constructor")) {
  481.         if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class")
  482.         if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier")
  483.         if (isGenerator) this.raise(key.start, "Constructor can't be a generator")
  484.         method.kind = "constructor"
  485.         hadConstructor = true
  486.       }
  487.     }
  488.     this.parseClassMethod(classBody, method, isGenerator)
  489.     if (isGetSet) {
  490.       let paramCount = method.kind === "get" ? 0 : 1
  491.       if (method.value.params.length !== paramCount) {
  492.         let start = method.value.start
  493.         if (method.kind === "get")
  494.           this.raiseRecoverable(start, "getter should have no params")
  495.         else
  496.           this.raiseRecoverable(start, "setter should have exactly one param")
  497.       }
  498.       if (method.kind === "set" && method.value.params[0].type === "RestElement")
  499.         this.raise(method.value.params[0].start, "Setter cannot use rest params")
  500.     }
  501.   }
  502.   node.body = this.finishNode(classBody, "ClassBody")
  503.   return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
  504. }
  505.  
  506. pp.parseClassMethod = function(classBody, method, isGenerator) {
  507.   method.value = this.parseMethod(isGenerator)
  508.   classBody.body.push(this.finishNode(method, "MethodDefinition"))
  509. }
  510.  
  511. pp.parseClassId = function(node, isStatement) {
  512.   node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null
  513. }
  514.  
  515. pp.parseClassSuper = function(node) {
  516.   node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null
  517. }
  518.  
  519. // Parses module export declaration.
  520.  
  521. pp.parseExport = function(node) {
  522.   this.next()
  523.   // export * from '...'
  524.   if (this.eat(tt.star)) {
  525.     this.expectContextual("from")
  526.     node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  527.     this.semicolon()
  528.     return this.finishNode(node, "ExportAllDeclaration")
  529.   }
  530.   if (this.eat(tt._default)) { // export default ...
  531.     let parens = this.type == tt.parenL
  532.     let expr = this.parseMaybeAssign()
  533.     let needsSemi = true
  534.     if (!parens && (expr.type == "FunctionExpression" ||
  535.                     expr.type == "ClassExpression")) {
  536.       needsSemi = false
  537.       if (expr.id) {
  538.         expr.type = expr.type == "FunctionExpression"
  539.           ? "FunctionDeclaration"
  540.           : "ClassDeclaration"
  541.       }
  542.     }
  543.     node.declaration = expr
  544.     if (needsSemi) this.semicolon()
  545.     return this.finishNode(node, "ExportDefaultDeclaration")
  546.   }
  547.   // export var|const|let|function|class ...
  548.   if (this.shouldParseExportStatement()) {
  549.     node.declaration = this.parseStatement(true)
  550.     node.specifiers = []
  551.     node.source = null
  552.   } else { // export { x, y as z } [from '...']
  553.     node.declaration = null
  554.     node.specifiers = this.parseExportSpecifiers()
  555.     if (this.eatContextual("from")) {
  556.       node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  557.     } else {
  558.       // check for keywords used as local names
  559.       for (let i = 0; i < node.specifiers.length; i++) {
  560.         if (this.keywords.test(node.specifiers[i].local.name) || this.reservedWords.test(node.specifiers[i].local.name)) {
  561.           this.unexpected(node.specifiers[i].local.start)
  562.         }
  563.       }
  564.  
  565.       node.source = null
  566.     }
  567.     this.semicolon()
  568.   }
  569.   return this.finishNode(node, "ExportNamedDeclaration")
  570. }
  571.  
  572. pp.shouldParseExportStatement = function() {
  573.   return this.type.keyword || this.isLet()
  574. }
  575.  
  576. // Parses a comma-separated list of module exports.
  577.  
  578. pp.parseExportSpecifiers = function() {
  579.   let nodes = [], first = true
  580.   // export { x, y as z } [from '...']
  581.   this.expect(tt.braceL)
  582.   while (!this.eat(tt.braceR)) {
  583.     if (!first) {
  584.       this.expect(tt.comma)
  585.       if (this.afterTrailingComma(tt.braceR)) break
  586.     } else first = false
  587.  
  588.     let node = this.startNode()
  589.     node.local = this.parseIdent(this.type === tt._default)
  590.     node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local
  591.     nodes.push(this.finishNode(node, "ExportSpecifier"))
  592.   }
  593.   return nodes
  594. }
  595.  
  596. // Parses import declaration.
  597.  
  598. pp.parseImport = function(node) {
  599.   this.next()
  600.   // import '...'
  601.   if (this.type === tt.string) {
  602.     node.specifiers = empty
  603.     node.source = this.parseExprAtom()
  604.   } else {
  605.     node.specifiers = this.parseImportSpecifiers()
  606.     this.expectContextual("from")
  607.     node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected()
  608.   }
  609.   this.semicolon()
  610.   return this.finishNode(node, "ImportDeclaration")
  611. }
  612.  
  613. // Parses a comma-separated list of module imports.
  614.  
  615. pp.parseImportSpecifiers = function() {
  616.   let nodes = [], first = true
  617.   if (this.type === tt.name) {
  618.     // import defaultObj, { x, y as z } from '...'
  619.     let node = this.startNode()
  620.     node.local = this.parseIdent()
  621.     this.checkLVal(node.local, true)
  622.     nodes.push(this.finishNode(node, "ImportDefaultSpecifier"))
  623.     if (!this.eat(tt.comma)) return nodes
  624.   }
  625.   if (this.type === tt.star) {
  626.     let node = this.startNode()
  627.     this.next()
  628.     this.expectContextual("as")
  629.     node.local = this.parseIdent()
  630.     this.checkLVal(node.local, true)
  631.     nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"))
  632.     return nodes
  633.   }
  634.   this.expect(tt.braceL)
  635.   while (!this.eat(tt.braceR)) {
  636.     if (!first) {
  637.       this.expect(tt.comma)
  638.       if (this.afterTrailingComma(tt.braceR)) break
  639.     } else first = false
  640.  
  641.     let node = this.startNode()
  642.     node.imported = this.parseIdent(true)
  643.     if (this.eatContextual("as")) {
  644.       node.local = this.parseIdent()
  645.     } else {
  646.       node.local = node.imported
  647.       if (this.isKeyword(node.local.name)) this.unexpected(node.local.start)
  648.       if (this.reservedWordsStrict.test(node.local.name)) this.raise(node.local.start, "The keyword '" + node.local.name + "' is reserved")
  649.     }
  650.     this.checkLVal(node.local, true)
  651.     nodes.push(this.finishNode(node, "ImportSpecifier"))
  652.   }
  653.   return nodes
  654. }
  655.  
downloadstatement.js Source code - Download reactide Source code
Related Source Codes/Software:
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
postal - 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top