OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 // Flags: --harmony-types |
| 6 |
| 7 |
| 8 load("test/mjsunit/harmony/typesystem/testgen.js"); |
| 9 |
| 10 |
| 11 function CheckValidAmbient(decl, full, preamble) { |
| 12 preamble = typeof(preamble) === "undefined" ? '' : preamble + '; '; |
| 13 CheckValid(preamble + "declare " + decl); |
| 14 if (typeof(full) === "undefined") full = decl; |
| 15 if (typeof(full) === "null") return; |
| 16 CheckValid(preamble + "declare " + decl + "; " + full); |
| 17 } |
| 18 |
| 19 function CheckInvalidAmbient(decl, full=null, preamble) { |
| 20 preamble = typeof(preamble) === "undefined" ? '' : preamble + '; '; |
| 21 CheckInvalid(preamble + "declare " + decl); |
| 22 if (typeof(full) === "undefined") full = decl; |
| 23 if (typeof(full) === "null") return; |
| 24 CheckInvalid(preamble + "declare " + decl + "; " + full); |
| 25 } |
| 26 |
| 27 function CheckInvalidAmbientInInnerScope(decl, full=null, preamble) { |
| 28 preamble = typeof(preamble) === "undefined" ? '' : preamble + '; '; |
| 29 CheckInvalid(preamble + "{ declare " + decl + "}"); |
| 30 CheckInvalid(preamble + "try { declare " + decl + "} catch (x) {}"); |
| 31 CheckInvalid(preamble + "function f() { declare " + decl + "}"); |
| 32 CheckInvalid(preamble + "for (declare " + decl + " of []) {} }"); |
| 33 } |
| 34 |
| 35 |
| 36 function CheckAmbientVariableDeclarations(valid, invalid=valid) { |
| 37 for (var key of ["var", "let", "const"]) { |
| 38 if (key != "const") { |
| 39 valid(key + " x"); |
| 40 valid(key + " x: number"); |
| 41 valid(key + " x, y"); |
| 42 valid(key + " x: number, y: string"); |
| 43 } else { |
| 44 valid(key + " x", key + " x = 42"); |
| 45 valid(key + " x: number", key + " x: number = 42"); |
| 46 valid(key + " x, y", key + " x = 42, y = 'hello'"); |
| 47 valid(key + " x: number, y: string", |
| 48 key + " x: number = 42, y: string = 'hello'"); |
| 49 } |
| 50 valid(key + " [x, y]", key + " [x, y] = [42, 'hello']"); |
| 51 valid(key + " [x, y] : [number, string]", |
| 52 key + " [x, y] : [number, string] = [42, 'hello']"); |
| 53 valid(key + " {a: x, b: y}", |
| 54 key + " {a: x, b: y} = {a: 42, b: 'hello'}"); |
| 55 valid(key + " {a: x, b: y} : {a: number, b: string}", |
| 56 key + " {a: x, b: y} : {a: number, b: string} = {a: 42, b: 'hello'}"); |
| 57 // Simple invalid declarations. |
| 58 invalid(key + " x : ()"); |
| 59 // Initializers are not allowed in ambient variable declarations. |
| 60 invalid(key + " x = 42"); |
| 61 invalid(key + " x: number = 42"); |
| 62 invalid(key + " x = 42, y = 'hello'"); |
| 63 invalid(key + " x: number = 42, y: string = 'hello'"); |
| 64 } |
| 65 } |
| 66 |
| 67 (function TestAmbientVariableDeclarations() { |
| 68 CheckAmbientVariableDeclarations(CheckValidAmbient, CheckInvalidAmbient); |
| 69 CheckAmbientVariableDeclarations(CheckInvalidAmbientInInnerScope); |
| 70 })(); |
| 71 |
| 72 |
| 73 function CheckAmbientFunctionDeclarations(valid, invalid=valid) { |
| 74 function check(decl) { |
| 75 valid(decl, decl + "{}"); |
| 76 invalid(decl + "{}"); // Disallow bodies in ambient function declarations. |
| 77 } |
| 78 check("function f()"); |
| 79 check("function f() : number"); |
| 80 check("function f(x: number)"); |
| 81 check("function f(x: number) : number"); |
| 82 check("function f<A>()"); |
| 83 check("function f<A>() : A"); |
| 84 check("function f<A>(x: A)"); |
| 85 check("function f<A, B>(x: A) : B"); |
| 86 // We allow generators as well. |
| 87 check("function* f()"); |
| 88 check("function* f() : number"); |
| 89 check("function* f(x: number)"); |
| 90 check("function* f(x: number) : number"); |
| 91 check("function* f<A>()"); |
| 92 check("function* f<A>() : A"); |
| 93 check("function* f<A>(x: A)"); |
| 94 check("function* f<A, B>(x: A) : B"); |
| 95 // Simple invalid declarations. |
| 96 invalid("function f() : ()"); |
| 97 invalid("function f(x? = 42) : ()"); |
| 98 invalid("function f<>()"); |
| 99 // The function's name must be present. |
| 100 invalid("function ()"); |
| 101 invalid("function () : number"); |
| 102 invalid("function (x: number)"); |
| 103 invalid("function (x: number) : number"); |
| 104 invalid("function <A>()"); |
| 105 invalid("function <A>() : A"); |
| 106 invalid("function <A>(x: A)"); |
| 107 invalid("function <A, B>(x: A) : B"); |
| 108 } |
| 109 |
| 110 (function TestAmbientFunctionDeclarations() { |
| 111 CheckAmbientFunctionDeclarations(CheckValidAmbient, CheckInvalidAmbient); |
| 112 CheckAmbientFunctionDeclarations(CheckInvalidAmbientInInnerScope); |
| 113 })(); |
| 114 |
| 115 |
| 116 function CheckAmbientClassDeclarations(valid, invalid=valid) { |
| 117 function check(check_header) { |
| 118 check_header("class C"); |
| 119 check_header("class C extends B", "class B {}"); |
| 120 check_header("class C implements I"); |
| 121 check_header("class C implements I, J"); |
| 122 check_header("class C extends B implements I", "class B {}"); |
| 123 check_header("class C extends B implements I, J", "class B {}"); |
| 124 check_header("class C<A, B>"); |
| 125 check_header("class C<A, B> extends D", "class D {}"); |
| 126 check_header("class C<A, B> implements I<A, B>"); |
| 127 check_header("class C<A, B> extends D implements I<A, B>", "class D {}"); |
| 128 } |
| 129 function good(members) { |
| 130 var ambient_body = ""; |
| 131 var body = ""; |
| 132 members.forEach(function([member, suffix='']) { |
| 133 if (suffix != "") suffix = " " + suffix; |
| 134 ambient_body += member + "; "; |
| 135 body += member + suffix + "; "; |
| 136 }); |
| 137 check(function (header, preamble) { |
| 138 valid(header + " {" + ambient_body + "}", |
| 139 header + " {" + body + "}", preamble); |
| 140 }); |
| 141 } |
| 142 function bad(member, suffix='') { |
| 143 check(function (header, preamble) { |
| 144 invalid(header + " {" + member + "}", null, preamble); |
| 145 if (suffix != "") { |
| 146 invalid(header + " {" + member + " " + suffix + "}", null, preamble); |
| 147 } |
| 148 }); |
| 149 } |
| 150 // Test all possible valid members. |
| 151 good([ |
| 152 // constructor |
| 153 ["constructor (x: number, y: boolean)", "{ this.x = x; this.y = y; }"], |
| 154 // variable members |
| 155 ["x"], |
| 156 ["y: boolean"], |
| 157 ["'one': number"], |
| 158 ["'2': boolean"], |
| 159 ["3: string"], |
| 160 // methods |
| 161 ["f1 () : number", "{ return 42; }"], |
| 162 ["f2 (a: number[]) : number", "{ return a[0]; }"], |
| 163 ["f3 (a: number[], b: number) : number", "{ return b || a[0]; }"], |
| 164 ["f4 <A, B>(a: A, b: B) : [A, B]", "{ return [a, b]; }"], |
| 165 // index members |
| 166 ["[x: string]"], |
| 167 ["[x: string] : number"], |
| 168 ["[x: number]"], |
| 169 ["[x: number] : boolean"] |
| 170 ]); |
| 171 // Test all possible valid static members. |
| 172 good([ |
| 173 // variable members |
| 174 ["static x"], |
| 175 ["static y: boolean"], |
| 176 ["static 'one': number"], |
| 177 ["static '2': boolean"], |
| 178 ["static 3: string"], |
| 179 // methods |
| 180 ["static f1 () : number", "{ return 42; }"], |
| 181 ["static f2 (a: number[]) : number", "{ return a[0]; }"], |
| 182 ["static f3 (a: number[], b: number) : number", "{ return b || a[0]; }"], |
| 183 ["static f4 <A, B>(a: A, b: B) : [A, B]", "{ return [a, b]; }"] |
| 184 ]); |
| 185 // Invalid constructors. |
| 186 bad("constructor (a : number) : boolean", "{}"), |
| 187 bad("constructor <A>(a : A)", "{}"); |
| 188 // Initializers in variable members are not allowed. |
| 189 bad("x = 42"), |
| 190 bad("x : number = 42"), |
| 191 bad("'four': number = 4"), |
| 192 bad("'5': boolean = false"), |
| 193 bad("6: string[] = [...['six', 'six', 'and', 'six']]"), |
| 194 // Getters and setters are not allowed, whether valid... |
| 195 bad("get x ()", "{ return 42; }"); |
| 196 bad("get x () : number", "{ return 42; }"); |
| 197 bad("set x (a)", "{}"); |
| 198 bad("set x (a) : void", "{}"); |
| 199 bad("set x (a : number)", "{}"); |
| 200 bad("set x (a : number) : void", "{}"); |
| 201 // ... or invalid. |
| 202 bad("get x (a)", "{ return 42; }"); |
| 203 bad("get x (a) : number", "{ return 42; }"); |
| 204 bad("get x (a, b)", "{ return 42; }"); |
| 205 bad("get x (a, b) : number", "{ return 42; }"); |
| 206 bad("get x (a : number)", "{ return 42; }"); |
| 207 bad("get x (a : number) : number", "{ return 42; }"); |
| 208 bad("get x <A>()", "{ return 42; }"); |
| 209 bad("set x ()", "{}"); |
| 210 bad("set x () : void", "{}"); |
| 211 bad("set x (a : number, b : number)", "{}"); |
| 212 bad("set x (a : number, b : number) : void", "{}"); |
| 213 bad("set x (...rest)", "{}"); |
| 214 bad("set x (...rest : string[]) : void", "{}"); |
| 215 bad("set x <A>(a : A)", "{}"); |
| 216 } |
| 217 |
| 218 (function TestAmbientClassDeclarations() { |
| 219 CheckAmbientClassDeclarations(CheckValidAmbient, CheckInvalidAmbient); |
| 220 CheckAmbientClassDeclarations(CheckInvalidAmbientInInnerScope); |
| 221 })(); |
| 222 |
| 223 (function TestMoreInvalidAmbients() { |
| 224 CheckInvalidAmbient("type N = number"); |
| 225 CheckInvalidAmbient("interface I {}"); |
| 226 CheckInvalidAmbient("x = 42"); |
| 227 CheckInvalidAmbient("{}"); |
| 228 CheckInvalidAmbient("while (true) {}"); |
| 229 })(); |
OLD | NEW |