Browse Source

Allow arrow functions to contain 'use strict' for simple parameter lists. Fixes #323.

Dmitry Panov 4 years ago
parent
commit
acd0507c3d
2 changed files with 24 additions and 15 deletions
  1. 11 15
      compiler_expr.go
  2. 13 0
      compiler_test.go

+ 11 - 15
compiler_expr.go

@@ -830,12 +830,7 @@ func (c *compiler) compileParameterBindingIdentifier(name unistring.String, offs
 		c.checkIdentifierName(name, offset)
 		c.checkIdentifierLName(name, offset)
 	}
-	b, unique := c.scope.bindNameShadow(name)
-	if !unique && c.scope.strict {
-		c.throwSyntaxError(offset, "Strict mode function may not have duplicate parameter names (%s)", name)
-		return nil, false
-	}
-	return b, unique
+	return c.scope.bindNameShadow(name)
 }
 
 func (c *compiler) compileParameterPatternIdBinding(name unistring.String, offset int) {
@@ -911,16 +906,17 @@ func (e *compiledFunctionLiteral) emitGetter(putOnStack bool) {
 		if item.Initializer != nil {
 			hasInits = true
 		}
-		if hasPatterns || hasInits || e.isArrow {
-			if firstDupIdx >= 0 {
-				e.c.throwSyntaxError(firstDupIdx, "Duplicate parameter name not allowed in this context")
-				return
-			}
-			if e.strict != nil {
-				e.c.throwSyntaxError(int(e.strict.Idx)-1, "Illegal 'use strict' directive in function with non-simple parameter list")
-				return
-			}
+
+		if firstDupIdx >= 0 && (hasPatterns || hasInits || s.strict || e.isArrow) {
+			e.c.throwSyntaxError(firstDupIdx, "Duplicate parameter name not allowed in this context")
+			return
 		}
+
+		if (hasPatterns || hasInits) && e.strict != nil {
+			e.c.throwSyntaxError(int(e.strict.Idx)-1, "Illegal 'use strict' directive in function with non-simple parameter list")
+			return
+		}
+
 		if !hasInits {
 			length++
 		}

+ 13 - 0
compiler_test.go

@@ -4100,6 +4100,19 @@ func TestCatchParamPattern(t *testing.T) {
 	testScript1(SCRIPT, asciiString("1 2 3"), t)
 }
 
+func TestArrowUseStrict(t *testing.T) {
+	// simple parameter list -- ok
+	_, err := Compile("", "(a) => {'use strict';}", false)
+	if err != nil {
+		t.Fatal(err)
+	}
+	// non-simple parameter list -- syntax error
+	_, err = Compile("", "(a=0) => {'use strict';}", false)
+	if err == nil {
+		t.Fatal("expected error")
+	}
+}
+
 /*
 func TestBabel(t *testing.T) {
 	src, err := ioutil.ReadFile("babel7.js")