Skip to content

Commit

Permalink
Add 2022-03 decorators version (stage 3) (#14836)
Browse files Browse the repository at this point in the history
* Copy `applyDecs`->`applyDecs2203` helper, and `2021-12`->`2022-03` tests

* Avoid conflicting fn names in helpers

* Add `2022-03` decorators version

* Rename `isPrivate`/`isStatic`->`private`/`static`

* Disallow `@(...)()` in 2022-03 decorators

This commits add a new `allowCallParenthesized` option to the decorators parser plugin:
when set to `false`, `@(...)()`-style decorators are allowed to match the stage 3
proposal presented in March 2022.

It will default to `false` in Babel 8 (we might just remove the option)

* Disallow `decoratorsBeforeExport` option with 2022-03 decorators

This aligns with the Babel 8 behavior

* Remove `.initializer` fallback for accessor properties

* Remove `.initializer` fallback for accessor properties

* Expose `.access` for public class elements

* Remove `getMetadata`/`setMetadata`

* Make the parser error recoverable

* Print necessary parentheses in generator
  • Loading branch information
nicolo-ribaudo committed Sep 5, 2022
1 parent 85ce832 commit 16d3220
Show file tree
Hide file tree
Showing 325 changed files with 7,789 additions and 77 deletions.
7 changes: 3 additions & 4 deletions packages/babel-generator/src/generators/expressions.ts
Expand Up @@ -131,14 +131,13 @@ function isDecoratorMemberExpression(
function shouldParenthesizeDecoratorExpression(
node: t.Expression | t.Super | t.V8IntrinsicIdentifier,
) {
if (node.type === "CallExpression") {
node = node.callee;
}
if (node.type === "ParenthesizedExpression") {
// We didn't check extra?.parenthesized here because we don't track decorators in needsParen
return false;
}
return !isDecoratorMemberExpression(node);
return !isDecoratorMemberExpression(
node.type === "CallExpression" ? node.callee : node,
);
}

export function Decorator(this: Printer, node: t.Decorator) {
Expand Down
Expand Up @@ -9,7 +9,6 @@ class C extends class {} {
@(this.dec)
@(super.dec)
@(new DecFactory)
@(decs[three])()
p;
}

Expand All @@ -20,6 +19,11 @@ class C extends class {} {
p;
}

class ShouldAddParens {
@(decs[three])()
p;
}

class WillPreserveParens {
@(decs)
@(decs.one)
Expand Down
Expand Up @@ -10,7 +10,6 @@ class C extends class {} {
@(this.dec)
@(super.dec)
@(new DecFactory())
@(decs[three])()
p;
}

Expand All @@ -21,6 +20,11 @@ class C extends class {} {
p;
}

class ShouldAddParens {
@((decs[three])())
p;
}

class WillPreserveParens {
@(decs)
@(decs.one)
Expand Down
6 changes: 5 additions & 1 deletion packages/babel-helpers/src/helpers-generated.ts

Large diffs are not rendered by default.

87 changes: 46 additions & 41 deletions packages/babel-helpers/src/helpers/applyDecs.js
@@ -1,5 +1,10 @@
/* @minVersion 7.17.8 */

/**
* NOTE: This is an old version of the helper, used for 2021-12 decorators.
* Updates should be done in applyDecs2203.js.
*/

/**
Enums are used in this file, but not assigned to vars to avoid non-hoistable values
Expand All @@ -18,16 +23,16 @@
CLASS = 10; // only used in assertValidReturnValue
*/

function createMetadataMethodsForProperty(
function old_createMetadataMethodsForProperty(
metadataMap,
kind,
property,
decoratorFinishedRef
) {
return {
getMetadata: function (key) {
assertNotFinished(decoratorFinishedRef, "getMetadata");
assertMetadataKey(key);
old_assertNotFinished(decoratorFinishedRef, "getMetadata");
old_assertMetadataKey(key);

var metadataForKey = metadataMap[key];

Expand All @@ -48,8 +53,8 @@ function createMetadataMethodsForProperty(
}
},
setMetadata: function (key, value) {
assertNotFinished(decoratorFinishedRef, "setMetadata");
assertMetadataKey(key);
old_assertNotFinished(decoratorFinishedRef, "setMetadata");
old_assertMetadataKey(key);

var metadataForKey = metadataMap[key];

Expand Down Expand Up @@ -80,7 +85,7 @@ function createMetadataMethodsForProperty(
};
}

function convertMetadataMapToFinal(obj, metadataMap) {
function old_convertMetadataMapToFinal(obj, metadataMap) {
var parentMetadataMap = obj[Symbol.metadata || Symbol.for("Symbol.metadata")];
var metadataKeys = Object.getOwnPropertySymbols(metadataMap);

Expand Down Expand Up @@ -123,15 +128,15 @@ function convertMetadataMapToFinal(obj, metadataMap) {
obj[Symbol.metadata || Symbol.for("Symbol.metadata")] = metadataMap;
}

function createAddInitializerMethod(initializers, decoratorFinishedRef) {
function old_createAddInitializerMethod(initializers, decoratorFinishedRef) {
return function addInitializer(initializer) {
assertNotFinished(decoratorFinishedRef, "addInitializer");
assertCallable(initializer, "An initializer");
old_assertNotFinished(decoratorFinishedRef, "addInitializer");
old_assertCallable(initializer, "An initializer");
initializers.push(initializer);
};
}

function memberDec(
function old_memberDec(
dec,
name,
desc,
Expand Down Expand Up @@ -171,7 +176,7 @@ function memberDec(
var decoratorFinishedRef = { v: false };

if (kind !== 0 /* FIELD */) {
ctx.addInitializer = createAddInitializerMethod(
ctx.addInitializer = old_createAddInitializerMethod(
initializers,
decoratorFinishedRef
);
Expand Down Expand Up @@ -218,7 +223,7 @@ function memberDec(
value,
Object.assign(
ctx,
createMetadataMethodsForProperty(
old_createMetadataMethodsForProperty(
metadataMap,
metadataKind,
metadataName,
Expand All @@ -231,27 +236,27 @@ function memberDec(
}
}

function assertNotFinished(decoratorFinishedRef, fnName) {
function old_assertNotFinished(decoratorFinishedRef, fnName) {
if (decoratorFinishedRef.v) {
throw new Error(
"attempted to call " + fnName + " after decoration was finished"
);
}
}

function assertMetadataKey(key) {
function old_assertMetadataKey(key) {
if (typeof key !== "symbol") {
throw new TypeError("Metadata keys must be symbols, received: " + key);
}
}

function assertCallable(fn, hint) {
function old_assertCallable(fn, hint) {
if (typeof fn !== "function") {
throw new TypeError(hint + " must be a function");
}
}

function assertValidReturnValue(kind, value) {
function old_assertValidReturnValue(kind, value) {
var type = typeof value;

if (kind === 1 /* ACCESSOR */) {
Expand All @@ -261,16 +266,16 @@ function assertValidReturnValue(kind, value) {
);
}
if (value.get !== undefined) {
assertCallable(value.get, "accessor.get");
old_assertCallable(value.get, "accessor.get");
}
if (value.set !== undefined) {
assertCallable(value.set, "accessor.set");
old_assertCallable(value.set, "accessor.set");
}
if (value.init !== undefined) {
assertCallable(value.init, "accessor.init");
old_assertCallable(value.init, "accessor.init");
}
if (value.initializer !== undefined) {
assertCallable(value.initializer, "accessor.initializer");
old_assertCallable(value.initializer, "accessor.initializer");
}
} else if (type !== "function") {
var hint;
Expand All @@ -285,7 +290,7 @@ function assertValidReturnValue(kind, value) {
}
}

function getInit(desc) {
function old_getInit(desc) {
var initializer;
if (
(initializer = desc.init) == null &&
Expand All @@ -297,7 +302,7 @@ function getInit(desc) {
return initializer;
}

function applyMemberDec(
function old_applyMemberDec(
ret,
base,
decInfo,
Expand Down Expand Up @@ -351,7 +356,7 @@ function applyMemberDec(
var newValue, get, set;

if (typeof decs === "function") {
newValue = memberDec(
newValue = old_memberDec(
decs,
name,
desc,
Expand All @@ -364,12 +369,12 @@ function applyMemberDec(
);

if (newValue !== void 0) {
assertValidReturnValue(kind, newValue);
old_assertValidReturnValue(kind, newValue);

if (kind === 0 /* FIELD */) {
initializer = newValue;
} else if (kind === 1 /* ACCESSOR */) {
initializer = getInit(newValue);
initializer = old_getInit(newValue);
get = newValue.get || value.get;
set = newValue.set || value.set;

Expand All @@ -382,7 +387,7 @@ function applyMemberDec(
for (var i = decs.length - 1; i >= 0; i--) {
var dec = decs[i];

newValue = memberDec(
newValue = old_memberDec(
dec,
name,
desc,
Expand All @@ -395,13 +400,13 @@ function applyMemberDec(
);

if (newValue !== void 0) {
assertValidReturnValue(kind, newValue);
old_assertValidReturnValue(kind, newValue);
var newInit;

if (kind === 0 /* FIELD */) {
newInit = newValue;
} else if (kind === 1 /* ACCESSOR */) {
newInit = getInit(newValue);
newInit = old_getInit(newValue);
get = newValue.get || value.get;
set = newValue.set || value.set;

Expand Down Expand Up @@ -485,7 +490,7 @@ function applyMemberDec(
}
}

function applyMemberDecs(
function old_applyMemberDecs(
ret,
Class,
protoMetadataMap,
Expand Down Expand Up @@ -555,7 +560,7 @@ function applyMemberDecs(
}
}

applyMemberDec(
old_applyMemberDec(
ret,
base,
decInfo,
Expand All @@ -568,11 +573,11 @@ function applyMemberDecs(
);
}

pushInitializers(ret, protoInitializers);
pushInitializers(ret, staticInitializers);
old_pushInitializers(ret, protoInitializers);
old_pushInitializers(ret, staticInitializers);
}

function pushInitializers(ret, initializers) {
function old_pushInitializers(ret, initializers) {
if (initializers) {
ret.push(function (instance) {
for (var i = 0; i < initializers.length; i++) {
Expand All @@ -583,7 +588,7 @@ function pushInitializers(ret, initializers) {
}
}

function applyClassDecs(ret, targetClass, metadataMap, classDecs) {
function old_applyClassDecs(ret, targetClass, metadataMap, classDecs) {
if (classDecs.length > 0) {
var initializers = [];
var newClass = targetClass;
Expand All @@ -597,12 +602,12 @@ function applyClassDecs(ret, targetClass, metadataMap, classDecs) {
{
kind: "class",
name: name,
addInitializer: createAddInitializerMethod(
addInitializer: old_createAddInitializerMethod(
initializers,
decoratorFinishedRef
),
},
createMetadataMethodsForProperty(
old_createMetadataMethodsForProperty(
metadataMap,
0 /* CONSTRUCTOR */,
name,
Expand All @@ -615,7 +620,7 @@ function applyClassDecs(ret, targetClass, metadataMap, classDecs) {
}

if (nextNewClass !== undefined) {
assertValidReturnValue(10 /* CLASS */, nextNewClass);
old_assertValidReturnValue(10 /* CLASS */, nextNewClass);
newClass = nextNewClass;
}
}
Expand Down Expand Up @@ -779,19 +784,19 @@ export default function applyDecs(targetClass, memberDecs, classDecs) {

var protoMetadataMap = {};

applyMemberDecs(
old_applyMemberDecs(
ret,
targetClass,
protoMetadataMap,
staticMetadataMap,
memberDecs
);

convertMetadataMapToFinal(targetClass.prototype, protoMetadataMap);
old_convertMetadataMapToFinal(targetClass.prototype, protoMetadataMap);

applyClassDecs(ret, targetClass, staticMetadataMap, classDecs);
old_applyClassDecs(ret, targetClass, staticMetadataMap, classDecs);

convertMetadataMapToFinal(targetClass, staticMetadataMap);
old_convertMetadataMapToFinal(targetClass, staticMetadataMap);

return ret;
}

0 comments on commit 16d3220

Please sign in to comment.