syntax.js (10909B)
1 // |jit-test| skip-if: !getBuildConfiguration("decorators") 2 3 load(libdir + "asserts.js"); 4 5 Reflect.parse("class c {@dec1 field = false;}"); 6 Reflect.parse("class c {@dec1 @dec2 @dec3 field = false;}"); 7 Reflect.parse("class c {@dec1 @dec2 @dec3('a') static field = false;}"); 8 Reflect.parse("class c {@dec1 method() {};}"); 9 Reflect.parse("class c {@dec1 @dec2 @dec3 method() {};}"); 10 Reflect.parse("class c {@dec1 @dec2 @dec3 static method() {};}"); 11 Reflect.parse("class c {@dec1 @dec2('a') @dec3 method(...args) {};}"); 12 Reflect.parse("class c {@((a, b, c) => {}) method(a, b) {};}"); 13 Reflect.parse("class c {@((a, b, c) => {}) @dec2('a', 'b') @dec3 method(a, b) {};}"); 14 Reflect.parse("@dec1 class c {}"); 15 Reflect.parse("@dec1 @dec2 @dec3 class c {}"); 16 Reflect.parse("@dec1('a') @(() => {}) @dec3 class c {}"); 17 Reflect.parse("@dec1('a') @(() => {}) @dec3 class c {@((a, b, c) => {}) @dec2('a', 'b') @dec3 method(a, b) {};}"); 18 Reflect.parse("x = @dec class { #x }"); 19 Reflect.parse("x = (class A { }, @dec class { })"); 20 Reflect.parse("@dec1 class A extends @dec2 class B extends @dec3 class {} {} {}"); 21 Reflect.parse("class c {@dec1.dec2.dec3 method() {};}"); 22 Reflect.parse("class c {@dec1 @dec2.dec3.dec4 @dec5 method() {};}"); 23 Reflect.parse("class c {@dec1('a') @dec2.dec3.dec4 @dec5 method() {};}"); 24 Reflect.parse("class c {@dec1('a') @dec2.dec3.dec4('b', 'c') @dec5 method() {};}"); 25 Reflect.parse("class c {@dec1('a') @dec2.dec3.dec4('b', 'c') @dec5.dec6 method() {};}"); 26 Reflect.parse("@dec1.dec2 class c {}"); 27 Reflect.parse("@dec1.dec2 @dec3.dec4 @dec5 class c {}"); 28 Reflect.parse("@dec1.dec2('a') @(() => {}) @dec4 class c {}"); 29 Reflect.parse("@dec1.dec2('a') @(() => {}) @dec4 class c {@((a, b, c) => {}) @dec5.dec6('a', 'b') @dec7 method(a, b) {};}"); 30 Reflect.parse("class c {accessor field = false;}"); 31 Reflect.parse("class c {static accessor field = false;}"); 32 Reflect.parse("class c {@dec1 @dec2 accessor field = false;}"); 33 Reflect.parse("class c {@dec1 @dec2 @dec3 static accessor field = false;}"); 34 Reflect.parse("let accessor = false;"); 35 Reflect.parse("class accessor {accessor = false;}"); 36 Reflect.parse("class c {accessor = false;}"); 37 Reflect.parse("class c {accessor\n= false;}"); 38 Reflect.parse("class c {accessor\nfield = false;}"); 39 Reflect.parse("class C {accessor\n foo() {}}"); 40 Reflect.parse("class c {accessor; }"); 41 Reflect.parse("class c {accessor\nset field(a) {}}"); 42 Reflect.parse("class c {accessor\nasync field(a) {}}"); 43 Reflect.parse("class c {accessor\n* field(a) {}}"); 44 Reflect.parse("{accessor, field(a)}"); 45 Reflect.parse("class c {static accessor x = 1;}"); 46 Reflect.parse("class c {accessor #y = 2;}"); 47 Reflect.parse("class c {static dec1(){}; static {@c.dec1 class d{@c.dec1 field}}}"); 48 Reflect.parse("class c {static #dec1(){}; static {@c.#dec1 class d{@c.#dec1 field}}}"); 49 Reflect.parse("class c {@as field = false;}"); 50 Reflect.parse("class c {@accessor field = false;}"); 51 Reflect.parse("class c {@assert field = false;}"); 52 Reflect.parse("class c {@async field = false;}"); 53 Reflect.parse("class c {@await field = false;}"); 54 Reflect.parse("class c {@each field = false;}"); 55 Reflect.parse("class c {@from field = false;}"); 56 Reflect.parse("class c {@get field = false;}"); 57 Reflect.parse("class c {@meta field = false;}"); 58 Reflect.parse("class c {@of field = false;}"); 59 Reflect.parse("class c {@set field = false;}"); 60 Reflect.parse("class c {@target field = false;}"); 61 62 assertThrowsInstanceOf(() => Reflect.parse("class c {@ method() {};}"), SyntaxError); 63 assertThrowsInstanceOf(() => Reflect.parse("class c {@((a, b, c => {}) method(a, b) {};}"), SyntaxError); 64 assertThrowsInstanceOf(() => Reflect.parse("class c {@dec1 static @dec2 method(a, b) {};}"), SyntaxError); 65 assertThrowsInstanceOf(() => Reflect.parse("@dec1 let x = 1"), SyntaxError); 66 assertThrowsInstanceOf(() => Reflect.parse("@dec1 f(a) {}"), SyntaxError); 67 assertThrowsInstanceOf(() => Reflect.parse("@dec1 () => {}"), SyntaxError); 68 assertThrowsInstanceOf(() => Reflect.parse("@class class { x; }"), SyntaxError); 69 assertThrowsInstanceOf(() => Reflect.parse("@for class { x; }"), SyntaxError); 70 assertThrowsInstanceOf(() => Reflect.parse("class c {@dec1. method() {};}"), SyntaxError); 71 assertThrowsInstanceOf(() => Reflect.parse("@dec1. class c {method() {};}"), SyntaxError); 72 assertThrowsInstanceOf(() => Reflect.parse("@dec1.(a) class c {method() {};}"), SyntaxError); 73 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor method() {};}"), SyntaxError); 74 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor @dec1 field = false;}"), SyntaxError); 75 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor, }"), SyntaxError); 76 assertThrowsInstanceOf(() => Reflect.parse("({ accessor field: 10 })"), SyntaxError); 77 assertThrowsInstanceOf(() => Reflect.parse("({ accessor foo });"), SyntaxError); 78 assertThrowsInstanceOf(() => Reflect.parse("({ accessor foo = 10 } = {});"), SyntaxError); 79 assertThrowsInstanceOf(() => Reflect.parse("class c {async accessor foo() {}}"), SyntaxError); 80 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor set field(a) {}}"), SyntaxError); 81 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor *field(a) {}}"), SyntaxError); 82 assertThrowsInstanceOf(() => Reflect.parse("class c {accessor *field(a) {}}"), SyntaxError); 83 assertThrowsInstanceOf(() => Reflect.parse("class c {@dec[0] x}"), SyntaxError); 84 assertThrowsInstanceOf(() => Reflect.parse("class c {@new dec() x}"), SyntaxError); 85 assertThrowsInstanceOf(() => Reflect.parse("class c {@super x}"), SyntaxError); 86 assertThrowsInstanceOf(() => Reflect.parse("class c {@super() x}"), SyntaxError); 87 assertThrowsInstanceOf(() => Reflect.parse("class c {@super.dec() x}"), SyntaxError); 88 assertThrowsInstanceOf(() => Reflect.parse("class c {@import \"decorator\" x}"), SyntaxError); 89 assertThrowsInstanceOf(() => Reflect.parse("class c {@dec`template` x}"), SyntaxError); 90 assertThrowsInstanceOf(() => Reflect.parse("class c {@import.meta.url x}"), SyntaxError); 91 assertThrowsInstanceOf(() => Reflect.parse("class c {@new.target x}"), SyntaxError); 92 assertThrowsInstanceOf(() => Reflect.parse("class c {@obj.first?.second x}"), SyntaxError); 93 assertThrowsInstanceOf(() => Reflect.parse("class c {@class x}"), SyntaxError); 94 assertThrowsInstanceOf(() => Reflect.parse("class c {@function() x}"), SyntaxError); 95 assertThrowsInstanceOf(() => Reflect.parse("class c {@{} x}"), SyntaxError); 96 assertThrowsInstanceOf(() => Reflect.parse("class c {@[] x}"), SyntaxError); 97 assertThrowsInstanceOf(() => Reflect.parse("class c {@\"string\" x}"), SyntaxError); 98 assertThrowsInstanceOf(() => Reflect.parse("class c {@`string` x}"), SyntaxError); 99 assertThrowsInstanceOf(() => Reflect.parse("class c {@/[a-z]+/ x}"), SyntaxError); 100 assertThrowsInstanceOf(() => Reflect.parse("class c {@true x}"), SyntaxError); 101 assertThrowsInstanceOf(() => Reflect.parse("class c {@1n x}"), SyntaxError); 102 assertThrowsInstanceOf(() => Reflect.parse("class c {@this x}"), SyntaxError); 103 assertThrowsInstanceOf(() => Reflect.parse("class c {@null x}"), SyntaxError); 104 assertThrowsInstanceOf(() => Reflect.parse("class c {@... x}"), SyntaxError); 105 assertThrowsInstanceOf(() => Reflect.parse("class c {@let x}"), SyntaxError); 106 assertThrowsInstanceOf(() => Reflect.parse("class c {@static x}"), SyntaxError); 107 assertThrowsInstanceOf(() => Reflect.parse("class c {@yield x}"), SyntaxError); 108 assertThrowsInstanceOf(() => Reflect.parse("class c {@if x}"), SyntaxError); 109 assertThrowsInstanceOf(() => Reflect.parse("class c {@enum x}"), SyntaxError); 110 assertThrowsInstanceOf(() => Reflect.parse("class c {@implements x}"), SyntaxError); 111 assertThrowsInstanceOf(() => Reflect.parse("class c {@foo().bar.prop x}"), SyntaxError); 112 assertThrowsInstanceOf(() => Reflect.parse("class c {@foo.bar().prop x}"), SyntaxError); 113 assertThrowsInstanceOf(() => Reflect.parse("class c {@foo.bar().prop() x}"), SyntaxError); 114 115 // assert we have the right syntax tree 116 const syntax = Reflect.parse("class c {}"); 117 assertEq(syntax.type, "Program"); 118 assertEq(syntax.body.length, 1); 119 assertEq(syntax.body[0].type, "ClassStatement"); 120 assertEq(syntax.body[0].id.type, "Identifier"); 121 assertEq(syntax.body[0].id.name, "c"); 122 assertEq(syntax.body[0].decorators, null); 123 124 // assert decrorators on a class 125 const syntax2 = Reflect.parse("@dec @dec2 class c {}"); 126 assertEq(syntax2.type, "Program"); 127 assertEq(syntax2.body.length, 1); 128 assertEq(syntax2.body[0].decorators.type, "SequenceExpression"); 129 assertEq(syntax2.body[0].decorators.expressions.length, 2); 130 assertEq(syntax2.body[0].decorators.expressions[0].type, "Identifier"); 131 assertEq(syntax2.body[0].decorators.expressions[0].name, "dec"); 132 assertEq(syntax2.body[0].decorators.expressions[1].type, "Identifier"); 133 assertEq(syntax2.body[0].decorators.expressions[1].name, "dec2"); 134 135 // assert decorators on class fields 136 const syntax3 = Reflect.parse("class c {@dec1 @dec2 field = false;}"); 137 assertEq(syntax3.type, "Program"); 138 assertEq(syntax3.body.length, 1); 139 assertEq(syntax3.body[0].decorators, null); 140 assertEq(syntax3.body[0].body[0].type, "ClassField"); 141 assertEq(syntax3.body[0].body[0].decorators.type, "SequenceExpression"); 142 assertEq(syntax3.body[0].body[0].decorators.expressions.length, 2); 143 assertEq(syntax3.body[0].body[0].decorators.expressions[0].type, "Identifier"); 144 assertEq(syntax3.body[0].body[0].decorators.expressions[0].name, "dec1"); 145 assertEq(syntax3.body[0].body[0].decorators.expressions[1].type, "Identifier"); 146 assertEq(syntax3.body[0].body[0].decorators.expressions[1].name, "dec2"); 147 148 // assert decorators on accessors 149 const syntax4 = Reflect.parse("class c {@dec1 @dec2 accessor field = false;}"); 150 assertEq(syntax3.type, "Program"); 151 assertEq(syntax3.body.length, 1); 152 assertEq(syntax3.body[0].decorators, null); 153 assertEq(syntax3.body[0].body[0].type, "ClassField"); 154 assertEq(syntax3.body[0].body[0].decorators.type, "SequenceExpression"); 155 assertEq(syntax3.body[0].body[0].decorators.expressions.length, 2); 156 assertEq(syntax3.body[0].body[0].decorators.expressions[0].type, "Identifier"); 157 assertEq(syntax3.body[0].body[0].decorators.expressions[0].name, "dec1"); 158 assertEq(syntax3.body[0].body[0].decorators.expressions[1].type, "Identifier"); 159 assertEq(syntax3.body[0].body[0].decorators.expressions[1].name, "dec2"); 160 161 // assert decorators on methods 162 const syntax5 = Reflect.parse("class c {@dec1 @dec2 method() {};}"); 163 assertEq(syntax5.type, "Program"); 164 assertEq(syntax5.body.length, 1); 165 assertEq(syntax5.body[0].decorators, null); 166 assertEq(syntax5.body[0].body[0].type, "ClassMethod"); 167 assertEq(syntax5.body[0].body[0].decorators.type, "SequenceExpression"); 168 assertEq(syntax5.body[0].body[0].decorators.expressions.length, 2); 169 assertEq(syntax5.body[0].body[0].decorators.expressions[0].type, "Identifier"); 170 assertEq(syntax5.body[0].body[0].decorators.expressions[0].name, "dec1"); 171 assertEq(syntax5.body[0].body[0].decorators.expressions[1].type, "Identifier"); 172 assertEq(syntax5.body[0].body[0].decorators.expressions[1].name, "dec2");