Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support ES2021 Logical Assignment #953

Merged
merged 1 commit into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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");
Loading