提交 4cb4f9bc 编写于 作者: A attila

8008814: Configurable ignore/warning/error behavior for function declaration as statement

Reviewed-by: jlaskey, sundar
上级 2e4c92b4
......@@ -37,8 +37,8 @@ import jdk.nashorn.internal.runtime.ECMAErrors;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.JSErrorType;
import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
/**
* Base class for parsers.
......@@ -244,6 +244,16 @@ public abstract class AbstractParser {
return new ParserException(errorType, formatted, source, line, column, token);
}
/**
* Report a warning to the error manager.
*
* @param errorType The error type of the warning
* @param message Warning message.
*/
protected final void warning(final JSErrorType errorType, final String message, final long errorToken) {
errors.warning(error(errorType, message, errorToken));
}
/**
* Generate 'expected' message.
*
......
......@@ -675,9 +675,6 @@ loop:
if (type == FUNCTION) {
// As per spec (ECMA section 12), function declarations as arbitrary statement
// is not "portable". Implementation can issue a warning or disallow the same.
if (isStrictMode && !topLevel) {
throw error(AbstractParser.message("strict.no.func.here"), token);
}
functionExpression(true, topLevel);
return;
}
......@@ -2332,6 +2329,12 @@ loop:
if (isStatement) {
if (topLevel) {
functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
} else if (isStrictMode) {
throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("strict.no.func.decl.here"), functionToken);
} else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.ERROR) {
throw error(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here"), functionToken);
} else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) {
warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken);
}
if (ARGUMENTS.symbolName().equals(name.getName())) {
lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS);
......
......@@ -85,6 +85,33 @@ public final class ScriptEnvironment {
/** Launch using as fx application */
public final boolean _fx;
/**
* Behavior when encountering a function declaration in a lexical context where only statements are acceptable
* (function declarations are source elements, but not statements).
*/
public enum FunctionStatementBehavior {
/**
* Accept the function declaration silently and treat it as if it were a function expression assigned to a local
* variable.
*/
ACCEPT,
/**
* Log a parser warning, but accept the function declaration and treat it as if it were a function expression
* assigned to a local variable.
*/
WARNING,
/**
* Raise a {@code SyntaxError}.
*/
ERROR
}
/**
* Behavior when encountering a function declaration in a lexical context where only statements are acceptable
* (function declarations are source elements, but not statements).
*/
public final FunctionStatementBehavior _function_statement;
/** Should lazy compilation take place */
public final boolean _lazy_compilation;
......@@ -161,6 +188,13 @@ public final class ScriptEnvironment {
_early_lvalue_error = options.getBoolean("early.lvalue.error");
_empty_statements = options.getBoolean("empty.statements");
_fullversion = options.getBoolean("fullversion");
if(options.getBoolean("function.statement.error")) {
_function_statement = FunctionStatementBehavior.ERROR;
} else if(options.getBoolean("function.statement.warning")) {
_function_statement = FunctionStatementBehavior.WARNING;
} else {
_function_statement = FunctionStatementBehavior.ACCEPT;
}
_fx = options.getBoolean("fx");
_lazy_compilation = options.getBoolean("lazy.compilation");
_loader_per_compile = options.getBoolean("loader.per.compile");
......
......@@ -243,7 +243,13 @@ public final class Options {
*/
public String getString(final String key) {
final Option<?> option = get(key);
return option != null ? (String)option.getValue() : null;
if(option != null) {
final String value = (String)option.getValue();
if(value != null) {
return value.intern();
}
}
return null;
}
/**
......
......@@ -144,6 +144,20 @@ nashorn.option.fullversion = { \
desc="Print full version info of Nashorn." \
}
nashorn.option.function.statement.error= { \
name="--function-statement-error", \
desc="Report an error when function declaration is used as a statement.", \
is_undocumented=true, \
default=false \
}
nashorn.option.function.statement.warning = { \
name="--function-statement-warning", \
desc="Warn when function declaration is used as a statement.", \
is_undocumented=true, \
default=false \
}
nashorn.option.fx = { \
name="-fx", \
desc="Launch script as an fx application.", \
......
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* NASHORN-8008814: it's not a compile time error to have a nested strict function declaration when the outer one is not strict
*
* @test
* @run
*/
function f() {
if(true) {
function g() {
"use strict";
print("g invoked!")
}
}
g()
}
f()
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* NASHORN-8008814: it's not a compile time error to have a nested function declaration when warnings are reported
*
* @option --function-statement-warning
* @test
* @run/ignore-std-error
*/
function f() {
if(true) {
function g() {
print("g invoked!")
}
}
g()
}
f()
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* NASHORN-8008814: it's a compile time error to have a nested function declaration when there's an option to treat it as an error
*
* @option --function-statement-error
* @test/compile-error
*/
if(true) {
function g() {
}
}
test/script/error/NASHORN-8008814-1.js:32:2 Function declarations can only occur at program or function body level. You should use a function expression here instead.
function g() {
^
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* NASHORN-8008814: it's a compile time error to have a nested function declaration in strict mode
*
* @test/compile-error
*/
"use strict";
if(true) {
function g() {
}
}
test/script/error/NASHORN-8008814-2.js:32:2 In strict mode, function declarations can only occur at program or function body level. You should use a function expression here instead.
function g() {
^
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册