Decorators Proposal - ECMAScript

Table of Contents

  1. Introduction
  2. 1 Terms
    1. 1.1 Decorator
    2. 1.2 Class Decorator Function
    3. 1.3 Property/Method Decorator Function
    4. 1.4 Decorator Factory
  3. 2 Decorator Targets
  4. 3 Decorator Evaluation and Application Order
  5. 4 Abstract Operations
    1. 4.1 Decorator Operations
      1. 4.1.1 Decorate ( Decorators, O, P, desc )
      2. 4.1.2 DecorateConstructor ( Decorators, F )
      3. 4.1.3 DecorateProperty ( Decorators, O, P, desc )
    2. 4.2 Operations on Objects
      1. 4.2.1 CreateListFromIterator ( iterator [, elementTypes] )
      2. 4.2.2 GetOrCreateMetadataMap ( O, P, Create )
      3. 4.2.3 [[HasMetadata]] ( MetadataKey, P )
      4. 4.2.4 OrdinaryHasMetadata ( MetadataKey, O, P )
      5. 4.2.5 [[HasOwnMetadata]] ( MetadataKey, P )
      6. 4.2.6 OrdinaryHasOwnMetadata ( MetadataKey, O, P )
      7. 4.2.7 [[GetMetadata]] ( MetadataKey, P )
      8. 4.2.8 OrdinaryGetMetadata ( MetadataKey, O, P )
      9. 4.2.9 [[GetOwnMetadata]] ( MetadataKey, P, ParamIndex )
      10. 4.2.10 OrdinaryGetOwnMetadata ( MetadataKey, O, P )
      11. 4.2.11 [[DefineOwnMetadata]] ( MetadataKey, MetadataValue, P )
      12. 4.2.12 OrdinaryDefineOwnMetadata ( MetadataKey, MetadataValue, O, P )
      13. 4.2.13 [[MetadataKeys]] ( P )
      14. 4.2.14 OrdinaryMetadataKeys ( O, P )
      15. 4.2.15 [[OwnMetadataKeys]] ( P )
      16. 4.2.16 OrdinaryOwnMetadataKeys ( O, P )
      17. 4.2.17 [[DeleteMetadata]]( MetadataKey, P )
  6. 5 Reflection
    1. 5.1 The Reflect Object
      1. 5.1.1 Metadata Decorator Functions
      2. 5.1.2 Reflect.decorate ( decorators, target, propertyKey, attributes )
      3. 5.1.3 Reflect.metadata ( metadataKey, metadataValue )
      4. 5.1.4 Reflect.defineMetadata ( metadataKey, metadataValue, target, propertyKey )
      5. 5.1.5 Reflect.hasMetadata ( metadataKey, target, propertyKey )
      6. 5.1.6 Reflect.hasOwnMetadata ( metadataKey, target, propertyKey )
      7. 5.1.7 Reflect.getMetadata ( metadataKey, target, propertyKey )
      8. 5.1.8 Reflect.getOwnMetadata ( metadataKey, target, propertyKey )
      9. 5.1.9 Reflect.getMetadataKeys ( target, propertyKey )
      10. 5.1.10 Reflect.getOwnMetadataKeys ( target, propertyKey )
      11. 5.1.11 Reflect.deleteMetadata ( metadataKey, target, propertyKey )
  7. A Grammar
    1. A.1 Expressions
    2. A.2 Functions and Classes
    3. A.3 Scripts and Modules

Introduction

Proposal to add Decorators to ECMAScript.

For the TypeScript specific proposal, see http://rbuckton.github.io/reflectdecorators/typescript.html

1Terms

1.1Decorator

NoteThis section is non-normative.

A decorator is an expression that is evaluated after a class has been defined, that can be used to annotate or modify the class in some fashion. This expression must evaluate to a function, which is executed by the runtime to apply the decoration.

@decoratorExpression
class C {
}

1.2Class Decorator Function

NoteThis section is non-normative.

A class decorator function is a function that accepts a constructor function as its argument, and returns either undefined, the provided constructor function, or a new constructor function. Returning undefined is equivalent to returning the provided constructor function.

// A class decorator function
function dec(target) {  
 // modify, annotate, or replace target...
}

1.3Property/Method Decorator Function

NoteThis section is non-normative.

A property decorator function is a function that accepts three arguments: The object that owns the property, the key for the property (a string or a symbol), and optionally the property descriptor of the property. The function must return either undefined, the provided property descriptor, or a new property descriptor. Returning undefined is equivalent to returning the provided property descriptor.

// A property (or method/accessor) decorator function
function dec(target, key, descriptor) {
  // annotate the target and key; or modify or replace the descriptor...
}
    

1.4Decorator Factory

NoteThis section is non-normative.

A decorator factory is a function that can accept any number of arguments, and must return one of the above types of decorator function.

// a class decorator factory function
function dec(x, y) {
  // the class decorator function
  return function (target) {
      // modify, annotate, or replace target...
  }
}

2Decorator Targets

NoteThis section is non-normative.

A decorator can be legally applied to any of the following:

Please note that a decorator currently cannot be legally applied to any of the following:

This list may change in the future.

3Decorator Evaluation and Application Order

NoteThis section is non-normative.

Decorators are evaluated in the order they appear preceeding their target declaration, to preserve side-effects due to evaluation order. Decorators are applied to their target declaration in reverse order, starting with the decorator closest to the declaration. This behavior is specified to preserve the expected behavior of decorators without a declarative syntax.

@F
@G
class C {   
}

For example, the above listing could be approximately written without decorators in the following fashion:

C = F(G(C))

In the above example, the expression F is evaluated first, followed by the expression G. G is then called with the constructor function as its argument, followed by calling F with the result. The actual process of applying decorators is more complex than the above example however, though you may still imperatively apply decorators with a reflection API.

If a class declaration has decorators on both the class and any of its members or parameters, the decorators are applied using the following pseudocode:

for each member M of class C
  if M is an accessor then
      let accessor = first accessor (get or set, in declaration order) of M
      let memberDecorators = decorators of accessor
      for each parameter of accessor
          let paramDecorators = decorators of parameter           
          let paramIndex = ordinal index of parameter
          Reflect.decorate(paramDecorators, accessor, paramIndex)
      next parameter

      let accessor = second accessor (get or set, in declaration order) of M
      if accessor then
          let memberDecorators = memberDecorators + decorators of accessor
          for each parameter of accessor
              let paramDecorators = decorators of parameter           
              let paramIndex = ordinal index of parameter
              Reflect.decorate(paramDecorators, accessor, paramIndex)
          next parameter
      end if
  else if M is a method
      let memberDecorators = decorators of M
      for each parameter of M
          let paramDecorators = decorators of parameter           
          let paramIndex = ordinal index of parameter
          Reflect.decorate(paramDecorators, M, paramIndex)
      next parameter
  else
      let memberDecorators = decorators of M
  end if

  let name = name of M
  let target = C.prototype if M is on the prototype; otherwise, C if M is static  
  Reflect.decorate(memberDecorators, C, name)
next member

for each parameter of C
  let paramDecorators = decorators of parameter
  let paramIndex = ordinal index of parameter
  Reflect.decorate(paramDecorators, C, paramIndex)
next parameter

let classDecorators = decorators of C
let C = Reflect.decorate(classDecorators, C)
  

4Abstract Operations

4.1Decorator Operations

4.1.1Decorate ( Decorators, O, P, desc )

When the abstract operation Decorate is called with ECMAScript language value Decorators, Object O, property key P, and property descriptor desc, the following steps are taken:

  1. If P is undefined and desc is undefined, then
    1. If IsCallable(O) is not true, throw a TypeError exception.
    2. Return DecorateConstructor(Decorators, O).
  2. Else
    1. Return DecorateProperty(Decorators, O, P, desc).

4.1.2DecorateConstructor ( Decorators, F )

When the abstract operation DecorateConstructor is called with ECMAScript language value Decorators and Object F, the following steps are taken:

  1. Let result be F.
  2. Let iterator be GetIterator(Decorators).
  3. Let list be CreateListFromIterator(iterator, «Object»).
  4. For each decorator in list in reverse order
    1. Let decorated be Call(decorator, null, result).
    2. ReturnIfAbrupt(decorated).
    3. If IsCallable(decorated), then
      1. Set result to be decorated.
    4. Else if decorated is not undefined, throw a TypeError exception.

4.1.3DecorateProperty ( Decorators, O, P, desc )

When the abstract operation DecorateProperty is called with ECMAScript language value Decorators, Object O, property key P, and property descriptor desc, the following steps are taken:

  1. Let result be desc.
  2. Let key be ToPropertyKey(P).
  3. Let iterator be GetIterator(Decorators).
  4. Let list be CreateListFromIterator(iterator, «Object»).
  5. For each decorator in list in reverse order
    1. Let decorated be Call(decorator, null, O, key, result).
    2. ReturnIfAbrupt(decorated).
    3. If Type(decorated) is Object, then
      1. Set result to be decorated.
    4. Else if decorated is not undefined, throw a TypeError exception.

4.2Operations on Objects

4.2.1CreateListFromIterator ( iterator [, elementTypes] )

When the abstract operation CreateListFromIterator is called with ECMAScript language value iterator, the following steps are taken:

  1. ReturnIfAbrupt(iterator).
  2. If elementTypes was not passed, let elementTypes be (Undefined, Null, Boolean, String, Symbol, Number, Object).
  3. Let list be an empty List.
  4. Repeat
    1. Let next be IteratorStep(iterator).
    2. ReturnIfAbrupt(next).
    3. If next is false, return list.
    4. Let nextValue be IteratorValue(next).
    5. ReturnIfAbrupt(nextValue).
    6. If Type(nextValue) is not an element of elementTypes, then
      1. Return IteratorClose(iterator, Completion{[[type]]: throw, [[value]]: a newly created TypeError object, [[target]: empty}).
    7. Append nextValue as the last element of list.

4.2.2GetOrCreateMetadataMap ( O, P, Create )

When the abstract operation GetOrCreateMetadataMap is called with Object O, property key P, and Boolean Create the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let metadataMap be undefined.
  3. Let succeeded be true.
  4. Let targetMetadata be the value of O's [[Metadata]] internal slot.
  5. If targetMetadata is undefined, then
    1. If Create is false, return undefined.
    2. Set targetMetadata to be a newly created Map object.
    3. Set the [[Metadata]] internal slot of O to targetMetadata.
  6. Let metadataMap be Invoke(targetMetadata, "get", P).
  7. ReturnIfAbrupt(metadataMap).
  8. If metadataMap is undefined, then
    1. If Create is false, return undefined.
    2. Set metadataMap to be a newly created Map object.
    3. Let setStatus be Invoke(targetMetadata, "set", P, metadataMap).
    4. ReturnIfAbrupt(setStatus).
  9. Return metadataMap.

4.2.3[[HasMetadata]] ( MetadataKey, P )

When the [[HasMetadata]] internal method of O is called with ECMAScript language value MetadataKey and property key P, the following steps are taken:

  1. Return OrdinaryHasMetadata(MetadataKey, O, P).

4.2.4OrdinaryHasMetadata ( MetadataKey, O, P )

When the abstract operation OrdinaryHasMetadata is called with ECMAScript language value MetadataKey, Object O, and property key P, the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let hasOwn be OrdinaryHasOwnMetadata(MetadataKey, O, P).
  3. If hasOwn is true, return true.
  4. Let parent be O.[[GetPrototypeOf]]().
  5. ReturnIfAbrupt(parent).
  6. If parent is not null, then
    1. return parent.[[HasMetadata]](MetadataKey, P).
  7. Return false.

4.2.5[[HasOwnMetadata]] ( MetadataKey, P )

When the [[HasOwnMetadata]] internal method of O is called with ECMAScript language value MetadataKey and property key P, the following steps are taken:

  1. Return OrdinaryHasOwnMetadata(MetadataKey, O, P).

4.2.6OrdinaryHasOwnMetadata ( MetadataKey, O, P )

When the abstract operation OrdinaryHasOwnMetadata is called with ECMAScript language value MetadataKey, Object O, and property key P, the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let metadataMap be GetOrCreateMetadataMap(O, P, false).
  3. ReturnIfAbrupt(metadataMap).
  4. If metadataMap is undefined, return false.
  5. Return Invoke(metadataMap, "has", MetadataKey).

4.2.7[[GetMetadata]] ( MetadataKey, P )

When the [[GetMatadata]] internal method of O is called with ECMAScript language value MetadataKey and property key P, the following steps are taken:

  1. Return OrdinaryGetMetadata(MetadataKey, O, P).

4.2.8OrdinaryGetMetadata ( MetadataKey, O, P )

When the abstract operation OrdinaryGetMetadata is called with ECMAScript language value MetadataKey, Object O, and property key P, the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let hasOwn be OrdinaryHasOwnMetadata(MetadataKey, O, P).
  3. If hasOwn is true, then
    1. return OrdinaryGetOwnMetadata(MetadataKey, O, P).
  4. Let parent be O.[[GetPrototypeOf]]().
  5. ReturnIfAbrupt(parent).
  6. If parent is not null, then
    1. return parent.[[GetMetadata]](MetadataKey, P).
  7. Return undefined.

4.2.9[[GetOwnMetadata]] ( MetadataKey, P, ParamIndex )

When the [[GetOwnMetadata]] internal method of O is called with ECMAScript language value MetadataKey and property key P, the following steps are taken:

  1. Return OrdinaryGetOwnMetadata(MetadataKey, O, P).

4.2.10OrdinaryGetOwnMetadata ( MetadataKey, O, P )

When the abstract operation OrdinaryGetOwnMetadata is called with ECMAScript language value MetadataKey, Object O, and property key P, the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let metadataMap be GetOrCreateMetadataMap(O, P, false).
  3. ReturnIfAbrupt(metadataMap).
  4. If metadataMap is undefined, return undefined.
  5. Return Invoke(metadataMap, "get", MetadataKey).

4.2.11[[DefineOwnMetadata]] ( MetadataKey, MetadataValue, P )

When the [[DefineOwnMetadata]] internal method of O is called with ECMAScript language value MetadataKey, ECMAScript language value MetadataValue, and property key P, the following steps are taken:

  1. Return OrdinaryDefineOwnMetadata(MetadataKey, MetadataValue, O, P)

4.2.12OrdinaryDefineOwnMetadata ( MetadataKey, MetadataValue, O, P )

When the abstract operation OrdinaryDefineOwnProperty is called with ECMAScript language value MetadataKey, ECMAScript language value MetadataValue, Object O, and property key P, the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let metadataMap be GetOrCreateMetadataMap(O, P, true).
  3. ReturnIfAbrupt(metadataMap).
  4. Return Invoke(metadataMap, "set", MetadataKey, MetadataValue).

4.2.13[[MetadataKeys]] ( P )

When the [[MetadataKeys]] internal method of O is called with property key P the following steps are taken:

  1. Return OrdinaryMetadataKeys(O, P).

4.2.14OrdinaryMetadataKeys ( O, P )

When the abstract operation OrdinaryMetadataKeys is called with Object O and property key P the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let ownKeys be OrdinaryOwnMetadataKeys(O, P).
  3. Let parent = O.[[GetPrototypeOf]]().
  4. ReturnIfAbrupt(parent).
  5. If parent is null, then return ownKeys.
  6. Let parentKeys be O.[[OrdinaryMetadataKeys]](P).
  7. ReturnIfAbrupt(parentKeys).
  8. Let ownKeysLen = Get(ownKeys, "length").
  9. ReturnIfAbrupt(ownKeysLen).
  10. If ownKeysLen is 0, return parentKeys.
  11. Let parentKeysLen = Get(parentKeys, "length").
  12. ReturnIfAbrupt(parentKeysLen).
  13. If parentKeysLen is 0, return ownKeys.
  14. Let set be a newly created Set object.
  15. Let keys be ArrayCreate(0).
  16. Let k be 0.
  17. For each element key of ownKeys
    1. Let hasKey be Invoke(set, "has", key).
    2. ReturnIfAbrupt(hasKey).
    3. If hasKey is false, then
      1. Let Pk be ToString(k).
      2. Let addStatus be Invoke(set, "add", key).
      3. ReturnIfAbrupt(addStatus).
      4. Let defineStatus be CreateDataPropertyOrThrow(keys, Pk, key).
      5. ReturnIfAbrupt(defineStatus).
      6. Increase k by 1.
  18. For each element key of parentKeys
    1. Let hasKey be Invoke(set, "has", key).
    2. ReturnIfAbrupt(hasKey).
    3. If hasKey is false, then
      1. Let Pk be ToString(k).
      2. Let addStatus be Invoke(set, "add", key).
      3. ReturnIfAbrupt(addStatus).
      4. Let defineStatus be CreateDataPropertyOrThrow(keys, Pk, key).
      5. ReturnIfAbrupt(defineStatus).
      6. Increase k by 1.
  19. Let setStatus be Set(keys, "length", k).
  20. ReturnIfAbrupt(setStatus).
  21. return keys.

4.2.15[[OwnMetadataKeys]] ( P )

When the [[OwnMetadataKeys]] internal method of O is called with property key P the following steps are taken:

  1. Return OrdinaryOwnMetadataKeys(O, P).

4.2.16OrdinaryOwnMetadataKeys ( O, P )

When the abstract operation OrdinaryOwnMetadataKeys is called with Object O and property key P the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let keys be ArrayCreate(0).
  3. Let metadataMap be GetOrCreateMetadataMap(O, P, false).
  4. ReturnIfAbrupt(metadataMap).
  5. If metadataMap is undefined, return keys.
  6. Let keysObj be Invoke(metadataMap, "keys").
  7. ReturnIfAbrupt(keysObj).
  8. Let iterator be GetIterator(keysObj).
  9. ReturnIfAbrupt(iterator).
  10. Let k be 0.
  11. Repeat
    1. Let Pk be ToString(k).
    2. Let next be IteratorStep(iterator).
    3. ReturnIfAbrupt(next).
    4. If next is false, then
      1. Let setStatus be Set(keys, "length", k, true).
      2. ReturnIfAbrupt(setStatus).
      3. Return keys.
    5. Let nextValue be IteratorValue(next).
    6. ReturnIfAbrupt(nextValue).
    7. Let defineStatus be CreateDataPropertyOrThrow(keys, Pk, nextValue).
    8. If defineStatus is an abrupt completion, return IteratorClose(iterator, defineStatus).
    9. Increase k by 1.

4.2.17[[DeleteMetadata]]( MetadataKey, P )

When the [[DeleteMetadata]] internal method of O is called with ECMAScript language value MetadataKey and property key P the following steps are taken:

  1. Assert: P is undefined or IsPropertyKey(P) is true.
  2. Let metadataMap be GetOrCreateMetadataMap(O, P, false).
  3. ReturnIfAbrupt(metadataMap).
  4. If metadataMap is undefined, return false.
  5. Return Invoke(metadataMap, "delete", MetadataKey).

5Reflection

5.1The Reflect Object

This section contains amendments to the Reflect object.

NoteA shim for this API can be found here: https://github.com/rbuckton/ReflectDecorators

5.1.1Metadata Decorator Functions

A metadata decorator function is an anonymous built-in function that has [[MetadataKey]] and [[MetadataValue]] internal slots.

When a metadata decorator function F is called with arguments target and key, the following steps are taken:

  1. Assert: F has a [[MetadataKey]] internal slot whose value is an ECMAScript language value, or undefined.
  2. Assert: F has a [[MetadataValue]] internal slot whose value is an ECMAScript language value, or undefined.
  3. If Type(target) is not Object, throw a TypeError exception.
  4. If key is not undefined and IsPropertyKey(key) is false, throw a TypeError exception.
  5. Let metadataKey be the value of F's [[MetadataKey]] internal slot.
  6. Let metadataValue be the value of F's [[MetadataValue]] internal slot.
  7. Return target.[[DefineMetadata]](metadataKey, metadataValue, target, key).

5.1.2Reflect.decorate ( decorators, target, propertyKey, attributes )

When the decorator function is called with arguments decorators, target, propertyKey, and attributes, the following steps are taken:

  1. If Type(decorators) is not Object, throw a TypeError exception.
  2. If Type(target) is not Object, throw a TypeError exception.
  3. Let key be ToPropertyKey(propertyKey).
  4. ReturnIfAbrupt(propertyKey).
  5. Let desc be ToPropertyDescriptor(attributes).
  6. ReturnIfAbrupt(desc).
  7. Return Decorate(decorators, target, propertyKey, desc).

5.1.3Reflect.metadata ( metadataKey, metadataValue )

When the metadata function is called with arguments metadataKey and metadataValue, the following steps are taken:

  1. Let decorator be a new built-in function object as defined in Metadata Decorator Functions.
  2. Set the [[MetadataKey]] internal slot of decorator to metadataKey.
  3. Set the [[MetadataValue]] internal slot of decorator to metadataValue.
  4. return decorator.

5.1.4Reflect.defineMetadata ( metadataKey, metadataValue, target, propertyKey )

When the defineMetadata function is called with arguments metadataKey, metadataValue, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[DefineMetadata]](metadataKey, metadataValue, propertyKey).

5.1.5Reflect.hasMetadata ( metadataKey, target, propertyKey )

When the hasMetadata function is called with arguments metadataKey, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[HasMetadata]](metadataKey, propertyKey).

5.1.6Reflect.hasOwnMetadata ( metadataKey, target, propertyKey )

When the hasOwnMetadata function is called with arguments metadataKey, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[HasOwn]](metadataKey, propertyKey).

5.1.7Reflect.getMetadata ( metadataKey, target, propertyKey )

When the getMetadata function is called with arguments metadataKey, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[GetMetadata]](metadataKey, propertyKey).

5.1.8Reflect.getOwnMetadata ( metadataKey, target, propertyKey )

When the getOwnMetadata function is called with arguments metadataKey, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[GetOwnMetadata]](metadataKey, propertyKey).

5.1.9Reflect.getMetadataKeys ( target, propertyKey )

When the getMetadataKeys function is called with arguments target and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[GetMetadataKeys]](propertyKey).

5.1.10Reflect.getOwnMetadataKeys ( target, propertyKey )

When the getOwnMetadataKeys function is called with arguments target and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[GetOwnMetadataKeys]](propertyKey).

5.1.11Reflect.deleteMetadata ( metadataKey, target, propertyKey )

When the deleteMetadata function is called with arguments metadataKey, target, and propertyKey, the following steps are taken:

  1. If Type(target) is not Object, throw a TypeError exception.
  2. return target.[[DeleteMetadata]](metadataKey, propertyKey).

AGrammar

A.1Expressions

MemberExpression [Yield, Decorator]:PrimaryExpression [?Yield] [~Decorator]MemberExpression [?Yield, ?Decorator][Expression [In, ?Yield]] MemberExpression [?Yield, ?Decorator].IdentifierName MemberExpression [?Yield, ?Decorator]TemplateLiteral [?Yield] SuperProperty [?Yield, ?Decorator] MetaProperty newMemberExpression [?Yield, ?Decorator]Arguments [?Yield] SuperProperty [Yield, Decorator]:[~Decorator]super[Expression [In, ?Yield]] NewExpression [Yield, Decorator]:MemberExpression [?Yield, ?Decorator] newNewExpression [?Yield, ?Decorator] CallExpression [Yield, Decorator]:MemberExpression [?Yield, ?Decorator]Arguments [?Yield] SuperCall [?Yield] CallExpression [?Yield, ?Decorator]Arguments [?Yield] [~Decorator]CallExpression [?Yield][Expression [In, ?Yield]] CallExpression [?Yield, ?Decorator].IdentifierName CallExpression [?Yield, ?Decorator]TemplateLiteral [?Yield] LeftHandSideExpression [Yield, Decorator]:NewExpression [?Yield, ?Decorator] CallExpression [?Yield, ?Decorator]

A.2Functions and Classes

ClassDeclaration [Yield, Default]:DecoratorList [?Yield] optclassBindingIdentifier [?Yield]ClassTail [?Yield] [+Default]DecoratorList [?Yield] optclassClassTail [?Yield] ClassExpression [Yield, GeneratorParameter]:DecoratorList [?Yield] optclassBindingIdentifier [?Yield] optClassTail [?Yield, ?GeneratorParameter] ClassElement [Yield]:DecoratorList [?Yield] optMethodDefinition [?Yield] DecoratorList [?Yield] optstaticMethodDefinition [?Yield] ; DecoratorList [Yield]:DecoratorList [?Yield] optDecorator [?Yield] Decorator [Yield]:@LeftHandSideExpression [Decorator, ?Yield]

A.3Scripts and Modules

ExportDeclaration:export*FromClause; exportExportClauseFromClause; exportExportClause; exportVariableStatement export[lookahead ≠ @]Declaration exportdefaultHoistableDeclaration [Default] exportdefault[lookahead ≠ @]ClassDeclaration [Default] exportdefault[lookahead ∉ { function, class, @ }]AssignmentExpression DecoratorListexport[lookahead ≠ @]ClassDeclaration DecoratorListexportdefault[lookahead ≠ @]ClassDeclaration [Default]