Stage 1 Draft / January 23, 2024

Optional Chaining Assignment

1 Assignment Operators

1.1 Static Semantics: AssignmentTargetType

The syntax-directed operation AssignmentTargetType takes no arguments and returns simple, optional, or invalid. It is defined piecewise over the following productions:

IdentifierReference : Identifier
  1. If this IdentifierReference is contained in strict mode code and StringValue of Identifier is either "eval" or "arguments", return invalid.
  2. Return simple.
IdentifierReference : yield await CallExpression : CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MemberExpression . PrivateIdentifier
  1. Return simple.
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. Return AssignmentTargetType of OptionalChain.
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. Return optional.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. Let expr be the ParenthesizedExpression that is covered by CoverParenthesizedExpressionAndArrowParameterList.
  2. Return AssignmentTargetType of expr.
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CallExpression : CoverCallExpressionAndAsyncArrowHead SuperCall ImportCall CallExpression Arguments CallExpression TemplateLiteral OptionalChain : ?. Arguments ?. TemplateLiteral OptionalChain Arguments OptionalChain TemplateLiteral NewExpression : new NewExpression MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments NewTarget : new . target ImportMeta : import . meta LeftHandSideExpression : OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. Return invalid.

1.2 Static Semantics: Early Errors

AssignmentExpression : LeftHandSideExpression = AssignmentExpression

If LeftHandSideExpression is either an ObjectLiteral or an ArrayLiteral, the following Early Error rules are applied:

If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, the following Early Error rule is applied:

AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression

1.3 Runtime Semantics: Evaluation

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  1. If LeftHandSideExpression is neither an ObjectLiteral nor an ArrayLiteral, then
    1. Let lref be ? Evaluation of LeftHandSideExpression.
    2. If lref is undefined and LeftHandSideExpression is not a ParenthesizedExpression, return undefined.
    3. If IsAnonymousFunctionDefinition(AssignmentExpression) and IsIdentifierRef of LeftHandSideExpression are both true, then
      1. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
    4. Else,
      1. Let rref be ? Evaluation of AssignmentExpression.
      2. Let rval be ? GetValue(rref).
    5. If lref is undefined, throw a TypeError exception.
    6. Perform ? PutValue(lref, rval).
    7. Return rval.
  2. Let assignmentPattern be the AssignmentPattern that is covered by LeftHandSideExpression.
  3. Let rref be ? Evaluation of AssignmentExpression.
  4. Let rval be ? GetValue(rref).
  5. Perform ? DestructuringAssignmentEvaluation of assignmentPattern with argument rval.
  6. Return rval.
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. Let lref be ? Evaluation of LeftHandSideExpression.
  2. If lref is undefined, then
    1. If LeftHandSideExpression is a ParenthesizedExpression, throw a TypeError exception.
    2. Return undefined.
  3. Let lval be ? GetValue(lref).
  4. Let rref be ? Evaluation of AssignmentExpression.
  5. Let rval be ? GetValue(rref).
  6. Let assignmentOpText be the source text matched by AssignmentOperator.
  7. Let opText be the sequence of Unicode code points associated with assignmentOpText in the following table:
    assignmentOpText opText
    **= **
    *= *
    /= /
    %= %
    += +
    -= -
    <<= <<
    >>= >>
    >>>= >>>
    &= &
    ^= ^
    |= |
  8. Let r be ? ApplyStringOrNumericBinaryOperator(lval, opText, rval).
  9. Perform ? PutValue(lref, r).
  10. Return r.
AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
  1. Let lref be ? Evaluation of LeftHandSideExpression.
  2. If lref is undefined, then
    1. If LeftHandSideExpression is a ParenthesizedExpression, throw a TypeError exception.
    2. Return undefined.
  3. Let lval be ? GetValue(lref).
  4. Let lbool be ToBoolean(lval).
  5. If lbool is false, return lval.
  6. If IsAnonymousFunctionDefinition(AssignmentExpression) is true and IsIdentifierRef of LeftHandSideExpression is true, then
    1. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
  7. Else,
    1. Let rref be ? Evaluation of AssignmentExpression.
    2. Let rval be ? GetValue(rref).
  8. Perform ? PutValue(lref, rval).
  9. Return rval.
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. Let lref be ? Evaluation of LeftHandSideExpression.
  2. If lref is undefined, then
    1. If LeftHandSideExpression is a ParenthesizedExpression, throw a TypeError exception.
    2. Return undefined.
  3. Let lval be ? GetValue(lref).
  4. Let lbool be ToBoolean(lval).
  5. If lbool is true, return lval.
  6. If IsAnonymousFunctionDefinition(AssignmentExpression) is true and IsIdentifierRef of LeftHandSideExpression is true, then
    1. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
  7. Else,
    1. Let rref be ? Evaluation of AssignmentExpression.
    2. Let rval be ? GetValue(rref).
  8. Perform ? PutValue(lref, rval).
  9. Return rval.
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. Let lref be ? Evaluation of LeftHandSideExpression.
  2. If lref is undefined, then
    1. If LeftHandSideExpression is a ParenthesizedExpression, throw a TypeError exception.
    2. Return undefined.
  3. Let lval be ? GetValue(lref).
  4. If lval is neither undefined nor null, return lval.
  5. If IsAnonymousFunctionDefinition(AssignmentExpression) is true and IsIdentifierRef of LeftHandSideExpression is true, then
    1. Let rval be ? NamedEvaluation of AssignmentExpression with argument lref.[[ReferencedName]].
  6. Else,
    1. Let rref be ? Evaluation of AssignmentExpression.
    2. Let rval be ? GetValue(rref).
  7. Perform ? PutValue(lref, rval).
  8. Return rval.

A Copyright & Software License

Copyright Notice

© 2024 Nicolò Ribaudo

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.