Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Unified Diff: test/mjsunit/harmony/typesystem/ambient-declarations.js

Issue 1871923003: Add parsing for ambient declarations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@types-devel
Patch Set: Minor fixes to address code review comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: test/mjsunit/harmony/typesystem/ambient-declarations.js
diff --git a/test/mjsunit/harmony/typesystem/ambient-declarations.js b/test/mjsunit/harmony/typesystem/ambient-declarations.js
new file mode 100644
index 0000000000000000000000000000000000000000..47b3e63689c58ffa76c2850a102df7e9ec36b799
--- /dev/null
+++ b/test/mjsunit/harmony/typesystem/ambient-declarations.js
@@ -0,0 +1,229 @@
+// Copyright 2016 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --harmony-types
+
+
+load("test/mjsunit/harmony/typesystem/testgen.js");
+
+
+function CheckValidAmbient(decl, full, preamble) {
+ preamble = typeof(preamble) === "undefined" ? '' : preamble + '; ';
+ CheckValid(preamble + "declare " + decl);
+ if (typeof(full) === "undefined") full = decl;
+ if (typeof(full) === "null") return;
+ CheckValid(preamble + "declare " + decl + "; " + full);
+}
+
+function CheckInvalidAmbient(decl, full=null, preamble) {
+ preamble = typeof(preamble) === "undefined" ? '' : preamble + '; ';
+ CheckInvalid(preamble + "declare " + decl);
+ if (typeof(full) === "undefined") full = decl;
+ if (typeof(full) === "null") return;
+ CheckInvalid(preamble + "declare " + decl + "; " + full);
+}
+
+function CheckInvalidAmbientInInnerScope(decl, full=null, preamble) {
+ preamble = typeof(preamble) === "undefined" ? '' : preamble + '; ';
+ CheckInvalid(preamble + "{ declare " + decl + "}");
+ CheckInvalid(preamble + "try { declare " + decl + "} catch (x) {}");
+ CheckInvalid(preamble + "function f() { declare " + decl + "}");
+ CheckInvalid(preamble + "for (declare " + decl + " of []) {} }");
+}
+
+
+function CheckAmbientVariableDeclarations(valid, invalid=valid) {
+ for (var key of ["var", "let", "const"]) {
+ if (key != "const") {
+ valid(key + " x");
+ valid(key + " x: number");
+ valid(key + " x, y");
+ valid(key + " x: number, y: string");
+ } else {
+ valid(key + " x", key + " x = 42");
+ valid(key + " x: number", key + " x: number = 42");
+ valid(key + " x, y", key + " x = 42, y = 'hello'");
+ valid(key + " x: number, y: string",
+ key + " x: number = 42, y: string = 'hello'");
+ }
+ valid(key + " [x, y]", key + " [x, y] = [42, 'hello']");
+ valid(key + " [x, y] : [number, string]",
+ key + " [x, y] : [number, string] = [42, 'hello']");
+ valid(key + " {a: x, b: y}",
+ key + " {a: x, b: y} = {a: 42, b: 'hello'}");
+ valid(key + " {a: x, b: y} : {a: number, b: string}",
+ key + " {a: x, b: y} : {a: number, b: string} = {a: 42, b: 'hello'}");
+ // Simple invalid declarations.
+ invalid(key + " x : ()");
+ // Initializers are not allowed in ambient variable declarations.
+ invalid(key + " x = 42");
+ invalid(key + " x: number = 42");
+ invalid(key + " x = 42, y = 'hello'");
+ invalid(key + " x: number = 42, y: string = 'hello'");
+ }
+}
+
+(function TestAmbientVariableDeclarations() {
+ CheckAmbientVariableDeclarations(CheckValidAmbient, CheckInvalidAmbient);
+ CheckAmbientVariableDeclarations(CheckInvalidAmbientInInnerScope);
+})();
+
+
+function CheckAmbientFunctionDeclarations(valid, invalid=valid) {
+ function check(decl) {
+ valid(decl, decl + "{}");
+ invalid(decl + "{}"); // Disallow bodies in ambient function declarations.
+ }
+ check("function f()");
+ check("function f() : number");
+ check("function f(x: number)");
+ check("function f(x: number) : number");
+ check("function f<A>()");
+ check("function f<A>() : A");
+ check("function f<A>(x: A)");
+ check("function f<A, B>(x: A) : B");
+ // We allow generators as well.
+ check("function* f()");
+ check("function* f() : number");
+ check("function* f(x: number)");
+ check("function* f(x: number) : number");
+ check("function* f<A>()");
+ check("function* f<A>() : A");
+ check("function* f<A>(x: A)");
+ check("function* f<A, B>(x: A) : B");
+ // Simple invalid declarations.
+ invalid("function f() : ()");
+ invalid("function f(x? = 42) : ()");
+ invalid("function f<>()");
+ // The function's name must be present.
+ invalid("function ()");
+ invalid("function () : number");
+ invalid("function (x: number)");
+ invalid("function (x: number) : number");
+ invalid("function <A>()");
+ invalid("function <A>() : A");
+ invalid("function <A>(x: A)");
+ invalid("function <A, B>(x: A) : B");
+}
+
+(function TestAmbientFunctionDeclarations() {
+ CheckAmbientFunctionDeclarations(CheckValidAmbient, CheckInvalidAmbient);
+ CheckAmbientFunctionDeclarations(CheckInvalidAmbientInInnerScope);
+})();
+
+
+function CheckAmbientClassDeclarations(valid, invalid=valid) {
+ function check(check_header) {
+ check_header("class C");
+ check_header("class C extends B", "class B {}");
+ check_header("class C implements I");
+ check_header("class C implements I, J");
+ check_header("class C extends B implements I", "class B {}");
+ check_header("class C extends B implements I, J", "class B {}");
+ check_header("class C<A, B>");
+ check_header("class C<A, B> extends D", "class D {}");
+ check_header("class C<A, B> implements I<A, B>");
+ check_header("class C<A, B> extends D implements I<A, B>", "class D {}");
+ }
+ function good(members) {
+ var ambient_body = "";
+ var body = "";
+ members.forEach(function([member, suffix='']) {
+ if (suffix != "") suffix = " " + suffix;
+ ambient_body += member + "; ";
+ body += member + suffix + "; ";
+ });
+ check(function (header, preamble) {
+ valid(header + " {" + ambient_body + "}",
+ header + " {" + body + "}", preamble);
+ });
+ }
+ function bad(member, suffix='') {
+ check(function (header, preamble) {
+ invalid(header + " {" + member + "}", null, preamble);
+ if (suffix != "") {
+ invalid(header + " {" + member + " " + suffix + "}", null, preamble);
+ }
+ });
+ }
+ // Test all possible valid members.
+ good([
+ // constructor
+ ["constructor (x: number, y: boolean)", "{ this.x = x; this.y = y; }"],
+ // variable members
+ ["x"],
+ ["y: boolean"],
+ ["'one': number"],
+ ["'2': boolean"],
+ ["3: string"],
+ // methods
+ ["f1 () : number", "{ return 42; }"],
+ ["f2 (a: number[]) : number", "{ return a[0]; }"],
+ ["f3 (a: number[], b: number) : number", "{ return b || a[0]; }"],
+ ["f4 <A, B>(a: A, b: B) : [A, B]", "{ return [a, b]; }"],
+ // index members
+ ["[x: string]"],
+ ["[x: string] : number"],
+ ["[x: number]"],
+ ["[x: number] : boolean"]
+ ]);
+ // Test all possible valid static members.
+ good([
+ // variable members
+ ["static x"],
+ ["static y: boolean"],
+ ["static 'one': number"],
+ ["static '2': boolean"],
+ ["static 3: string"],
+ // methods
+ ["static f1 () : number", "{ return 42; }"],
+ ["static f2 (a: number[]) : number", "{ return a[0]; }"],
+ ["static f3 (a: number[], b: number) : number", "{ return b || a[0]; }"],
+ ["static f4 <A, B>(a: A, b: B) : [A, B]", "{ return [a, b]; }"]
+ ]);
+ // Invalid constructors.
+ bad("constructor (a : number) : boolean", "{}"),
+ bad("constructor <A>(a : A)", "{}");
+ // Initializers in variable members are not allowed.
+ bad("x = 42"),
+ bad("x : number = 42"),
+ bad("'four': number = 4"),
+ bad("'5': boolean = false"),
+ bad("6: string[] = [...['six', 'six', 'and', 'six']]"),
+ // Getters and setters are not allowed, whether valid...
+ bad("get x ()", "{ return 42; }");
+ bad("get x () : number", "{ return 42; }");
+ bad("set x (a)", "{}");
+ bad("set x (a) : void", "{}");
+ bad("set x (a : number)", "{}");
+ bad("set x (a : number) : void", "{}");
+ // ... or invalid.
+ bad("get x (a)", "{ return 42; }");
+ bad("get x (a) : number", "{ return 42; }");
+ bad("get x (a, b)", "{ return 42; }");
+ bad("get x (a, b) : number", "{ return 42; }");
+ bad("get x (a : number)", "{ return 42; }");
+ bad("get x (a : number) : number", "{ return 42; }");
+ bad("get x <A>()", "{ return 42; }");
+ bad("set x ()", "{}");
+ bad("set x () : void", "{}");
+ bad("set x (a : number, b : number)", "{}");
+ bad("set x (a : number, b : number) : void", "{}");
+ bad("set x (...rest)", "{}");
+ bad("set x (...rest : string[]) : void", "{}");
+ bad("set x <A>(a : A)", "{}");
+}
+
+(function TestAmbientClassDeclarations() {
+ CheckAmbientClassDeclarations(CheckValidAmbient, CheckInvalidAmbient);
+ CheckAmbientClassDeclarations(CheckInvalidAmbientInInnerScope);
+})();
+
+(function TestMoreInvalidAmbients() {
+ CheckInvalidAmbient("type N = number");
+ CheckInvalidAmbient("interface I {}");
+ CheckInvalidAmbient("x = 42");
+ CheckInvalidAmbient("{}");
+ CheckInvalidAmbient("while (true) {}");
+})();

Powered by Google App Engine
This is Rietveld 408576698