ES6 class syntax should use block scoping
https://bugs.webkit.org/show_bug.cgi?id=142567

Reviewed by Geoffrey Garen.

Source/JavaScriptCore:

We treat class declarations like we do "let" declarations.
The class name is under TDZ until the class declaration
statement is evaluated. Class declarations also follow
the same rules as "let": No duplicate definitions inside
a lexical environment.

* parser/ASTBuilder.h:
(JSC::ASTBuilder::createClassDeclStatement):
* parser/Parser.cpp:
(JSC::Parser<LexerType>::parseClassDeclaration):
* tests/stress/class-syntax-block-scoping.js: Added.
(assert):
(truth):
(.):
* tests/stress/class-syntax-definition-semantics.js: Added.
(shouldBeSyntaxError):
(shouldNotBeSyntaxError):
(truth):
* tests/stress/class-syntax-tdz.js:
(assert):
(shouldThrowTDZ):
(truth):
(.):

LayoutTests:

* js/class-constructor-return-expected.txt:
* js/class-syntax-call-expected.txt:
* js/class-syntax-declaration-expected.txt:
* js/class-syntax-default-constructor-expected.txt:
* js/class-syntax-extends-expected.txt:
* js/class-syntax-name-expected.txt:
* js/class-syntax-super-expected.txt:
* js/script-tests/class-constructor-return.js:
(shouldThrow):
(shouldNotThrow):
(shouldBeTrue):
(shouldBeFalse):
* js/script-tests/class-syntax-call.js:
(A):
(B):
(shouldThrow):
(shouldNotThrow):
* js/script-tests/class-syntax-declaration.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
* js/script-tests/class-syntax-default-constructor.js:
(shouldThrow):
(shouldBe):
(shouldBeTrue):
(assert):
(A):
(B):
* js/script-tests/class-syntax-extends.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(Base):
(Base.prototype.baseMethod):
* js/script-tests/class-syntax-name.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(runTestShouldBe):
* js/script-tests/class-syntax-super.js:
(shouldThrow):
(shouldNotThrow):
(shouldBe):
(shouldBeTrue):
(shouldBeFalse):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@187680 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js b/Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js
new file mode 100644
index 0000000..f3526f9
--- /dev/null
+++ b/Source/JavaScriptCore/tests/stress/class-syntax-block-scoping.js
@@ -0,0 +1,49 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Assertion failure");
+}
+noInline(assert);
+
+function truth() { return true; }
+noInline(truth);
+
+const NUM_LOOPS = 1000;
+
+;(function() {
+    function foo() {
+        let first;
+        let second;
+        class A {};
+        first = A;
+        if (truth()) {
+            class A {};
+            second = A;
+        }
+        assert(first !== second);
+    }
+    function baz() {
+        class A { static hello() { return 10; } };
+        assert(A.hello() === 10);
+        if (truth()) {
+            class A { static hello() { return 20; } };
+            assert(A.hello() === 20);
+        }
+        assert(A.hello() === 10);
+    }
+    function bar() {
+        class A { static hello() { return 10; } };
+        let capA = function() { return A; }
+        assert(A.hello() === 10);
+        if (truth()) {
+            class A { static hello() { return 20; } };
+            let capA = function() { return A; }
+            assert(A.hello() === 20);
+        }
+        assert(A.hello() === 10);
+    }
+    for (let i = 0; i < NUM_LOOPS; i++) {
+        foo();
+        bar();
+        baz();
+    }
+})();