Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

const [y, y] = [] throws a TypeError, instead of SyntaxError #989

Closed
p-bakker opened this issue Jul 5, 2021 · 7 comments
Closed

const [y, y] = [] throws a TypeError, instead of SyntaxError #989

p-bakker opened this issue Jul 5, 2021 · 7 comments
Labels
bug Issues considered a bug Ecma Incompatibility Issues about Rhino being incompatible with the EcmaScript spec

Comments

@p-bakker
Copy link
Collaborator

p-bakker commented Jul 5, 2021

Followup of #386

@p-bakker p-bakker added bug Issues considered a bug Ecma Incompatibility Issues about Rhino being incompatible with the EcmaScript spec labels Jul 5, 2021
@p-bakker p-bakker changed the title const [y, y] = [] throwsa TypeError, instead of SyntaxError const [y, y] = [] throws a TypeError, instead of SyntaxError Jul 5, 2021
@tuchida
Copy link
Contributor

tuchida commented Jul 6, 2021

Perhaps this is the same problem.

const y = undefined;
const y = undefined; // SyntaxError, but TypeError in Rhino

It should not be possible to achieve this without implementing TDZ.

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 7, 2021

Is this really related to TDZ? IMHO this is just about redeclaration of a const, whereas TDZ is about accessing a const before it is declared, with let/const not being hoisted to the top of a function like vars, but only being defined as the point in the code where they are declared, so any code accessing them before they are declared is what TDZ is about (AFAIK)

@tuchida
Copy link
Contributor

tuchida commented Jul 7, 2021

Sorry, this may not be directly related.
However, if the redeclaration check is to be done in the parse phase instead of the execution phase, I think TDZ will have to be implemented at the same time.

@p-bakker
Copy link
Collaborator Author

p-bakker commented Jul 7, 2021

To my knowledge TDZ issues throw a ReferenceError and I think those are runtime errors, not parse-time errors.

And redeclaration of const/let throws a SyntaxError, which is a parse-time error I think

@tuchida
Copy link
Contributor

tuchida commented Jul 16, 2024

ref. #1519, #1520
After applying these, I got the following error.
I made a merging mistake. It will still be a TypeError as before.

$ ./gradlew run -q --console=plain --args="-version 200"
Rhino 1.7.16-SNAPSHOT
js> const [y, y] = []
js: line 2: TypeError: redeclaration of const y.
js: 
js: ^

@tuchida
Copy link
Contributor

tuchida commented Jul 19, 2024

Errors whose message starts with TypeError: are TypeError.

@Override
public void error(String message, String sourceURI, int line, String lineText, int lineOffset) {
if (forEval) {
// Assume error message strings that start with "TypeError: "
// should become TypeError exceptions. A bit of a hack, but we
// don't want to change the ErrorReporter interface.
String error = "SyntaxError";
final String TYPE_ERROR_NAME = "TypeError";
final String DELIMETER = ": ";
final String prefix = TYPE_ERROR_NAME + DELIMETER;
if (message.startsWith(prefix)) {
error = TYPE_ERROR_NAME;
message = message.substring(prefix.length());
}
throw ScriptRuntime.constructError(
error, message, sourceURI, line, lineText, lineOffset);
}

Perhaps all of these are fine with SyntaxError.

msg.var.redecl =\
TypeError: redeclaration of var {0}.
msg.const.redecl =\
TypeError: redeclaration of const {0}.
msg.let.redecl =\
TypeError: redeclaration of variable {0}.
msg.parm.redecl =\
TypeError: redeclaration of formal parameter {0}.
msg.fn.redecl =\
TypeError: redeclaration of function {0}.

msg.generator.returns =\
TypeError: generator function {0} returns a value
msg.anon.generator.returns =\
TypeError: anonymous generator function returns a value

// old generator
function g() { return 0; yield 1; }
// js: "<stdin>", line 2: TypeError: generator function g returns a value
// js: function g() { return 0; yield 1; }
// js: ................................^
// js: "<stdin>", line 2: Compilation produced 1 syntax errors.

// latest generator
function *g() { return 0; yield 1; }  // no error

However, TypeError is correct if the constant is overwritten at runtime. A different message would be needed in this case.

public static void redefineProperty(Scriptable obj, String name, boolean isConst) {
Scriptable base = getBase(obj, name);
if (base == null) return;
if (base instanceof ConstProperties) {
ConstProperties cp = (ConstProperties) base;
if (cp.isConst(name)) throw ScriptRuntime.typeErrorById("msg.const.redecl", name);
}
if (isConst) throw ScriptRuntime.typeErrorById("msg.var.redecl", name);

function NaN() {} // TypeError

@tuchida
Copy link
Contributor

tuchida commented Jul 21, 2024

Fixed by #1530.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issues considered a bug Ecma Incompatibility Issues about Rhino being incompatible with the EcmaScript spec
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

2 participants