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.ErrorManager;
|
||||||
import jdk.nashorn.internal.runtime.JSErrorType;
|
import jdk.nashorn.internal.runtime.JSErrorType;
|
||||||
import jdk.nashorn.internal.runtime.ParserException;
|
import jdk.nashorn.internal.runtime.ParserException;
|
||||||
import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
|
|
||||||
import jdk.nashorn.internal.runtime.Source;
|
import jdk.nashorn.internal.runtime.Source;
|
||||||
|
import jdk.nashorn.internal.runtime.regexp.RegExpFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for parsers.
|
* Base class for parsers.
|
||||||
@ -244,6 +244,16 @@ public abstract class AbstractParser {
|
|||||||
return new ParserException(errorType, formatted, source, line, column, token);
|
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.
|
* Generate 'expected' message.
|
||||||
*
|
*
|
||||||
|
@ -675,9 +675,6 @@ loop:
|
|||||||
if (type == FUNCTION) {
|
if (type == FUNCTION) {
|
||||||
// As per spec (ECMA section 12), function declarations as arbitrary statement
|
// As per spec (ECMA section 12), function declarations as arbitrary statement
|
||||||
// is not "portable". Implementation can issue a warning or disallow the same.
|
// 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);
|
functionExpression(true, topLevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2332,6 +2329,12 @@ loop:
|
|||||||
if (isStatement) {
|
if (isStatement) {
|
||||||
if (topLevel) {
|
if (topLevel) {
|
||||||
functionNode = functionNode.setFlag(lc, FunctionNode.IS_DECLARED);
|
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())) {
|
if (ARGUMENTS.symbolName().equals(name.getName())) {
|
||||||
lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS);
|
lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS);
|
||||||
|
@ -85,6 +85,33 @@ public final class ScriptEnvironment {
|
|||||||
/** Launch using as fx application */
|
/** Launch using as fx application */
|
||||||
public final boolean _fx;
|
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 */
|
/** Should lazy compilation take place */
|
||||||
public final boolean _lazy_compilation;
|
public final boolean _lazy_compilation;
|
||||||
|
|
||||||
@ -161,6 +188,13 @@ public final class ScriptEnvironment {
|
|||||||
_early_lvalue_error = options.getBoolean("early.lvalue.error");
|
_early_lvalue_error = options.getBoolean("early.lvalue.error");
|
||||||
_empty_statements = options.getBoolean("empty.statements");
|
_empty_statements = options.getBoolean("empty.statements");
|
||||||
_fullversion = options.getBoolean("fullversion");
|
_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");
|
_fx = options.getBoolean("fx");
|
||||||
_lazy_compilation = options.getBoolean("lazy.compilation");
|
_lazy_compilation = options.getBoolean("lazy.compilation");
|
||||||
_loader_per_compile = options.getBoolean("loader.per.compile");
|
_loader_per_compile = options.getBoolean("loader.per.compile");
|
||||||
|
@ -243,7 +243,13 @@ public final class Options {
|
|||||||
*/
|
*/
|
||||||
public String getString(final String key) {
|
public String getString(final String key) {
|
||||||
final Option<?> option = get(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." \
|
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 = { \
|
nashorn.option.fx = { \
|
||||||
name="-fx", \
|
name="-fx", \
|
||||||
desc="Launch script as an fx application.", \
|
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