[7.0] Replacing current decorators with decorators-legacy (#5290)

This commit is contained in:
Alex Kuzmenko
2017-02-15 22:42:50 +02:00
committed by Henry Zhu
parent c3098d2437
commit fa2a373acd
37 changed files with 1958 additions and 107 deletions

View File

@@ -54,9 +54,7 @@ npm install --save-dev babel-plugin-transform-decorators
## Usage
### Via `.babelrc` (Recommended)
**.babelrc**
Add the following line to your .babelrc file:
```json
{
@@ -64,6 +62,32 @@ npm install --save-dev babel-plugin-transform-decorators
}
```
#### NOTE: Order of Plugins Matters!
If you are including your plugins manually and using `transform-class-properties`, make sure that `transform-decorators` comes *before* `transform-class-properties`.
Wrong:
```json
{
"plugins": [
"transform-class-properties",
"transform-decorators"
]
}
```
Right:
```json
{
"plugins": [
"transform-decorators",
"transform-class-properties"
]
}
```
### Via CLI
```sh

View File

@@ -1,17 +1,19 @@
{
"name": "babel-plugin-transform-decorators",
"version": "6.22.0",
"version": "1.3.4",
"author": "Logan Smyth <loganfsmyth@gmail.com>",
"license": "MIT",
"description": "Compile class and object decorators to ES5",
"repository": "https://github.com/babel/babel/tree/master/packages/babel-plugin-transform-decorators",
"license": "MIT",
"main": "lib/index.js",
"keywords": [
"babel-plugin"
"babel",
"babel-plugin",
"decorators"
],
"dependencies": {
"babel-types": "^6.22.0",
"babel-plugin-syntax-decorators": "^6.13.0",
"babel-helper-explode-class": "^6.22.0",
"babel-runtime": "^6.2.0",
"babel-template": "^6.22.0"
},
"devDependencies": {

View File

@@ -1,132 +1,341 @@
// Fork of https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy
import template from "babel-template";
import explodeClass from "babel-helper-explode-class";
const buildClassDecorator = template(`
CLASS_REF = DECORATOR(CLASS_REF) || CLASS_REF;
DECORATOR(CLASS_REF = INNER) || CLASS_REF;
`);
export default function ({ types: t }) {
function cleanDecorators(decorators) {
return decorators.reverse().map((dec) => dec.expression);
}
const buildClassPrototype = template(`
CLASS_REF.prototype;
`);
function transformClass(path, ref, state) {
const nodes = [];
const buildGetDescriptor = template(`
Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
`);
state;
let classDecorators = path.node.decorators;
if (classDecorators) {
path.node.decorators = null;
classDecorators = cleanDecorators(classDecorators);
for (const decorator of classDecorators) {
nodes.push(buildClassDecorator({
CLASS_REF: ref,
DECORATOR: decorator
}));
}
}
const map = Object.create(null);
for (const method of path.get("body.body")) {
const decorators = method.node.decorators;
if (!decorators) continue;
const alias = t.toKeyAlias(method.node);
map[alias] = map[alias] || [];
map[alias].push(method.node);
method.remove();
}
for (const alias in map) {
const items = map[alias];
items;
}
return nodes;
}
function hasDecorators(path) {
if (path.isClass()) {
if (path.node.decorators) return true;
for (const method of (path.node.body.body: Array<Object>)) {
if (method.decorators) {
return true;
const buildGetObjectInitializer = template(`
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
enumerable: true,
configurable: true,
writable: true,
initializer: function(){
return TEMP;
}
}
} else if (path.isObjectExpression()) {
for (const prop of (path.node.properties: Array<Object>)) {
if (prop.decorators) {
return true;
})
`);
const buildInitializerWarningHelper = template(`
function NAME(descriptor, context){
throw new Error(
'Decorating class property failed. Please ensure that ' +
'transform-class-properties is enabled.'
);
}
`);
const buildInitializerDefineProperty = template(`
function NAME(target, property, descriptor, context){
if (!descriptor) return;
Object.defineProperty(target, property, {
enumerable: descriptor.enumerable,
configurable: descriptor.configurable,
writable: descriptor.writable,
value: descriptor.initializer ? descriptor.initializer.call(context) : void 0,
});
}
`);
const buildApplyDecoratedDescriptor = template(`
function NAME(target, property, decorators, descriptor, context){
var desc = {};
Object['ke' + 'ys'](descriptor).forEach(function(key){
desc[key] = descriptor[key];
});
desc.enumerable = !!desc.enumerable;
desc.configurable = !!desc.configurable;
if ('value' in desc || desc.initializer){
desc.writable = true;
}
}
desc = decorators.slice().reverse().reduce(function(desc, decorator){
return decorator(target, property, desc) || desc;
}, desc);
if (context && desc.initializer !== void 0){
desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
desc.initializer = undefined;
}
if (desc.initializer === void 0){
// This is a hack to avoid this being processed by 'transform-runtime'.
// See issue #9.
Object['define' + 'Property'](target, property, desc);
desc = null;
}
return desc;
}
`);
export default function({ types: t }) {
/**
* Add a helper to take an initial descriptor, apply some decorators to it, and optionally
* define the property.
*/
function ensureApplyDecoratedDescriptorHelper(path, state) {
if (!state.applyDecoratedDescriptor) {
state.applyDecoratedDescriptor = path.scope.generateUidIdentifier("applyDecoratedDescriptor");
const helper = buildApplyDecoratedDescriptor({
NAME: state.applyDecoratedDescriptor,
});
path.scope.getProgramParent().path.unshiftContainer("body", helper);
}
return false;
return state.applyDecoratedDescriptor;
}
function doError(path) {
throw path.buildCodeFrameError(
`Decorators are not officially supported yet in 6.x pending a proposal update.
However, if you need to use them you can install the legacy decorators transform with:
/**
* Add a helper to call as a replacement for class property definition.
*/
function ensureInitializerDefineProp(path, state) {
if (!state.initializerDefineProp) {
state.initializerDefineProp = path.scope.generateUidIdentifier("initDefineProp");
const helper = buildInitializerDefineProperty({
NAME: state.initializerDefineProp,
});
path.scope.getProgramParent().path.unshiftContainer("body", helper);
}
npm install babel-plugin-transform-decorators-legacy --save-dev
return state.initializerDefineProp;
}
and add the following line to your .babelrc file:
/**
* Add a helper that will throw a useful error if the transform fails to detect the class
* property assignment, so users know something failed.
*/
function ensureInitializerWarning(path, state) {
if (!state.initializerWarningHelper) {
state.initializerWarningHelper = path.scope.generateUidIdentifier("initializerWarningHelper");
const helper = buildInitializerWarningHelper({
NAME: state.initializerWarningHelper,
});
path.scope.getProgramParent().path.unshiftContainer("body", helper);
}
{
"plugins": ["transform-decorators-legacy"]
}
return state.initializerWarningHelper;
}
The repo url is: https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy.
`);
/**
* If the decorator expressions are non-identifiers, hoist them to before the class so we can be sure
* that they are evaluated in order.
*/
function applyEnsureOrdering(path) {
// TODO: This should probably also hoist computed properties.
const decorators = (
path.isClass()
? [path].concat(path.get("body.body"))
: path.get("properties")
).reduce((acc, prop) => acc.concat(prop.node.decorators || []), []);
const identDecorators = decorators.filter((decorator) => !t.isIdentifier(decorator.expression));
if (identDecorators.length === 0) return;
return t.sequenceExpression(identDecorators.map((decorator) => {
const expression = decorator.expression;
const id = decorator.expression = path.scope.generateDeclaredUidIdentifier("dec");
return t.assignmentExpression("=", id, expression);
}).concat([path.node]));
}
/**
* Given a class expression with class-level decorators, create a new expression
* with the proper decorated behavior.
*/
function applyClassDecorators(classPath) {
const decorators = classPath.node.decorators || [];
classPath.node.decorators = null;
if (decorators.length === 0) return;
const name = classPath.scope.generateDeclaredUidIdentifier("class");
return decorators
.map((dec) => dec.expression)
.reverse()
.reduce(function(acc, decorator) {
return buildClassDecorator({
CLASS_REF: name,
DECORATOR: decorator,
INNER: acc,
}).expression;
}, classPath.node);
}
/**
* Given a class expression with method-level decorators, create a new expression
* with the proper decorated behavior.
*/
function applyMethodDecorators(path, state) {
const hasMethodDecorators = path.node.body.body.some(function(node) {
return (node.decorators || []).length > 0;
});
if (!hasMethodDecorators) return;
return applyTargetDecorators(path, state, path.node.body.body);
}
/**
* Given an object expression with property decorators, create a new expression
* with the proper decorated behavior.
*/
function applyObjectDecorators(path, state) {
const hasMethodDecorators = path.node.properties.some(function(node) {
return (node.decorators || []).length > 0;
});
if (!hasMethodDecorators) return;
return applyTargetDecorators(path, state, path.node.properties);
}
/**
* A helper to pull out property decorators into a sequence expression.
*/
function applyTargetDecorators(path, state, decoratedProps) {
const name = path.scope.generateDeclaredUidIdentifier(path.isClass() ? "class" : "obj");
const exprs = decoratedProps.reduce(function(acc, node) {
const decorators = node.decorators || [];
node.decorators = null;
if (decorators.length === 0) return acc;
if (node.computed) {
throw path.buildCodeFrameError("Computed method/property decorators are not yet supported.");
}
const property = t.isLiteral(node.key) ? node.key : t.stringLiteral(node.key.name);
const target = (path.isClass() && !node.static) ? buildClassPrototype({
CLASS_REF: name,
}).expression : name;
if (t.isClassProperty(node, { static: false })) {
const descriptor = path.scope.generateDeclaredUidIdentifier("descriptor");
const initializer = node.value ?
t.functionExpression(null, [], t.blockStatement([t.returnStatement(node.value)])) :
t.nullLiteral();
node.value = t.callExpression(
ensureInitializerWarning(path, state), [descriptor, t.thisExpression()]
);
acc = acc.concat([
t.assignmentExpression(
"=", descriptor, t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
target,
property,
t.arrayExpression(decorators.map((dec) => dec.expression)),
t.objectExpression([
t.objectProperty(t.identifier("enumerable"), t.booleanLiteral(true)),
t.objectProperty(t.identifier("initializer"), initializer),
]),
])
),
]);
} else {
acc = acc.concat(
t.callExpression(ensureApplyDecoratedDescriptorHelper(path, state), [
target,
property,
t.arrayExpression(decorators.map((dec) => dec.expression)),
(
t.isObjectProperty(node) ||
t.isClassProperty(node, { static: true })) ?
buildGetObjectInitializer({
TEMP: path.scope.generateDeclaredUidIdentifier("init"),
TARGET: target,
PROPERTY: property,
}).expression : buildGetDescriptor({
TARGET: target,
PROPERTY: property,
}
).expression,
target,
])
);
}
return acc;
}, []);
return t.sequenceExpression([
t.assignmentExpression("=", name, path.node),
t.sequenceExpression(exprs),
name,
]);
}
return {
inherits: require("babel-plugin-syntax-decorators"),
visitor: {
ClassExpression(path) {
if (!hasDecorators(path)) return;
doError(path);
ExportDefaultDeclaration(path) {
if (!path.get("declaration").isClassDeclaration()) return;
explodeClass(path);
const { node } = path;
const ref = node.declaration.id || path.scope.generateUidIdentifier("default");
node.declaration.id = ref;
const ref = path.scope.generateDeclaredUidIdentifier("ref");
let nodes = [];
nodes.push(t.assignmentExpression("=", ref, path.node));
nodes = nodes.concat(transformClass(path, ref, this));
nodes.push(ref);
path.replaceWith(t.sequenceExpression(nodes));
// Split the class declaration and the export into two separate statements.
path.replaceWith(node.declaration);
path.insertAfter(t.exportNamedDeclaration(null, [t.exportSpecifier(ref, t.identifier("default"))]));
},
ClassDeclaration(path) {
if (!hasDecorators(path)) return;
doError(path);
explodeClass(path);
const { node } = path;
const ref = path.node.id;
let nodes = [];
const ref = node.id || path.scope.generateUidIdentifier("class");
nodes = nodes.concat(transformClass(path, ref, this).map((expr) => t.expressionStatement(expr)));
nodes.push(t.expressionStatement(ref));
path.replaceWith(t.variableDeclaration("let", [
t.variableDeclarator(ref, t.toExpression(node))
]));
},
ClassExpression(path, state) {
// Create a replacement for the class node if there is one. We do one pass to replace classes with
// class decorators, and a second pass to process method decorators.
const decoratedClass = (
applyEnsureOrdering(path) ||
applyClassDecorators(path, state) ||
applyMethodDecorators(path, state)
);
path.insertAfter(nodes);
if (decoratedClass) path.replaceWith(decoratedClass);
},
ObjectExpression(path, state) {
const decoratedObject = applyEnsureOrdering(path) || applyObjectDecorators(path, state);
if (decoratedObject) path.replaceWith(decoratedObject);
},
ObjectExpression(path) {
if (!hasDecorators(path)) return;
doError(path);
}
AssignmentExpression(path, state) {
if (!state.initializerWarningHelper) return;
if (!path.get("left").isMemberExpression()) return;
if (!path.get("left.property").isIdentifier()) return;
if (!path.get("right").isCallExpression()) return;
if (!path.get("right.callee").isIdentifier({ name: state.initializerWarningHelper.name })) return;
path.replaceWith(t.callExpression(ensureInitializerDefineProp(path, state), [
path.get("left.object").node,
t.stringLiteral(path.get("left.property").node.name),
path.get("right.arguments")[0].node,
path.get("right.arguments")[1].node,
]));
},
}
};
}

View File

@@ -0,0 +1,10 @@
function dec(cls){
cls.staticProp = "prop";
}
@dec
class Parent {
parent() {};
}
assert.equal(Parent.staticProp, "prop");

View File

@@ -0,0 +1,13 @@
function dec(cls){
return class Child extends cls {
child(){}
};
}
@dec
class Parent {
parent(){}
}
assert.equal(typeof Parent.prototype.parent, "function")
assert.equal(typeof Parent.prototype.child, "function")

View File

@@ -0,0 +1,28 @@
const calls = [];
function dec(id){
calls.push(id);
return function() {};
}
@dec(1)
@dec(2)
class Example {
@dec(3)
@dec(4)
method1() {};
@dec(5)
@dec(6)
prop1 = 1;
@dec(7)
@dec(8)
method2() {};
@dec(9)
@dec(10)
prop2 = 2;
}
assert.deepEqual(calls, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

View File

@@ -0,0 +1,29 @@
const calls = [];
function dec(id){
return function(){
calls.push(id);
};
}
@dec(10)
@dec(9)
class Example2 {
@dec(2)
@dec(1)
method1() {};
@dec(4)
@dec(3)
prop1 = 1;
@dec(6)
@dec(5)
method2() {};
@dec(8)
@dec(7)
prop2 = 2;
}
assert.deepEqual(calls, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

View File

@@ -0,0 +1,115 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
Object.assign(descriptor, {
enumerable: name.indexOf("enum") !== -1,
configurable: name.indexOf("conf") !== -1,
writable: name.indexOf("write") !== -1,
value: function(...args) {
return "__" + value.apply(this, args) + "__";
},
});
}
class Example {
@dec
enumconfwrite(){
return 1;
}
@dec
enumconf(){
return 2;
}
@dec
enumwrite(){
return 3;
}
@dec
enum(){
return 4;
}
@dec
confwrite(){
return 5;
}
@dec
conf(){
return 6;
}
@dec
write(){
return 7;
}
@dec
_(){
return 8;
}
}
assert(Example.prototype.hasOwnProperty('decoratedProps'));
assert.deepEqual(Example.prototype.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const inst = new Example();
const descs = Object.getOwnPropertyDescriptors(Example.prototype);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._(), "__8__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(name, 4);
assert.equal(typeof descriptor, "object");
}
class Example {
@dec
4() {};
}

View File

@@ -0,0 +1,117 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
value: function(...args){
return '__' + value.apply(this, args) + '__';
},
};
}
class Example {
@dec
enumconfwrite() {
return 1;
}
@dec
enumconf() {
return 2;
}
@dec
enumwrite() {
return 3;
}
@dec
enum() {
return 4;
}
@dec
confwrite() {
return 5;
}
@dec
conf() {
return 6;
}
@dec
write() {
return 7;
}
@dec
_() {
return 8;
}
}
assert(Example.prototype.hasOwnProperty('decoratedProps'));
assert.deepEqual(Example.prototype.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const inst = new Example();
const descs = Object.getOwnPropertyDescriptors(Example.prototype);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._(), "__8__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(name, "str");
assert.equal(typeof descriptor, "object");
}
class Example {
@dec
"str"() {};
}

View File

@@ -0,0 +1,27 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
descriptor.initializer = function(...args){
return "__" + initializer.apply(this, args) + "__";
};
}
class Base {
@dec
prop2 = 4;
}
class Example extends Base {
@dec
prop = 3;
}
let inst = new Example();
assert.equal(inst.prop, "__3__");
assert.equal(inst.prop2, "__4__");

View File

@@ -0,0 +1,99 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
Object.assign(descriptor, {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
});
}
class Example {
@dec
enumconfwrite = 1;
@dec
enumconf = 2;
@dec
enumwrite = 3;
@dec
enum = 4;
@dec
confwrite = 5;
@dec
conf = 6;
@dec
write = 7;
@dec
_ = 8;
}
const inst = new Example();
assert(Example.prototype.hasOwnProperty("decoratedProps"));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._, "__8__");

View File

@@ -0,0 +1,27 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, "prop");
assert.equal(typeof descriptor, "object");
let {initializer} = descriptor;
delete descriptor.initializer;
delete descriptor.writable;
let value;
descriptor.get = function(){
if (initializer){
value = '__' + initializer.call(this) + '__';
initializer = null;
}
return value;
};
}
class Example {
@dec
prop = 3;
}
let inst = new Example();
assert.equal(inst.prop, "__3__");

View File

@@ -0,0 +1,11 @@
function dec(target, name, descriptor) {
}
class Example {
@dec prop;
}
let inst = new Example();
assert(inst.hasOwnProperty("prop"));
assert.equal(inst.prop, undefined);

View File

@@ -0,0 +1,99 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
};
}
class Example {
@dec
enumconfwrite = 1;
@dec
enumconf = 2;
@dec
enumwrite = 3;
@dec
enum = 4;
@dec
confwrite = 5;
@dec
conf = 6;
@dec
write = 7;
@dec
_ = 8;
}
const inst = new Example();
assert(Example.prototype.hasOwnProperty("decoratedProps"));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._, "__8__");

View File

@@ -0,0 +1,113 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
Object.assign(descriptor, {
enumerable: name.indexOf("enum") !== -1,
configurable: name.indexOf("conf") !== -1,
writable: name.indexOf("write") !== -1,
value: function(...args) {
return "__" + value.apply(this, args) + "__";
},
});
}
class Example {
@dec
static enumconfwrite(){
return 1;
}
@dec
static enumconf(){
return 2;
}
@dec
static enumwrite(){
return 3;
}
@dec
static enum(){
return 4;
}
@dec
static confwrite(){
return 5;
}
@dec
static conf(){
return 6;
}
@dec
static write(){
return 7;
}
@dec
static _(){
return 8;
}
}
assert(Example.hasOwnProperty("decoratedProps"));
assert.deepEqual(Example.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(Example);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(Example.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(Example.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(Example.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(Example.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(Example.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(Example.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(Example.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(Example._(), "__8__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, 4);
assert.equal(typeof descriptor, "object");
}
class Example {
@dec
static 4() {}
}

View File

@@ -0,0 +1,114 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
value: function(...args){
return '__' + value.apply(this, args) + '__';
},
};
}
class Example {
@dec
static enumconfwrite() {
return 1;
}
@dec
static enumconf() {
return 2;
}
@dec
static enumwrite() {
return 3;
}
@dec
static enum() {
return 4;
}
@dec
static confwrite() {
return 5;
}
@dec
static conf() {
return 6;
}
@dec
static write() {
return 7;
}
@dec
static _() {
return 8;
}
}
assert(Example.hasOwnProperty("decoratedProps"));
assert.deepEqual(Example.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(Example);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(Example.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(Example.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(Example.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(Example.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(Example.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(Example.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(Example.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(Example._(), "__8__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(name, "str");
assert.equal(typeof descriptor, "object");
}
class Example {
@dec
static "str"() {};
}

View File

@@ -0,0 +1,99 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
Object.assign(descriptor, {
enumerable: name.indexOf("enum") !== -1,
configurable: name.indexOf("conf") !== -1,
writable: name.indexOf("write") !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
});
}
class Example {
@dec
static enumconfwrite = 1;
@dec
static enumconf = 2;
@dec
static enumwrite = 3;
@dec
static enum = 4;
@dec
static confwrite = 5;
@dec
static conf = 6;
@dec
static write = 7;
@dec
static _ = 8;
}
const inst = new Example();
assert(Example.hasOwnProperty("decoratedProps"));
assert.deepEqual(Example.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(Example);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(Example.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(Example.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(Example.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(Example.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(Example.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(Example.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(Example.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(Example._, "__8__");

View File

@@ -0,0 +1,25 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, "prop");
assert.equal(typeof descriptor, "object");
let {initializer} = descriptor;
delete descriptor.initializer;
delete descriptor.writable;
let value;
descriptor.get = function(){
if (initializer){
value = '__' + initializer.call(this) + '__';
initializer = null;
}
return value;
};
}
class Example {
@dec
static prop = 3;
}
assert.equal(Example.prop, "__3__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor) {
}
class Example {
@dec static prop;
}
assert(Example.hasOwnProperty("prop"));
assert.equal(Example.prop, undefined);

View File

@@ -0,0 +1,99 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
};
}
class Example {
@dec
static enumconfwrite = 1;
@dec
static enumconf = 2;
@dec
static enumwrite = 3;
@dec
static enum = 4;
@dec
static confwrite = 5;
@dec
static conf = 6;
@dec
static write = 7;
@dec
static _ = 8;
}
const inst = new Example();
assert(Example.hasOwnProperty("decoratedProps"));
assert.deepEqual(Example.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(Example);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(Example.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(Example.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(Example.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(Example.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(Example.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(Example.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(Example.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(Example._, "__8__");

View File

@@ -1,3 +0,0 @@
{
"plugins": ["external-helpers", "transform-es2015-destructuring", "transform-es2015-block-scoping", "transform-decorators", "transform-es2015-classes", "transform-class-properties"]
}

View File

@@ -0,0 +1,113 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
Object.assign(descriptor, {
enumerable: name.indexOf("enum") !== -1,
configurable: name.indexOf("conf") !== -1,
writable: name.indexOf("write") !== -1,
value: function(...args) {
return "__" + value.apply(this, args) + "__";
},
});
}
const inst = {
@dec
enumconfwrite(){
return 1;
},
@dec
enumconf(){
return 2;
},
@dec
enumwrite(){
return 3;
},
@dec
enum(){
return 4;
},
@dec
confwrite(){
return 5;
},
@dec
conf(){
return 6;
},
@dec
write(){
return 7;
},
@dec
_(){
return 8;
},
}
assert(inst.hasOwnProperty('decoratedProps'));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._(), "__8__");

View File

@@ -0,0 +1,11 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, 4);
assert.equal(typeof descriptor, "object");
}
const inst = {
@dec
4(){
}
};

View File

@@ -0,0 +1,113 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let value = descriptor.value;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
value: function(...args){
return '__' + value.apply(this, args) + '__';
},
};
}
const inst = {
@dec
enumconfwrite(){
return 1;
},
@dec
enumconf(){
return 2;
},
@dec
enumwrite(){
return 3;
},
@dec
enum(){
return 4;
},
@dec
confwrite(){
return 5;
},
@dec
conf(){
return 6;
},
@dec
write(){
return 7;
},
@dec
_(){
return 8;
},
}
assert(inst.hasOwnProperty('decoratedProps'));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite(), "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf(), "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite(), "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum(), "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite(), "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf(), "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write(), "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._(), "__8__");

View File

@@ -0,0 +1,12 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, "str");
assert.equal(typeof descriptor, "object");
}
const inst = {
@dec
"str"(){
}
};

View File

@@ -0,0 +1,25 @@
const calls = [];
function dec(id){
calls.push(id);
return function(){};
}
const obj = {
@dec(1)
@dec(2)
method1(){},
@dec(3)
@dec(4)
prop1: 1,
@dec(5)
@dec(6)
method2(){},
@dec(7)
@dec(8)
prop2: 2,
}
assert.deepEqual(calls, [1, 2, 3, 4, 5, 6, 7, 8]);

View File

@@ -0,0 +1,26 @@
const calls = [];
function dec(id){
return function(){
calls.push(id);
};
}
const obj = {
@dec(2)
@dec(1)
method1(){},
@dec(4)
@dec(3)
prop1: 1,
@dec(6)
@dec(5)
method2(){},
@dec(8)
@dec(7)
prop2: 2,
}
assert.deepEqual(calls, [1, 2, 3, 4, 5, 6, 7, 8]);

View File

@@ -0,0 +1,98 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
Object.assign(descriptor, {
enumerable: name.indexOf("enum") !== -1,
configurable: name.indexOf("conf") !== -1,
writable: name.indexOf("write") !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
});
}
const inst = {
@dec
enumconfwrite: 1,
@dec
enumconf: 2,
@dec
enumwrite: 3,
@dec
enum: 4,
@dec
confwrite: 5,
@dec
conf: 6,
@dec
write: 7,
@dec
_: 8,
};
assert(inst.hasOwnProperty("decoratedProps"));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._, "__8__");

View File

@@ -0,0 +1,25 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, "prop");
assert.equal(typeof descriptor, "object");
let {initializer} = descriptor;
delete descriptor.initializer;
delete descriptor.writable;
let value;
descriptor.get = function(){
if (initializer){
value = '__' + initializer.call(this) + '__';
initializer = null;
}
return value;
};
}
let inst = {
@dec
prop: 3
};
assert.equal(inst.prop, "__3__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, 4);
assert.equal(typeof descriptor, "object");
}
const inst = {
@dec
4: 1
};

View File

@@ -0,0 +1,97 @@
function dec(target, name, descriptor) {
assert(target);
assert.equal(typeof name, "string");
assert.equal(typeof descriptor, "object");
target.decoratedProps = (target.decoratedProps || []).concat([name]);
let initializer = descriptor.initializer;
return {
enumerable: name.indexOf('enum') !== -1,
configurable: name.indexOf('conf') !== -1,
writable: name.indexOf('write') !== -1,
initializer: function(...args){
return '__' + initializer.apply(this, args) + '__';
},
};
}
const inst = {
@dec
enumconfwrite: 1,
@dec
enumconf: 2,
@dec
enumwrite: 3,
@dec
enum: 4,
@dec
confwrite: 5,
@dec
conf: 6,
@dec
write: 7,
@dec
_: 8,
};
assert(inst.hasOwnProperty("decoratedProps"));
assert.deepEqual(inst.decoratedProps, [
"enumconfwrite",
"enumconf",
"enumwrite",
"enum",
"confwrite",
"conf",
"write",
"_",
]);
const descs = Object.getOwnPropertyDescriptors(inst);
assert(descs.enumconfwrite.enumerable);
assert(descs.enumconfwrite.writable);
assert(descs.enumconfwrite.configurable);
assert.equal(inst.enumconfwrite, "__1__");
assert(descs.enumconf.enumerable);
assert.equal(descs.enumconf.writable, false);
assert(descs.enumconf.configurable);
assert.equal(inst.enumconf, "__2__");
assert(descs.enumwrite.enumerable);
assert(descs.enumwrite.writable);
assert.equal(descs.enumwrite.configurable, false);
assert.equal(inst.enumwrite, "__3__");
assert(descs.enum.enumerable);
assert.equal(descs.enum.writable, false);
assert.equal(descs.enum.configurable, false);
assert.equal(inst.enum, "__4__");
assert.equal(descs.confwrite.enumerable, false);
assert(descs.confwrite.writable);
assert(descs.confwrite.configurable);
assert.equal(inst.confwrite, "__5__");
assert.equal(descs.conf.enumerable, false);
assert.equal(descs.conf.writable, false);
assert(descs.conf.configurable);
assert.equal(inst.conf, "__6__");
assert.equal(descs.write.enumerable, false);
assert(descs.write.writable);
assert.equal(descs.write.configurable, false);
assert.equal(inst.write, "__7__");
assert.equal(descs._.enumerable, false);
assert.equal(descs._.writable, false);
assert.equal(descs._.configurable, false);
assert.equal(inst._, "__8__");

View File

@@ -0,0 +1,10 @@
function dec(target, name, descriptor){
assert(target);
assert.equal(name, "str");
assert.equal(typeof descriptor, "object");
}
const inst = {
@dec
"str": 1
};

View File

@@ -0,0 +1,4 @@
{
"presets": ["es2015"],
"plugins": ["transform-decorators", "transform-class-properties"]
}