michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: // This file tests contextual restrictions for yield and arguments, and is michael@0: // derived from js1_8/genexps/regress-634472.js. michael@0: michael@0: function error(str) { michael@0: var base; michael@0: try { michael@0: // the following line must not be broken up into multiple lines michael@0: base = (function(){try{eval('throw new Error()')}catch(e){return e.lineNumber}})(); eval(str); michael@0: return null; michael@0: } catch (e) { michael@0: e.lineNumber = e.lineNumber - base + 1; michael@0: return e; michael@0: } michael@0: } michael@0: michael@0: const YIELD_PAREN = error("(function*(){(for (y of (yield 1, 2)) y)})").message; michael@0: const GENEXP_YIELD = error("(function*(){(for (x of yield 1) x)})").message; michael@0: const TOP_YIELD = error("yield").message; michael@0: const GENERIC = error("(for)").message; michael@0: const BAD_GENERATOR_SYNTAX = error("(for (x of []) x, 1)").message; michael@0: const MISSING_SEMI = error("yield 1").message; michael@0: const MISSING_PAREN = error("(yield 1)").message; michael@0: const PAREN_PAREN = error("(foo").message; michael@0: const FOR_OF_PAREN = error("(for (x of y, z) w)").message; michael@0: michael@0: const cases = [ michael@0: // Expressions involving yield without a value, not currently implemented. Many michael@0: // of these errors would need to be updated. michael@0: //{ expr: "yield", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield" }, michael@0: //{ expr: "1, yield", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield at end of list" }, michael@0: //{ expr: "yield, 1", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list" }, michael@0: //{ expr: "(yield)", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield, parenthesized" }, michael@0: //{ expr: "(1, yield)", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized" }, michael@0: //{ expr: "(yield, 1)", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized" }, michael@0: //{ expr: "((((yield))))", top: TOP_YIELD, fun: null, gen: GENEXP_YIELD, desc: "deeply nested yield" }, michael@0: //{ expr: "(for (x of []) yield)", top: TOP_YIELD, fun: GENERIC, gen: GENERIC, desc: "simple yield in genexp" }, michael@0: //{ expr: "(for (x of []) yield, 1)", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list in genexp" }, michael@0: //{ expr: "(for (x of []) 1, yield)", top: TOP_YIELD, fun: GENERIC, gen: GENERIC, desc: "simple yield at end of list in genexp" }, michael@0: //{ expr: "(for (x of []) (yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield, parenthesized in genexp" }, michael@0: //{ expr: "(for (x of []) 1, (yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield, parenthesized in list in genexp" }, michael@0: //{ expr: "(for (x of []) (1, yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in genexp" }, michael@0: //{ expr: "(for (x of []) 1, (2, yield))", top: TOP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, desc: "simple yield at end of list, parenthesized in list in genexp" }, michael@0: //{ expr: "(for (x of []) (yield, 1))", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized in genexp" }, michael@0: //{ expr: "(for (x of []) 1, (yield, 2))", top: TOP_YIELD, fun: YIELD_PAREN, gen: YIELD_PAREN, desc: "simple yield in list, parenthesized in list in genexp" }, michael@0: //{ expr: "(for (x of []) (function*() { yield }))", top: null, fun: null, gen: null, desc: "legal yield in nested function" }, michael@0: michael@0: // yield expressions michael@0: { expr: "yield 1", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg" }, michael@0: { expr: "1, yield 2", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: FOR_OF_PAREN, desc: "yield w/ arg at end of list" }, michael@0: { expr: "yield 1, 2", top: MISSING_SEMI, fun: MISSING_SEMI, gen: null, genexp: FOR_OF_PAREN, desc: "yield w/ arg in list" }, michael@0: { expr: "(yield 1)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg, parenthesized" }, michael@0: { expr: "(1, yield 2)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized" }, michael@0: { expr: "(yield 1, 2)", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: YIELD_PAREN, desc: "yield w/ arg in list, parenthesized" }, michael@0: michael@0: // deeply nested yield expressions michael@0: { expr: "((((yield 1))))", top: MISSING_PAREN, fun: MISSING_PAREN, gen: null, genexp: GENEXP_YIELD, desc: "deeply nested yield w/ arg" }, michael@0: michael@0: // arguments michael@0: { expr: "arguments", top: null, fun: null, gen: null, genexp: null, desc: "arguments in list" }, michael@0: { expr: "1, arguments", top: null, fun: null, gen: null, genexp: FOR_OF_PAREN, desc: "arguments in list" }, michael@0: michael@0: // yield in generator expressions michael@0: { expr: "(for (x of []) yield 1)", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg in genexp" }, michael@0: { expr: "(for (x of []) yield 1, 2)", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg in list in genexp" }, michael@0: { expr: "(for (x of []) 1, yield 2)", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg at end of list in genexp" }, michael@0: { expr: "(for (x of []) (yield 1))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg, parenthesized in genexp" }, michael@0: { expr: "(for (x of []) 1, (yield 2))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg, parenthesized in list in genexp" }, michael@0: { expr: "(for (x of []) (1, yield 2))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "yield w/ arg at end of list, parenthesized in genexp" }, michael@0: { expr: "(for (x of []) 1, (2, yield 3))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg at end of list, parenthesized in list in genexp" }, michael@0: { expr: "(for (x of []) (yield 1, 2))", top: YIELD_PAREN, fun: YIELD_PAREN, gen: YIELD_PAREN, genexp: YIELD_PAREN, desc: "yield w/ arg in list, parenthesized in genexp" }, michael@0: { expr: "(for (x of []) 1, (yield 2, 3))", top: PAREN_PAREN, fun: PAREN_PAREN, gen: PAREN_PAREN, genexp: PAREN_PAREN, desc: "yield w/ arg in list, parenthesized in list in genexp" }, michael@0: michael@0: // deeply nested yield in generator expressions michael@0: { expr: "(for (x of []) (((1, yield 2))))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "deeply nested yield in genexp" }, michael@0: { expr: "(for (y of []) (for (x of []) ((1, yield 2))))", top: GENEXP_YIELD, fun: GENEXP_YIELD, gen: GENEXP_YIELD, genexp: GENEXP_YIELD, desc: "deeply nested yield in multiple genexps" }, michael@0: michael@0: // arguments in generator expressions michael@0: { expr: "(for (x of []) arguments)", top: null, fun: null, gen: null, genexp: null, desc: "simple arguments in genexp" }, michael@0: { expr: "(for (x of []) 1, arguments)", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments in list in genexp" }, michael@0: { expr: "(for (x of []) (arguments))", top: null, fun: null, gen: null, genexp: null, desc: "arguments, parenthesized in genexp" }, michael@0: { expr: "(for (x of []) 1, (arguments))", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments, parenthesized in list in genexp" }, michael@0: { expr: "(for (x of []) (1, arguments))", top: null, fun: null, gen: null, genexp: null, desc: "arguments in list, parenthesized in genexp" }, michael@0: { expr: "(for (x of []) 1, (2, arguments))", top: BAD_GENERATOR_SYNTAX, fun: BAD_GENERATOR_SYNTAX, gen: BAD_GENERATOR_SYNTAX, genexp: BAD_GENERATOR_SYNTAX, desc: "arguments in list, parenthesized in list in genexp" }, michael@0: michael@0: // deeply nested arguments in generator expressions michael@0: { expr: "(for (x of []) (((1, arguments))))", top: null, fun: null, gen: null, genexp: null, desc: "deeply nested arguments in genexp" }, michael@0: { expr: "(for (y of []) (for (x of []) ((1, arguments))))", top: null, fun: null, gen: null, genexp: null, desc: "deeply nested arguments in multiple genexps" }, michael@0: michael@0: // legal yield/arguments in nested function michael@0: { expr: "(for (x of []) (function*() { yield 1 }))", top: null, fun: null, gen: null, genexp: null, desc: "legal yield in nested function" }, michael@0: { expr: "(for (x of []) (function() { arguments }))", top: null, fun: null, gen: null, genexp: null, desc: "legal arguments in nested function" }, michael@0: { expr: "(for (x of []) (function() arguments))", top: null, fun: null, gen: null, genexp: null, desc: "legal arguments in nested expression-closure" } michael@0: ]; michael@0: michael@0: //----------------------------------------------------------------------------- michael@0: test(); michael@0: //----------------------------------------------------------------------------- michael@0: michael@0: function splitKeyword(str) { michael@0: return str. michael@0: // replace(/[)] yield/, ')\nyield\n'). michael@0: replace(/yield ([0-9])/, '\nyield $1\n'). michael@0: replace(/yield([^ ]|$)/, '\nyield\n$1'). michael@0: replace(/arguments/, '\narguments\n'); michael@0: } michael@0: michael@0: function expectError1(err, ctx, msg) { michael@0: reportCompare('object', typeof err, 'exn for: ' + msg); michael@0: reportCompare(ctx, err.message, 'exn message for: ' + msg); michael@0: if (ctx !== BAD_GENERATOR_SYNTAX && ctx != PAREN_PAREN && ctx != FOR_OF_PAREN) michael@0: reportCompare(2, err.lineNumber, 'exn token for: ' + msg); michael@0: } michael@0: michael@0: function expectError(expr, wrapCtx, expect, msg) { michael@0: expectError1(error(wrapCtx(expr)), expect, msg); michael@0: } michael@0: michael@0: function expectSuccess(err, msg) { michael@0: reportCompare(null, err, 'parse: ' + msg); michael@0: } michael@0: michael@0: function atTop(str) { return str } michael@0: function inFun(str) { return '(function(){' + str + '})' } michael@0: function inGen(str) { return '(function*(){' + str + '})' } michael@0: function inGenExp(str) { return '(for (y of ' + str + ') y)' } michael@0: michael@0: function test() michael@0: { michael@0: enterFunc ('test'); michael@0: printBugNumber(BUGNUMBER); michael@0: printStatus (summary); michael@0: michael@0: for (var i = 0, len = cases.length; i < len; i++) { michael@0: var expr, top, fun, gen, genexp, desc; michael@0: expr = cases[i].expr; michael@0: top = cases[i].top; michael@0: fun = cases[i].fun; michael@0: gen = cases[i].gen; michael@0: genexp = cases[i].genexp; michael@0: desc = cases[i].desc; michael@0: michael@0: expr = splitKeyword(expr); michael@0: michael@0: if (top) michael@0: expectError(expr, atTop, top, 'top-level context, ' + desc); michael@0: else michael@0: expectSuccess(error(expr), 'top-level context, ' + desc); michael@0: michael@0: if (fun) michael@0: expectError(expr, inFun, fun, 'function context, ' + desc); michael@0: else michael@0: expectSuccess(error(inFun(expr)), 'function context, ' + desc); michael@0: michael@0: if (gen) michael@0: expectError(expr, inGen, gen, 'generator context, ' + desc); michael@0: else michael@0: expectSuccess(error(inGen(expr)), 'generator context, ' + desc); michael@0: michael@0: if (genexp) michael@0: expectError(expr, inGenExp, genexp, 'genexp context, ' + desc); michael@0: else michael@0: expectSuccess(error(inGenExp(expr)), 'genexp context, ' + desc); michael@0: } michael@0: michael@0: exitFunc ('test'); michael@0: }