8008814: Configurable ignore/warning/error behavior for function declaration as statement
Reviewed-by: jlaskey, sundar
This commit is contained in:
parent
56129142b0
commit
8c132a0300
@ -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.", \
|
||||
|
40
nashorn/test/script/basic/JDK-8008814-3.js
Normal file
40
nashorn/test/script/basic/JDK-8008814-3.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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()
|
1
nashorn/test/script/basic/JDK-8008814-3.js.EXPECTED
Normal file
1
nashorn/test/script/basic/JDK-8008814-3.js.EXPECTED
Normal file
@ -0,0 +1 @@
|
||||
g invoked!
|
40
nashorn/test/script/basic/JDK-8008814-4.js
Normal file
40
nashorn/test/script/basic/JDK-8008814-4.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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()
|
1
nashorn/test/script/basic/JDK-8008814-4.js.EXPECTED
Normal file
1
nashorn/test/script/basic/JDK-8008814-4.js.EXPECTED
Normal file
@ -0,0 +1 @@
|
||||
g invoked!
|
34
nashorn/test/script/error/JDK-8008814-1.js
Normal file
34
nashorn/test/script/error/JDK-8008814-1.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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() {
|
||||
}
|
||||
}
|
3
nashorn/test/script/error/JDK-8008814-1.js.EXPECTED
Normal file
3
nashorn/test/script/error/JDK-8008814-1.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
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() {
|
||||
^
|
34
nashorn/test/script/error/JDK-8008814-2.js
Normal file
34
nashorn/test/script/error/JDK-8008814-2.js
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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() {
|
||||
}
|
||||
}
|
3
nashorn/test/script/error/JDK-8008814-2.js.EXPECTED
Normal file
3
nashorn/test/script/error/JDK-8008814-2.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
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() {
|
||||
^
|
Loading…
x
Reference in New Issue
Block a user