Skip to content

Commit 9801b5a

Browse files
committed
Initial static class property support.
1 parent fb45b67 commit 9801b5a

File tree

2 files changed

+210
-7
lines changed

2 files changed

+210
-7
lines changed

src/index.js

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const buildGetDescriptor = template(`
1414

1515

1616
const buildGetObjectInitializer = template(`
17-
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY).value, {
17+
(TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
1818
enumerable: true,
1919
configurable: true,
2020
writable: true,
@@ -210,10 +210,6 @@ export default function({types: t}){
210210

211211
if (decorators.length === 0) return acc;
212212

213-
if (t.isClassProperty(node, {static: true})){
214-
throw path.buildCodeFrameError('Static class property decorators are not yet supported.')
215-
}
216-
217213
if (node.computed){
218214
throw path.buildCodeFrameError('Computed method/property decorators are not yet supported.')
219215
}
@@ -224,7 +220,7 @@ export default function({types: t}){
224220
CLASS_REF: name,
225221
}).expression : name;
226222

227-
if (t.isClassProperty(node)){
223+
if (t.isClassProperty(node, {static: false})){
228224
let descriptor = path.scope.generateDeclaredUidIdentifier('descriptor');
229225

230226
const initializer = node.value ?
@@ -249,7 +245,7 @@ export default function({types: t}){
249245
target,
250246
property,
251247
t.arrayExpression(decorators.map(dec => dec.expression)),
252-
t.isObjectProperty(node) ? buildGetObjectInitializer({
248+
(t.isObjectProperty(node) || t.isClassProperty(node, {static: true})) ? buildGetObjectInitializer({
253249
TEMP: path.scope.generateDeclaredUidIdentifier('init'),
254250
TARGET: target,
255251
PROPERTY: property,

test/index.js

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,213 @@ describe('decorators', function(){
807807
expect(inst._).to.eql('__8__');
808808
});
809809
});
810+
811+
describe('static properties', function(){
812+
it('should support decorating properties that have no initializer', function(){
813+
function dec(target, name, descriptor){
814+
815+
}
816+
817+
class Example {
818+
@dec static prop;
819+
}
820+
821+
expect(Example).to.have.ownProperty('prop');
822+
expect(Example.prop).to.be.undefined;
823+
});
824+
825+
it('should allow returning a descriptor', function(){
826+
function dec(target, name, descriptor){
827+
target.decoratedProps = (target.decoratedProps || []).concat([name]);
828+
829+
let initializer = descriptor.initializer;
830+
return {
831+
enumerable: name.indexOf('enum') !== -1,
832+
configurable: name.indexOf('conf') !== -1,
833+
writable: name.indexOf('write') !== -1,
834+
initializer: function(...args){
835+
return '__' + initializer.apply(this, args) + '__';
836+
},
837+
};
838+
}
839+
840+
class Example {
841+
@dec
842+
static enumconfwrite = 1;
843+
844+
@dec
845+
static enumconf = 2;
846+
847+
@dec
848+
static enumwrite = 3;
849+
850+
@dec
851+
static enum = 4;
852+
853+
@dec
854+
static confwrite = 5;
855+
856+
@dec
857+
static conf = 6;
858+
859+
@dec
860+
static write = 7;
861+
862+
@dec
863+
static _ = 8;
864+
}
865+
const inst = new Example();
866+
867+
expect(Example).to.have.ownProperty('decoratedProps');
868+
expect(Example.decoratedProps).to.eql([
869+
"enumconfwrite",
870+
"enumconf",
871+
"enumwrite",
872+
"enum",
873+
"confwrite",
874+
"conf",
875+
"write",
876+
"_",
877+
]);
878+
879+
const descs = Object.getOwnPropertyDescriptors(Example);
880+
expect(descs.enumconfwrite.enumerable).to.be.true;
881+
expect(descs.enumconfwrite.writable).to.be.true;
882+
expect(descs.enumconfwrite.configurable).to.be.true;
883+
expect(Example.enumconfwrite).to.eql('__1__');
884+
885+
expect(descs.enumconf.enumerable).to.be.true;
886+
expect(descs.enumconf.writable).to.be.false;
887+
expect(descs.enumconf.configurable).to.be.true;
888+
expect(Example.enumconf).to.eql('__2__');
889+
890+
expect(descs.enumwrite.enumerable).to.be.true;
891+
expect(descs.enumwrite.writable).to.be.true;
892+
expect(descs.enumwrite.configurable).to.be.false;
893+
expect(Example.enumwrite).to.eql('__3__');
894+
895+
expect(descs.enum.enumerable).to.be.true;
896+
expect(descs.enum.writable).to.be.false;
897+
expect(descs.enum.configurable).to.be.false;
898+
expect(Example.enum).to.eql('__4__');
899+
900+
expect(descs.confwrite.enumerable).to.be.false;
901+
expect(descs.confwrite.writable).to.be.true;
902+
expect(descs.confwrite.configurable).to.be.true;
903+
expect(Example.confwrite).to.eql('__5__');
904+
905+
expect(descs.conf.enumerable).to.be.false;
906+
expect(descs.conf.writable).to.be.false;
907+
expect(descs.conf.configurable).to.be.true;
908+
expect(Example.conf).to.eql('__6__');
909+
910+
expect(descs.write.enumerable).to.be.false;
911+
expect(descs.write.writable).to.be.true;
912+
expect(descs.write.configurable).to.be.false;
913+
expect(Example.write).to.eql('__7__');
914+
915+
expect(descs._.enumerable).to.be.false;
916+
expect(descs._.writable).to.be.false;
917+
expect(descs._.configurable).to.be.false;
918+
expect(Example._).to.eql('__8__');
919+
});
920+
921+
it('should allow mutating the original descriptor', function(){
922+
function dec(target, name, descriptor){
923+
target.decoratedProps = (target.decoratedProps || []).concat([name]);
924+
925+
let initializer = descriptor.initializer;
926+
Object.assign(descriptor, {
927+
enumerable: name.indexOf('enum') !== -1,
928+
configurable: name.indexOf('conf') !== -1,
929+
writable: name.indexOf('write') !== -1,
930+
initializer: function(...args){
931+
return '__' + initializer.apply(this, args) + '__';
932+
},
933+
});
934+
}
935+
936+
class Example {
937+
@dec
938+
static enumconfwrite = 1;
939+
940+
@dec
941+
static enumconf = 2;
942+
943+
@dec
944+
static enumwrite = 3;
945+
946+
@dec
947+
static enum = 4;
948+
949+
@dec
950+
static confwrite = 5;
951+
952+
@dec
953+
static conf = 6;
954+
955+
@dec
956+
static write = 7;
957+
958+
@dec
959+
static _ = 8;
960+
}
961+
const inst = new Example();
962+
963+
expect(Example).to.have.ownProperty('decoratedProps');
964+
expect(Example.decoratedProps).to.eql([
965+
"enumconfwrite",
966+
"enumconf",
967+
"enumwrite",
968+
"enum",
969+
"confwrite",
970+
"conf",
971+
"write",
972+
"_",
973+
]);
974+
975+
const descs = Object.getOwnPropertyDescriptors(Example);
976+
expect(descs.enumconfwrite.enumerable).to.be.true;
977+
expect(descs.enumconfwrite.writable).to.be.true;
978+
expect(descs.enumconfwrite.configurable).to.be.true;
979+
expect(Example.enumconfwrite).to.eql('__1__');
980+
981+
expect(descs.enumconf.enumerable).to.be.true;
982+
expect(descs.enumconf.writable).to.be.false;
983+
expect(descs.enumconf.configurable).to.be.true;
984+
expect(Example.enumconf).to.eql('__2__');
985+
986+
expect(descs.enumwrite.enumerable).to.be.true;
987+
expect(descs.enumwrite.writable).to.be.true;
988+
expect(descs.enumwrite.configurable).to.be.false;
989+
expect(Example.enumwrite).to.eql('__3__');
990+
991+
expect(descs.enum.enumerable).to.be.true;
992+
expect(descs.enum.writable).to.be.false;
993+
expect(descs.enum.configurable).to.be.false;
994+
expect(Example.enum).to.eql('__4__');
995+
996+
expect(descs.confwrite.enumerable).to.be.false;
997+
expect(descs.confwrite.writable).to.be.true;
998+
expect(descs.confwrite.configurable).to.be.true;
999+
expect(Example.confwrite).to.eql('__5__');
1000+
1001+
expect(descs.conf.enumerable).to.be.false;
1002+
expect(descs.conf.writable).to.be.false;
1003+
expect(descs.conf.configurable).to.be.true;
1004+
expect(Example.conf).to.eql('__6__');
1005+
1006+
expect(descs.write.enumerable).to.be.false;
1007+
expect(descs.write.writable).to.be.true;
1008+
expect(descs.write.configurable).to.be.false;
1009+
expect(Example.write).to.eql('__7__');
1010+
1011+
expect(descs._.enumerable).to.be.false;
1012+
expect(descs._.writable).to.be.false;
1013+
expect(descs._.configurable).to.be.false;
1014+
expect(Example._).to.eql('__8__');
1015+
});
1016+
});
8101017
});
8111018

8121019
describe('object', function(){

0 commit comments

Comments
 (0)