-
Notifications
You must be signed in to change notification settings - Fork 516
Open
Description
Proposal Readme
Proposal Spec Text
Tests
-
Fields
- Context
kindis"field" - Received value is
undefined - Decorator can return an initializer function that receives the initial value and can return a new value, or
undefined. Any other type of return value besides throws an error - Initializer functions for fields with multiple decorators are run in the reverse order of decorator evaluation (e.g. lexical order), and each initializer receives the return value of the previous initializer as its input
- Decorated field initializers are interleaved lexically with non-decorated field initializers
- Instance
- The
thisvalue of the initializer function is the instance of the class that is being initialized - Initializers is called at the same time as when the class field would be assigned if not decorated (e.g. right after
super(), in lexical order)
- The
- Static
- The
thisvalue of the initializer function is the class definition itself - Initializers are called at the same time as when the class field would be assigned if not decorated (e.g. ordering is the same relative to static class blocks, computed name evaluation, etc.)
- The
- Context
-
Methods
- Context
kindis"method" - Received value is the class method function, or the function returned by the previous decorator applied to the method (if any)
- Decorator can return a function or
undefined. Any other type of return value throws an error - The returned function is assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance methods, on the class itself for static methods)
- If the decorator returns
undefined, it assigns the original method OR the output of the most recent decorator which returned a function
- Context
-
Getters/Setters
- Context
kindis"getter"or"setter" - Received value is the class getter/setter function, or the function returned by the previous decorator applied to the method (if any)
- Decorator can return a function or
undefined. Any other type of return value throws an error - The returned function is assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance getters/setters, on the class itself for static getters/setters)
- If the decorator returns
undefined, it assigns the original getter/setter OR the output of the most recent decorator which returned a function
- Context
-
Auto-Accessors
- Behavior
-
accessorkeyword can be used to create an "empty" getter/setter pair on the class. The getter and setter read from and set to a private slot, with no additional observable behavior. -
accessorcan be combined with private fields,static, and computed property names, and works with all permutations of them -
accessorcan be given an initializer that provides a default value - Initializers run at the same time as class fields, and are interleaved lexically with class field initializers
-
- Decoration
- Context
kindis"accessor" - Received value is an object with
getandsetproperties which are the getter and setter of the accessor, or the most recent decoration that returned one. - Decorator can return an object containing
get,set, and/orinitproperties. Each of these must be a function, any other type of value will throw an error - Decorator can return
undefined, in which case previous value is used instead - If a previous decorator returns
getbut notset,getis replaced with the new value, and the previoussetis used - If a previous decorator returns
setbut notget,setis replaced with the new value, and the previousgetis used -
initreceives the initial value of the auto-accessor (or the returned value from the previousinit) and may return a new value -
initruns at the same time as a non-decorated accessor's initializer -
initfunctions for multiple decorators on a single field run in the reverse order of decorator evaluation (e.g. lexical order), and each initializer receives the returned value of the previous initializer - The returned getter and setter are assigned in the same location as a non-decorated version would have been (e.g. on the class prototype for instance accessors, on the class itself for static accessors)
- If the decorator returns
undefined, it assigns the original getter/setter OR the output of the most recent decorator which returned a value
- Context
- Behavior
-
Classes
- Context
kindis"class" - Class decorators receive the class definition, and may return a new construct-able value (e.g. another class, a proxy, a non-arrow function), or
undefined - Class decorators are applied before static elements are evaluated, static blocks are called, etc.
- If the returned value cannot be constructed, throw an error
- Class declarations can be decorated
- Class expressions can be decorated
- Bindings to the class itself within the class definition reference the final class definition (e.g. the value returned by the last decorator)
- Context
-
Context
-
name- Name is correct for standard public elements
- Name is the same as the name in code for private values (e.g.
#foo) - Name is correct for computed property names
- Name is correct for classes
-
access- Access includes
getandsetfunctions -
getandsetfunctions must be called withthisvalue to work properly - Access works for public elements
- Access works for private elements
-
getandsetaccess the method itself for methods/getters/setters (e.g. the slot that contains the method, public or private). This allows a decorator to get the final version of the method, for instance. -
setdoes NOT work for private class methods/getters/setters - Not defined for classes
- Access includes
-
private-
truefor private elements -
falsefor public elements - Not defined for classes
-
-
static-
truefor static elements -
falsefor non-static elements - Not defined for classes
-
-
addInitializer- Can receive a function as its first argument, throws an error if it receives any other type of value
- Methods/Getters/Setters: Extra initializers run immediately before class fields/accessors are assigned
- Fields/Accessors: Extra initializers run after the standard initializers are run and initial value is assigned
- Classes: Extra initializers run after class definition has completed, after static fields and elements have been assigned, just before the next statement or expression after the definition is run.
- Initializers run in the same order as decorator application (e.g. reverse lexical per element, lexical across all elements)
-
addInitializerthrows an error if called after decoration has finished (including if decoration was interrupted by an error)
-
-
General
- Syntax
- Application
- Decorators can be single identifiers (e.g.
@foo) - Decorators can be single call expressions (e.g.
@foo()) - Decorators can be a chain of property accesses (e.g.
@foo.bar.baz) - Decorators can be a chain of property accesses with a call expression at the end (e.g.
@foo.bar.baz()) - Decorator property accesses can include private names (e.g.
@foo.#bar) - Any other expression can be wrapped in parens at the top level, examples:
-
@(foo().bar) -
@(foo[0]) -
@(super.foo) -
@(this.foo) -
@(yield foo) -
@(await foo)
-
- Any other syntax is invalid
- Decorators can be single identifiers (e.g.
- Placement
- Can be placed just before a class element
- Can be placed just before a class declaration or expression
- Are placed before
exportanddefaultkeywords if they are applied to the class
- Application
- Ordering
- Decorators are applied to each element/class from inner to outer (reverse lexical)
- Decorators run in the order: Static non-fields -> Instance non-fields -> Static fields -> Instance fields -> Class
- Decorator expressions (e.g. the
dec()part of@dec()) are run before application, before static block initialization, interleaved and at the same time as computed expression name evaluation
- Decorators can be applied to all valid types of class elements (except static blocks)
- private
-
static -
async - generator
- Syntax
ptomato, Obiwarn, ioannad, wa-Nadoo, Akatroj and 1 more
Metadata
Metadata
Assignees
Labels
No labels