WIP: Implemented parseVariableDeclarator draft
authorDavid Teller <dteller@mozilla.com>
Fri, 04 Aug 2017 17:59:11 +0200
changeset 641373 533144912f72c98d07d2bed1d3bc377219b3efc5
parent 641372 f0c7a24aa199c7a3346430ce75fa482e8f2cde62
child 641374 1884c68b64ecb632a828316a63f5144dee7a52f4
push id72504
push userdteller@mozilla.com
push dateSun, 06 Aug 2017 22:28:40 +0000
milestone57.0a1
WIP: Implemented parseVariableDeclarator MozReview-Commit-ID: 64WRScIdend
js/src/frontend/BinSource.cpp
--- a/js/src/frontend/BinSource.cpp
+++ b/js/src/frontend/BinSource.cpp
@@ -98,17 +98,17 @@ public:
     }
 
     bool parse(char* start, char* stop, GlobalSharedContext* sc, UniquePtr<ParseNode>& out);
 private:
     bool raiseError();
 
     // --- Parse full nodes.
 
-    bool parseBool(SimpleTokenReader*, Maybe<bool>*);
+    bool parsePattern(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseProgram(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseStatementList(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parseScope(SimpleTokenReader* reader, ScopeData& out);
     bool parseExpression(SimpleTokenReader* reader, UniquePtr<ParseNode>& out);
     bool parsePropertyName(SimpleTokenReader* reader, UniquePtr<PropertyName>& out);
     bool parseBlockStatement(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
     bool parseCatchClause(SimpleTokenReader* reader, UniquePtr<ParseNode>&);
@@ -296,17 +296,17 @@ ASTReader::parseScope(SimpleTokenReader*
     }
     if (kind != BinKind::binjs_scope) {
         return this->raiseError();
     }
 
     for (auto field: fields) {
         switch (field) {
             case BinField::has_direct_eval:
-                if (!this->parseBool(reader, &out.hasDirectEval)) {
+                if (!this->readBool(reader, out.hasDirectEval)) {
                     return false;
                 }
                 break;
             case BinField::let_decl_names:
                 if (!this->parseStringList(reader, &out.letNames)) {
                     return false;
                 }
                 break;
@@ -1275,26 +1275,16 @@ ASTReader::parseVariableDeclarationAux(S
 
     result->setKind(kind);
     result->setOp(op);
     out = Move(result);
 
     return true;
 }
 
-bool
-ASTReader::parseBool(SimpleTokenReader* reader, Maybe<bool>* result) {
-    if (result->isSome()) {
-        // Already parsed.
-        // FIXME: Can replace with an assert once we have
-        // implemented headers and header validation.
-        return this->raiseError();
-    }
-    return reader->readBool(result);
-}
 
 bool
 ASTReader::parseExpression(SimpleTokenReader* reader, UniquePtr<ParseNode>& out) {
     if (out) {
         return this->raiseError();
     }
 
     SimpleTokenReader::BinFields fields(this->cx);
@@ -1867,17 +1857,17 @@ ASTReader::parseExpression(SimpleTokenRe
                         }
                         break;
                     case BinField::property:
                         if (!this->parseExpression(&sub, property)) {
                             return false;
                         }
                         break;
                     case BinField::computed:
-                        if (!this->parseBool(&sub, &isComputed)) {
+                        if (!this->readBool(&sub, isComputed)) {
                             return false;
                         }
                         break;
                     default:
                         return this->raiseError();
                 }
             }
 
@@ -2008,16 +1998,91 @@ ASTReader::parseExpressionStatementAux(S
         return this->raiseError();
     }
 
     out = Move(result);
     return false;
 }
 
 bool
+ASTReader::parseVariableDeclarator(SimpleTokenReader* reader, UniquePtr<ParseNode>& out) {
+    if (out) {
+        return this->raiseError();
+    }
+
+    BinKind kind;
+    SimpleTokenReader::BinFields fields(this->cx);
+    SimpleTokenReader sub(this->cx);
+
+    if (!reader->taggedTuple(kind, fields, &sub)) {
+        return false;
+    }
+
+    if (kind != BinKind::variable_declarator) {
+        return this->raiseError();
+    }
+
+    UniquePtr<ParseNode> id;
+    UniquePtr<ParseNode> init; // Optional.
+    for (auto field: fields) {
+        switch (field) {
+            case BinField::id:
+                if (!this->parsePattern(&sub, id)) {
+                    return false;
+                }
+                break;
+            case BinField::init:
+                if (!this->parseExpression(&sub, init)) {
+                    return false;
+                }
+                break;
+            default:
+                return this->raiseError();
+        }
+    }
+
+    if (!id) {
+        return this->raiseError();
+    }
+
+    UniquePtr<ParseNode> result;
+
+    // FIXME: Documentation in ParseNode is clearly obsolete.
+    if (id->isKind(PNK_NAME)) {
+        // var foo [= bar]
+        RootedAtom atom(cx, id->pn_atom);
+        result = UniquePtr<ParseNode>(new_<NameNode>(PNK_NAME, JSOP_NOP, atom, TokenPos()));
+        if (!result) {
+            return false;
+        }
+
+        if (init) {
+            result->pn_expr = init.release();
+        }
+    } else {
+        // var pattern = bar
+        if (!init) {
+            // Here, `init` is required.
+            return this->raiseError();
+        }
+        result = UniquePtr<ParseNode>(new_<BinaryNode>(PNK_ASSIGN, JSOP_NOP, TokenPos(), nullptr, nullptr));
+        if (!result) {
+            return false;
+        }
+
+        result->pn_left = id.release();
+        result->pn_right = init.release();
+    }
+
+    out = Move(result);
+    return true;
+}
+
+
+bool
 ASTReader::readNumber(SimpleTokenReader* reader, Maybe<double>& out) {
     if (out) {
         return this->raiseError();
     }
 
     return reader->readMaybeF64(&out);
 }