Stage 0 Draft / August 1, 2021

ES method extraction (2021)

Introduction

This is the formal specification for a proposed method-extraction operator &. in JavaScript. It modifies the original ECMAScript specification with several new or revised clauses. See the proposal's explainer for the proposal's background, motivation, and usage examples.

1 Syntax-Directed Operations

1.1 Function Name Inference

1.1.1 Static Semantics: IsFunctionDefinition

Editor's Note

This section augments the original IsFunctionDefinition clause.

MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier MemberExpression &. [ Expression ] MemberExpression &. IdentifierName MemberExpression TemplateLiteral
  1. Return false.

1.1.2 Static Semantics: IsIdentifierRef

Editor's Note

This section augments the original IsIdentifierRef clause.

MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier MemberExpression &. [ Expression ] MemberExpression &. IdentifierName MemberExpression &. TemplateLiteral
  1. Return false.

1.2 Contains

Editor's Note

This section augments the original Contains clause.

1.2.1 Static Semantics: Contains

With parameter symbol.

MemberExpression : MemberExpression . IdentifierName MemberExpression &. IdentifierName
  1. If MemberExpression Contains symbol is true, return true.
  2. Return false.
CallExpression : CallExpression . IdentifierName CallExpression &. IdentifierName
  1. If CallExpression Contains symbol is true, return true.
  2. Return false.
OptionalChain : OptionalChain . IdentifierName OptionalChain &. IdentifierName
  1. If OptionalChain Contains symbol is true, return true.
  2. Return false.

1.3 Miscellaneous

1.3.1 Static Semantics: AssignmentTargetType

Editor's Note

This section augments the original AssignmentTargetType clause.

MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments MemberExpression &. [ Expression ] MemberExpression &. IdentifierName
  1. Return invalid.

2 ECMAScript Language: Lexical Grammar

2.1 Punctuators

Editor's Note

This section augments the original Punctuators clause.

OtherPunctuator :: one of { ( ) [ ] . &. ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= =>

3 ECMAScript Language: Expressions

3.1 Left-Hand-Side Expressions

Editor's Note

This section augments the original Left-Hand-Side Expressions clause.

Syntax

MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier MemberExpression[?Yield, ?Await] &. [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] &. IdentifierName MemberExpression[?Yield, ?Await] &. TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier CallExpression[?Yield, ?Await] &. [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] &. IdentifierName CallExpression[?Yield, ?Await] &. TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier OptionalChain[?Yield, ?Await] &. [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] &. IdentifierName OptionalChain[?Yield, ?Await] &. TemplateLiteral[?Yield, ?Await, +Tagged]

3.1.1 Static Semantics

3.1.1.1 Static Semantics: Early Errors

Editor's Note MemberExpression : MemberExpression &. TemplateLiteral
  • It is a Syntax Error if any code matches this production.
Note 1

This production exists in order to prevent automatic semicolon insertion rules (11.9) from being applied to the following code with method extraction:

a&.b
`c`

so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code without method extraction:

a&b
`c`

which is a valid statement and where automatic semicolon insertion does not apply.

CallExpression : CallExpression &. TemplateLiteral
  • It is a Syntax Error if any code matches this production.
Note 2

This production exists in order to prevent automatic semicolon insertion rules (11.9) from being applied to the following code with method extraction:

a()&.b
`c`

so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code without method extraction:

a()&b
`c`

which is a valid statement and where automatic semicolon insertion does not apply.

OptionalChain : OptionalChain &. TemplateLiteral
  • It is a Syntax Error if any code matches this production.
Note 3

This production exists in order to prevent automatic semicolon insertion rules (11.9) from being applied to the following code with method extraction:

a?.()&.b
`c`

so that it would be interpreted as two valid statements. The purpose is to maintain consistency with similar code without method extraction:

a()&b
`c`

which is a valid statement and where automatic semicolon insertion does not apply.

3.1.2 Method Extraction

Editor's Note

This section is a wholly new subclause to be inserted after the new Operator clause.

3.1.2.1 Runtime Semantics: Evaluation

3.1.2.1.1 Runtime Semantics: Evaluation

MemberExpression : MemberExpression &. [ Expression ]
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If the code matched by this MemberExpression is strict mode code, let strict be true; else let strict be false.
  4. Let methodReference be ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict).
  5. Return ExtractMethod(methodReference).
MemberExpression : MemberExpression &. IdentifierName
  1. Let baseReference be the result of evaluating MemberExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If the code matched by this MemberExpression is strict mode code, let strict be true; else let strict be false.
  4. Let methodReference be ? EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict).
  5. Return ExtractMethod(methodReference).
CallExpression : CallExpression &. [ Expression ]
  1. Let baseReference be the result of evaluating CallExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If the code matched by this CallExpression is strict mode code, let strict be true; else let strict be false.
  4. Let methodReference be ? EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict).
  5. Return ExtractMethod(methodReference).
CallExpression : CallExpression &. IdentifierName
  1. Let baseReference be the result of evaluating CallExpression.
  2. Let baseValue be ? GetValue(baseReference).
  3. If the code matched by this CallExpression is strict mode code, let strict be true; else let strict be false.
  4. Let methodReference be ? EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict).
  5. Return ExtractMethod(methodReference).

3.1.2.1.2 ExtractMethod ( methodReference )

The abstract operation ExtractMethod takes argument methodReference (a Reference Record). It performs the following steps when called:

  1. Let method be ? GetValue(methodReference.[[ReferencedName]]).
  2. If IsCallable(method) is false, throw a TypeError exception.
  3. Let F be ? BoundFunctionCreate(method, methodReference.[[Base]], « »).
  4. Let L be 0.
  5. Let methodHasLength be ? HasOwnProperty(method, "length").
  6. If methodHasLength is true, then
    1. Let methodLen be ? Get(method, "length").
    2. If Type(methodLen) is Number, then
      1. If methodLen is +∞𝔽, set L to +∞.
      2. Else if methodLen is -∞𝔽, set L to 0.
      3. Else,
        1. Let methodLenAsInt be ! ToIntegerOrInfinity(methodLen).
        2. Assert: methodLenAsInt is finite.
        3. Set L to max(methodLenAsInt, 0).
  7. Perform ! SetFunctionLength(F, L).
  8. Let methodName be ? Get(method, "name").
  9. If Type(methodName) is not String, set methodName to the empty String.
  10. Perform SetFunctionName(F, methodName, "bound").
  11. Return F.
Note

Function objects created using method extraction are exotic objects. They also do not have a "prototype" property.

3.1.3 Optional Chains

Editor's Note

This section augments the original Optional Chains clause.

3.1.3.1 Runtime Semantics: ChainEvaluation

With parameters baseValue and baseReference.

OptionalChain : OptionalChain &. [ Expression ]
  1. Let optionalChain be OptionalChain.
  2. Let newReference be ? ChainEvaluation of optionalChain with arguments baseValue and baseReference.
  3. Let newValue be ? GetValue(newReference).
  4. If the code matched by this OptionalChain is strict mode code, let strict be true; else let strict be false.
  5. Let methodReference be ? EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict).
  6. Return ExtractMethod(methodReference).
OptionalChain : OptionalChain &. IdentifierName
  1. Let optionalChain be OptionalChain.
  2. Let newReference be ? ChainEvaluation of optionalChain with arguments baseValue and baseReference.
  3. Let newValue be ? GetValue(newReference).
  4. If the code matched by this OptionalChain is strict mode code, let strict be true; else let strict be false.
  5. Let methodReference be ? EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict).
  6. Return ExtractMethod(methodReference).

A Copyright & Software License

Copyright Notice

© 2021 J. S. Choi, Ecma International

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.