refactored SkSL VarDeclaration handling
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2312233002

Review-Url: https://codereview.chromium.org/2312233002
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 65187c3..b240e45 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -274,7 +274,7 @@
 }
 
 /* modifiers type IDENTIFIER varDeclarationEnd */
-std::unique_ptr<ASTVarDeclaration> Parser::varDeclaration() {
+std::unique_ptr<ASTVarDeclarations> Parser::varDeclarations() {
     ASTModifiers modifiers = this->modifiers();
     std::unique_ptr<ASTType> type(this->type());
     if (!type) {
@@ -301,23 +301,23 @@
     }
     std::vector<Type::Field> fields;
     while (this->peek().fKind != Token::RBRACE) {
-        std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
+        std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
         if (!decl) {
             return nullptr;
         }
-        for (size_t i = 0; i < decl->fNames.size(); i++) {
+        for (const auto& var : decl->fVars) {
             auto type = (const Type*) fTypes[decl->fType->fName];
-            for (int j = (int) decl->fSizes[i].size() - 1; j >= 0; j--) {
-                if (decl->fSizes[i][j]->fKind != ASTExpression::kInt_Kind) {
+            for (int i = (int) var.fSizes.size() - 1; i >= 0; i--) {
+                if (var.fSizes[i]->fKind != ASTExpression::kInt_Kind) {
                     this->error(decl->fPosition, "array size in struct field must be a constant");
                 }
-                uint64_t columns = ((ASTIntLiteral&) *decl->fSizes[i][j]).fValue;
+                uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
                 std::string name = type->name() + "[" + to_string(columns) + "]";
                 type = new Type(name, Type::kArray_Kind, *type, (int) columns);
                 fTypes.takeOwnership((Type*) type);
             }
-            fields.push_back(Type::Field(decl->fModifiers, decl->fNames[i], type));
-            if (decl->fValues[i]) {
+            fields.push_back(Type::Field(decl->fModifiers, var.fName, type));
+            if (var.fValue) {
                 this->error(decl->fPosition, "initializers are not permitted on struct fields");
             }
         }
@@ -331,20 +331,20 @@
 }
 
 /* structDeclaration ((IDENTIFIER varDeclarationEnd) | SEMICOLON) */
-std::unique_ptr<ASTVarDeclaration> Parser::structVarDeclaration(ASTModifiers modifiers) {
+std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers modifiers) {
     std::unique_ptr<ASTType> type = this->structDeclaration();
     if (!type) {
         return nullptr;
     }
     if (peek().fKind == Token::IDENTIFIER) {
         Token name = this->nextToken();
-        std::unique_ptr<ASTVarDeclaration> result = this->varDeclarationEnd(modifiers, 
-                                                                            std::move(type), 
-                                                                            std::move(name.fText));
+        std::unique_ptr<ASTVarDeclarations> result = this->varDeclarationEnd(modifiers, 
+                                                                             std::move(type), 
+                                                                             std::move(name.fText));
         if (result) {
-            for (size_t i = 0; i < result->fValues.size(); i++) {
-                if (result->fValues[i]) {
-                    this->error(result->fValues[i]->fPosition, 
+            for (const auto& var : result->fVars) {
+                if (var.fValue) {
+                    this->error(var.fValue->fPosition, 
                                 "struct variables cannot be initialized");
                 }
             }
@@ -357,12 +357,10 @@
 
 /* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER 
    (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
-std::unique_ptr<ASTVarDeclaration> Parser::varDeclarationEnd(ASTModifiers mods,
-                                                             std::unique_ptr<ASTType> type,
-                                                             std::string name) {
-    std::vector<std::string> names;
-    std::vector<std::vector<std::unique_ptr<ASTExpression>>> sizes;
-    names.push_back(name);
+std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
+                                                              std::unique_ptr<ASTType> type,
+                                                              std::string name) {
+    std::vector<ASTVarDeclaration> vars;
     std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
     while (this->peek().fKind == Token::LBRACKET) {
         this->nextToken();
@@ -380,26 +378,23 @@
             }
         }
     }
-    sizes.push_back(std::move(currentVarSizes));
-    std::vector<std::unique_ptr<ASTExpression>> values;
+    std::unique_ptr<ASTExpression> value;
     if (this->peek().fKind == Token::EQ) {
         this->nextToken();
-        std::unique_ptr<ASTExpression> value(this->expression());
+        value = this->expression();
         if (!value) {
             return nullptr;
         }
-        values.push_back(std::move(value));
-    } else {
-        values.push_back(nullptr);
     }
+    vars.emplace_back(std::move(name), std::move(currentVarSizes), std::move(value));
     while (this->peek().fKind == Token::COMMA) {
         this->nextToken();
         Token name;
         if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) {
             return nullptr;
         }
-        names.push_back(name.fText);
         currentVarSizes.clear();
+        value.reset();
         while (this->peek().fKind == Token::LBRACKET) {
             this->nextToken();
             if (this->peek().fKind == Token::RBRACKET) {
@@ -416,26 +411,21 @@
                 }
             }
         }
-        sizes.push_back(std::move(currentVarSizes));
         if (this->peek().fKind == Token::EQ) {
             this->nextToken();
-            std::unique_ptr<ASTExpression> value(this->expression());
+            value = this->expression();
             if (!value) {
                 return nullptr;
             }
-            values.push_back(std::move(value));
-        } else {
-            values.push_back(nullptr);
         }
+        vars.emplace_back(std::move(name.fText), std::move(currentVarSizes), std::move(value));
     }
     if (!this->expect(Token::SEMICOLON, "';'")) {
         return nullptr;
     }
-    return std::unique_ptr<ASTVarDeclaration>(new ASTVarDeclaration(std::move(mods),
-                                                                    std::move(type),
-                                                                    std::move(names),
-                                                                    std::move(sizes),
-                                                                    std::move(values)));
+    return std::unique_ptr<ASTVarDeclarations>(new ASTVarDeclarations(std::move(mods),
+                                                                      std::move(type),
+                                                                      std::move(vars)));
 }
 
 /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */
@@ -614,7 +604,7 @@
         case Token::HIGHP:   // fall through
         case Token::MEDIUMP: // fall through
         case Token::LOWP: {
-            auto decl = this->varDeclaration();
+            auto decl = this->varDeclarations();
             if (!decl) {
                 return nullptr;
             }
@@ -622,7 +612,7 @@
         }
         case Token::IDENTIFIER:
             if (this->isType(start.fText)) {
-                auto decl = this->varDeclaration();
+                auto decl = this->varDeclarations();
                 if (!decl) {
                     return nullptr;
                 }
@@ -663,9 +653,9 @@
         return nullptr;
     }
     this->nextToken();
-    std::vector<std::unique_ptr<ASTVarDeclaration>> decls; 
+    std::vector<std::unique_ptr<ASTVarDeclarations>> decls; 
     while (this->peek().fKind != Token::RBRACE) {
-        std::unique_ptr<ASTVarDeclaration> decl = this->varDeclaration();
+        std::unique_ptr<ASTVarDeclarations> decl = this->varDeclarations();
         if (!decl) {
             return nullptr;
         }
@@ -788,12 +778,12 @@
             break;
         case Token::CONST:
             initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
-                                                                           this->varDeclaration()));
+                                                                          this->varDeclarations()));
             break;
         case Token::IDENTIFIER: 
             if (this->isType(nextToken.fText)) {
                 initializer = std::unique_ptr<ASTStatement>(new ASTVarDeclarationStatement(
-                                                                           this->varDeclaration()));
+                                                                          this->varDeclarations()));
                 break;
             }
             // fall through