Title: [195178] trunk
Revision
195178
Author
[email protected]
Date
2016-01-16 16:04:37 -0800 (Sat, 16 Jan 2016)

Log Message

[ES6] Arrow function syntax. Arrow function should support the destructuring parameters.
https://bugs.webkit.org/show_bug.cgi?id=146934

Patch by Skachkov Oleksandr <[email protected]> on 2016-01-16
Reviewed by Saam Barati.
Source/_javascript_Core:

Added support of destructuring parameters, before arrow function expect only simple parameters,
e.g. (), (x), (x, y) or x in assigment expressio. To support destructuring parameters added
additional check that check for destructuring paramters if check does not pass for simple parameters.

* parser/Parser.cpp:
(JSC::Parser<LexerType>::isArrowFunctionParameters):
(JSC::Parser<LexerType>::parseAssignmentExpression):
* parser/Parser.h:

LayoutTests:

* js/arrowfunction-syntax-errors-expected.txt:
* js/arrowfunction-syntax-expected.txt:
* js/script-tests/arrowfunction-syntax-errors.js:
* js/script-tests/arrowfunction-syntax.js:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (195177 => 195178)


--- trunk/LayoutTests/ChangeLog	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/LayoutTests/ChangeLog	2016-01-17 00:04:37 UTC (rev 195178)
@@ -1,3 +1,15 @@
+2016-01-16  Skachkov Oleksandr  <[email protected]>
+
+        [ES6] Arrow function syntax. Arrow function should support the destructuring parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=146934
+
+        Reviewed by Saam Barati.
+
+        * js/arrowfunction-syntax-errors-expected.txt:
+        * js/arrowfunction-syntax-expected.txt:
+        * js/script-tests/arrowfunction-syntax-errors.js:
+        * js/script-tests/arrowfunction-syntax.js:
+
 2016-01-16  Joseph Pecoraro  <[email protected]>
 
         Web Inspector: Add tests for Array Utilities like lowerBound/upperBound

Modified: trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt (195177 => 195178)


--- trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/LayoutTests/js/arrowfunction-syntax-errors-expected.txt	2016-01-17 00:04:37 UTC (rev 195178)
@@ -123,6 +123,14 @@
 =>y+1 threw exception SyntaxError: Unexpected token '=>'.
 PASS var af3=(x, y)
 =>y+1 threw exception SyntaxError: Unexpected token '=>'.
+PASS ([a, b] => a + b)(["a_", "b_"]) threw exception SyntaxError: Unexpected token '=>'. Expected ')' to end a compound _expression_..
+PASS ({a, b} => a + b)({a:"a_", b:"b_"}) threw exception SyntaxError: Unexpected token '=>'. Expected ')' to end a compound _expression_..
+PASS ({c:a,d:b} => a + b)({c:"a_", d:"b_"}) threw exception SyntaxError: Unexpected token '=>'. Expected ')' to end a compound _expression_..
+PASS ({c:b,d:a} => a + b)({c:"a_", d:"b_"}) threw exception SyntaxError: Unexpected token '=>'. Expected ')' to end a compound _expression_..
+PASS var arr1 = [a, b] => a + b; threw exception SyntaxError: Unexpected token '=>'. Expected ';' after variable declaration..
+PASS var arr2 = {a, b} => a + b; threw exception SyntaxError: Unexpected token '=>'. Expected ';' after variable declaration..
+PASS var arr3 = {c:a,d:b} => a + b; threw exception SyntaxError: Unexpected token '=>'. Expected ';' after variable declaration..
+PASS var arr3 = {c:b,d:a} => a + b; threw exception SyntaxError: Unexpected token '=>'. Expected ';' after variable declaration..
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/arrowfunction-syntax-expected.txt (195177 => 195178)


--- trunk/LayoutTests/js/arrowfunction-syntax-expected.txt	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/LayoutTests/js/arrowfunction-syntax-expected.txt	2016-01-17 00:04:37 UTC (rev 195178)
@@ -40,6 +40,22 @@
 PASS (function funcSelfExecAE2(value) { var f = x => { x++; return x + 1; }; return f(value);})(123); is 125
 PASS (function funcSelfExecAE3(value) { var f = (x) => { x++; return x + 1; }; return f(value);})(123); is 125
 PASS (function funcSelfExecAE4(value) { var f = (x, y) => { x++; return x + y; }; return f(value, value * 2);})(123); is 370
+PASS (([a, b]) => a + b)(["a_", "b_"]) is "a_b_"
+PASS (({a, b}) => a + b)({a:"a_", b:"b_"}) is "a_b_"
+PASS (({c:a, d:b}) => a + b)({c:"a_", d:"b_"}) is "a_b_"
+PASS (({c:b, d:a}) => a + b)({c:"a_", d:"b_"}) is "b_a_"
+PASS ((x, y, {c:b, d:a}) => x + y + a + b)("x_", "y_", {c:"a_", d:"b_"}) is "x_y_b_a_"
+PASS (({c:b, d:a}, x, y) => x + y + a + b)({c:"a_", d:"b_"}, "x_", "y_") is "x_y_b_a_"
+PASS ((x, y, {c:b, d:a}, [e, f]) => x + y + a + b + e + f)("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"]) is "x_y_b_a_e_f_"
+PASS ((x, y, {c:b, d:a}, [e, f], ...theArgs) => x + y + a + b + e + f + theArgs[0] + theArgs[1])("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"], "g_", "h_") is "x_y_b_a_e_f_g_h_"
+PASS arr1(["a_", "b_"]) is "a_b_"
+PASS arr2({a:"a_", b:"b_"}) is "a_b_"
+PASS arr3({c:"a_", d:"b_"}) is "a_b_"
+PASS arr4({c:"a_", d:"b_"}) is "b_a_"
+PASS arr5("x_", "y_", {c:"a_", d:"b_"}) is "x_y_b_a_"
+PASS arr6({c:"a_", d:"b_"}, "x_", "y_") is "x_y_b_a_"
+PASS arr7("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"]) is "x_y_b_a_e_f_"
+PASS arr8("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"], "g_", "h_") is "x_y_b_a_e_f_g_h_"
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/script-tests/arrowfunction-syntax-errors.js (195177 => 195178)


--- trunk/LayoutTests/js/script-tests/arrowfunction-syntax-errors.js	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/LayoutTests/js/script-tests/arrowfunction-syntax-errors.js	2016-01-17 00:04:37 UTC (rev 195178)
@@ -38,4 +38,14 @@
 shouldThrow("var af2=(y)\n=>y+1");
 shouldThrow("var af3=(x, y)\n=>y+1");
 
+shouldThrow('([a, b] => a + b)(["a_", "b_"])' );
+shouldThrow('({a, b} => a + b)({a:"a_", b:"b_"})');
+shouldThrow('({c:a,d:b} => a + b)({c:"a_", d:"b_"})');
+shouldThrow('({c:b,d:a} => a + b)({c:"a_", d:"b_"})');
+
+shouldThrow('var arr1 = [a, b] => a + b;');
+shouldThrow('var arr2 = {a, b} => a + b;');
+shouldThrow('var arr3 = {c:a,d:b} => a + b;');
+shouldThrow('var arr3 = {c:b,d:a} => a + b;');
+
 var successfullyParsed = true;

Modified: trunk/LayoutTests/js/script-tests/arrowfunction-syntax.js (195177 => 195178)


--- trunk/LayoutTests/js/script-tests/arrowfunction-syntax.js	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/LayoutTests/js/script-tests/arrowfunction-syntax.js	2016-01-17 00:04:37 UTC (rev 195178)
@@ -79,4 +79,37 @@
 
 shouldBe('(function funcSelfExecAE4(value) { var f = (x, y) => { x++; return x + y; }; return f(value, value * 2);})(123);', '370');
 
+shouldBe('(([a, b]) => a + b)(["a_", "b_"])', '"a_b_"');
+shouldBe('(({a, b}) => a + b)({a:"a_", b:"b_"})', '"a_b_"');
+shouldBe('(({c:a, d:b}) => a + b)({c:"a_", d:"b_"})', '"a_b_"');
+shouldBe('(({c:b, d:a}) => a + b)({c:"a_", d:"b_"})', '"b_a_"');
+shouldBe('((x, y, {c:b, d:a}) => x + y + a + b)("x_", "y_", {c:"a_", d:"b_"})', '"x_y_b_a_"');
+shouldBe('(({c:b, d:a}, x, y) => x + y + a + b)({c:"a_", d:"b_"}, "x_", "y_")', '"x_y_b_a_"');
+shouldBe('((x, y, {c:b, d:a}, [e, f]) => x + y + a + b + e + f)("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"])', '"x_y_b_a_e_f_"');
+shouldBe('((x, y, {c:b, d:a}, [e, f], ...theArgs) => x + y + a + b + e + f + theArgs[0] + theArgs[1])("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"], "g_", "h_")', '"x_y_b_a_e_f_g_h_"');
+
+var arr1 = ([a, b]) => a + b;
+shouldBe('arr1(["a_", "b_"])', '"a_b_"');
+
+var arr2 = ({a, b}) => a + b;
+shouldBe('arr2({a:"a_", b:"b_"})', '"a_b_"');
+
+var arr3 = ({c:a, d:b}) => a + b;
+shouldBe('arr3({c:"a_", d:"b_"})', '"a_b_"');
+
+var arr4 = ({c:b, d:a}) => a + b;
+shouldBe('arr4({c:"a_", d:"b_"})', '"b_a_"');
+
+var arr5 = (x, y, {c:b, d:a}) => x + y + a + b;
+shouldBe('arr5("x_", "y_", {c:"a_", d:"b_"})', '"x_y_b_a_"');
+
+var arr6 = ({c:b, d:a}, x, y) => x + y + a + b;
+shouldBe('arr6({c:"a_", d:"b_"}, "x_", "y_")', '"x_y_b_a_"');
+
+var arr7 = (x, y, {c:b, d:a}, [e, f]) => x + y + a + b + e + f;
+shouldBe('arr7("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"])', '"x_y_b_a_e_f_"');
+
+var arr8 = (x, y, {c:b, d:a}, [e, f], ...theArgs) => x + y + a + b + e + f + theArgs[0] + theArgs[1];
+shouldBe('arr8("x_", "y_", {c:"a_", d:"b_"}, ["e_", "f_"], "g_", "h_")', '"x_y_b_a_e_f_g_h_"');
+
 var successfullyParsed = true;

Modified: trunk/Source/_javascript_Core/ChangeLog (195177 => 195178)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-17 00:04:37 UTC (rev 195178)
@@ -1,3 +1,19 @@
+2016-01-16  Skachkov Oleksandr  <[email protected]>
+
+        [ES6] Arrow function syntax. Arrow function should support the destructuring parameters.
+        https://bugs.webkit.org/show_bug.cgi?id=146934
+
+        Reviewed by Saam Barati.
+        
+        Added support of destructuring parameters, before arrow function expect only simple parameters,
+        e.g. (), (x), (x, y) or x in assigment expressio. To support destructuring parameters added
+        additional check that check for destructuring paramters if check does not pass for simple parameters.
+
+        * parser/Parser.cpp:
+        (JSC::Parser<LexerType>::isArrowFunctionParameters):
+        (JSC::Parser<LexerType>::parseAssignmentExpression):
+        * parser/Parser.h:
+
 2016-01-15  Benjamin Poulain  <[email protected]>
 
         [JSC] Legalize Memory Offsets for ARM64 before lowering to Air

Modified: trunk/Source/_javascript_Core/parser/Parser.cpp (195177 => 195178)


--- trunk/Source/_javascript_Core/parser/Parser.cpp	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/Source/_javascript_Core/parser/Parser.cpp	2016-01-17 00:04:37 UTC (rev 195178)
@@ -374,6 +374,49 @@
 }
 
 template <typename LexerType>
+bool Parser<LexerType>::isArrowFunctionParameters()
+{
+    bool isArrowFunction = false;
+
+    if (match(EOFTOK))
+        return false;
+    
+    bool isOpenParen = match(OPENPAREN);
+    bool isIdent = match(IDENT);
+    
+    if (!isOpenParen && !isIdent)
+        return false;
+
+    SavePoint saveArrowFunctionPoint = createSavePoint();
+        
+    if (isIdent) {
+        next();
+        isArrowFunction = match(ARROWFUNCTION);
+    } else {
+        RELEASE_ASSERT(isOpenParen);
+        next();
+        if (match(CLOSEPAREN)) {
+            next();
+            isArrowFunction = match(ARROWFUNCTION);
+        } else {
+            SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
+            // We make fake scope, otherwise parseFormalParameters will add variable to current scope that lead to errors
+            AutoPopScopeRef fakeScope(this, pushScope());
+            fakeScope->setSourceParseMode(SourceParseMode::ArrowFunctionMode);
+                
+            unsigned parametersCount = 0;
+            isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
+                
+            popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
+        }
+    }
+        
+    restoreSavePoint(saveArrowFunctionPoint);
+        
+    return isArrowFunction;
+}
+
+template <typename LexerType>
 bool Parser<LexerType>::allowAutomaticSemicolon()
 {
     return match(CLOSEBRACE) || match(EOFTOK) || m_lexer->prevTerminator();
@@ -2887,7 +2930,7 @@
 #endif
 
 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
-    if (isArrowFunctionParamters())
+    if (isArrowFunctionParameters())
         return parseArrowFunctionExpression(context);
 #endif
     

Modified: trunk/Source/_javascript_Core/parser/Parser.h (195177 => 195178)


--- trunk/Source/_javascript_Core/parser/Parser.h	2016-01-17 00:00:43 UTC (rev 195177)
+++ trunk/Source/_javascript_Core/parser/Parser.h	2016-01-17 00:04:37 UTC (rev 195178)
@@ -1027,41 +1027,7 @@
     {
         return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator();
     }
-    
-    ALWAYS_INLINE bool isArrowFunctionParamters()
-    {
-        bool isArrowFunction = false;
-        
-        if (match(EOFTOK))
-            return isArrowFunction;
-        
-        SavePoint saveArrowFunctionPoint = createSavePoint();
-        
-        if (consume(OPENPAREN)) {
-            bool isArrowFunctionParamters = true;
-            
-            while (consume(IDENT)) {
-                if (consume(COMMA)) {
-                    if (!match(IDENT)) {
-                        isArrowFunctionParamters = false;
-                        break;
-                    }
-                } else
-                    break;
-            }
-            
-            if (isArrowFunctionParamters) {
-                if (consume(CLOSEPAREN) && match(ARROWFUNCTION))
-                    isArrowFunction = true;
-            }
-        } else if (consume(IDENT) && match(ARROWFUNCTION))
-            isArrowFunction = true;
 
-        restoreSavePoint(saveArrowFunctionPoint);
-        
-        return isArrowFunction;
-    }
-    
     ALWAYS_INLINE unsigned tokenStart()
     {
         return m_token.m_location.startOffset;
@@ -1258,6 +1224,8 @@
     enum class FunctionDefinitionType { _expression_, Declaration, Method };
     template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType);
     
+    ALWAYS_INLINE bool isArrowFunctionParameters();
+    
     template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, SourceParseMode, ParserFunctionInfo<TreeBuilder>&);
     template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to