Skip to content

Commit

Permalink
Support ES2021 Logical Assignment
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Aug 29, 2021
1 parent 71de331 commit 2177758
Show file tree
Hide file tree
Showing 65 changed files with 1,690 additions and 32 deletions.
39 changes: 39 additions & 0 deletions Jint.Tests.Test262/Language/Expressions/LogicalTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using Xunit;

namespace Jint.Tests.Test262.Language.Expressions
{
public class LogicalTests : Test262Test
{
[Theory(DisplayName = "language\\expressions\\logical-and")]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-and", false)]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-and", true, Skip = "Skipped")]
protected void LogicalAnd(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}

[Theory(DisplayName = "language\\expressions\\logical-assignment")]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-assignment", false)]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-assignment", true, Skip = "Skipped")]
protected void LogicalAssignment(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}

[Theory(DisplayName = "language\\expressions\\logical-not")]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-not", false)]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-not", true, Skip = "Skipped")]
protected void LogicalNot(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}

[Theory(DisplayName = "language\\expressions\\logical-or")]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-or", false)]
[MemberData(nameof(SourceFiles), "language\\expressions\\logical-or", true, Skip = "Skipped")]
protected void LogicalOr(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (C) 2020 Rick Waldron. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators
description: >
Strict Mode - SyntaxError is thrown if the identifier arguments
appear as the LeftHandSideExpression of a Logical Assignment
operator(&&=)
flags: [onlyStrict]
negative:
phase: parse
type: SyntaxError
features: [logical-assignment-operators]
---*/
$DONOTEVALUATE();

arguments &&= 20;
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: Logical And Assignment Operator
features: [BigInt, logical-assignment-operators]
info: |
AssignmentExpression:
LeftHandSideExpression &&= AssignmentExpression
1. Let lref be the result of evaluating LeftHandSideExpression.
2. Let lval be ? GetValue(lref).
3. Let lbool be ! ToBoolean(lval).
4. If lbool is false, return lval.
5. Let rref be the result of evaluating AssignmentExpression.
6. Let rval be ? GetValue(rref).
7. Perform ? PutValue(lref, rval).
8. Return rval.
---*/

var value = 0n;
assert.sameValue(value &&= 1n, 0n, "(value &&= 1n) === 0n; where value = 0n");

value = 2n;
assert.sameValue(value &&= 1n, 1n, "(value &&= 1n) === 1n; where value = 2n");
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
The LeftHandSideExpression is evaluated before the AssignmentExpression.
features: [logical-assignment-operators]
---*/

function DummyError() { }

assert.throws(DummyError, function() {
var base = null;
var prop = function() {
throw new DummyError();
};
var expr = function() {
throw new Test262Error("right-hand side expression evaluated");
};

base[prop()] &&= expr();
});

assert.throws(TypeError, function() {
var base = null;
var prop = {
toString: function() {
throw new Test262Error("property key evaluated");
}
};
var expr = function() {
throw new Test262Error("right-hand side expression evaluated");
};

base[prop] &&= expr();
});

var count = 0;
var obj = {};
function incr() {
return ++count;
}

assert.sameValue(obj[incr()] &&= incr(), undefined, "obj[incr()] &&= incr()");
assert.sameValue(obj[1], undefined, "obj[1]");
assert.sameValue(count, 1, "count");

obj[2] = 1;
assert.sameValue(obj[incr()] &&= incr(), 3, "obj[incr()] &&= incr()");
assert.sameValue(obj[2], 3, "obj[2]");
assert.sameValue(count, 3, "count");
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: NamedEvaluation of Logical And Assignment
info: |
AssignmentExpression:
LeftHandSideExpression &&= AssignmentExpression
5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
features: [logical-assignment-operators]
---*/

var value = 1;
value &&= () => {};

assert.sameValue(value.name, "value", "value");
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: NamedEvaluation of Logical And Assignment
info: |
AssignmentExpression:
LeftHandSideExpression &&= AssignmentExpression
5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
features: [logical-assignment-operators]
---*/

var value = 1;
value &&= class {};

assert.sameValue(value.name, "value", "value");
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: NamedEvaluation of Logical And Assignment
info: |
AssignmentExpression:
LeftHandSideExpression &&= AssignmentExpression
5. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
a. Let rval be NamedEvaluation of AssignmentExpression with argument GetReferencedName(lref).
features: [logical-assignment-operators]
---*/

var value = 1;
value &&= function() {};

assert.sameValue(value.name, "value", "value");
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
Assignment operator(&&=) is a reference to a data property with the
attribute value {[[Set]]:undefined} and PutValue step is reached.
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

var obj = {};
Object.defineProperty(obj, "prop", {
get: function() {
return 2;
},
set: undefined,
enumerable: true,
configurable: true
});

assert.throws(TypeError, function() {
obj.prop &&= 1;
});
assert.sameValue(obj.prop, 2, "obj.prop");
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
Assignment operator(&&=) is a reference to a data property with the
attribute value {[[Set]]:undefined} and PutValue step is not reached.
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

var obj = {};
Object.defineProperty(obj, "prop", {
get: function() {
return 0;
},
set: undefined,
enumerable: true,
configurable: true
});

assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
Strict Mode - TypeError is not thrown if The LeftHandSide of a Logical
Assignment operator(&&=) is a reference to a non-existent property of an
object whose [[Extensible]] internal property is false.
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

var obj = {};
Object.preventExtensions(obj);

obj.prop &&= 1;
assert.sameValue(obj.prop, undefined, "obj.prop");
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-static-semantics-early-errors
description: >
It is a Syntax Error if AssignmentTargetType of LeftHandSideExpression is
not simple.
negative:
phase: parse
type: SyntaxError
features: [logical-assignment-operators]
---*/

$DONOTEVALUATE();

function test() {}
test() &&= 1;
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
Strict Mode - TypeError is thrown if the LeftHandSide of a Logical
Assignment operator(&&=) is a reference to a data property with the
attribute value {[[Writable]]:false} and PutValue step is reached.
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

var obj = {};
Object.defineProperty(obj, "prop", {
value: 2,
writable: false,
enumerable: true,
configurable: true
});

assert.throws(TypeError, function() {
obj.prop &&= 1;
});
assert.sameValue(obj.prop, 2, "obj.prop");
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
Strict Mode - TypeError is not thrown if the LeftHandSide of a Logical
Assignment operator(&&=) is a reference to a data property with the
attribute value {[[Writable]]:false} and PutValue step is not reached.
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

var obj = {};
Object.defineProperty(obj, "prop", {
value: 0,
writable: false,
enumerable: true,
configurable: true
});

assert.sameValue(obj.prop &&= 1, 0, "obj.prop");
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
ReferenceError is thrown if the LeftHandSideExpression of a Logical
Assignment operator(&&=) evaluates to an unresolvable reference
flags: [onlyStrict]
features: [logical-assignment-operators]
---*/

assert.throws(ReferenceError, function() {
unresolved &&= 1;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2020 Ecma International. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.

/*---
esid: sec-assignment-operators-runtime-semantics-evaluation
description: >
ReferenceError is thrown if the AssignmentExpression of a Logical
Assignment operator(&&=) evaluates to an unresolvable reference and the
AssignmentExpression is evaluated.
features: [logical-assignment-operators]
---*/

var value = 2;

assert.throws(ReferenceError, function() {
value &&= unresolved;
});
assert.sameValue(value, 2, "value");

0 comments on commit 2177758

Please sign in to comment.