mirror of https://github.com/svaarala/duktape.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
201 lines
4.0 KiB
201 lines
4.0 KiB
12 years ago
|
/*
|
||
|
* Try statement (E5 Section 12.14).
|
||
|
*/
|
||
|
|
||
|
/*===
|
||
|
===*/
|
||
|
|
||
|
/* FIXME: test for control flow -> normal, canceling with continue, etc */
|
||
|
|
||
|
/*===
|
||
|
foo
|
||
|
Error
|
||
|
foo
|
||
|
try finished
|
||
|
foo
|
||
|
bar
|
||
|
foo
|
||
|
===*/
|
||
|
|
||
|
/* The catch variable has a "let scope", i.e. it uses a temporary declarative
|
||
|
* lexical environment which is only active for the duration of the catch.
|
||
|
* A previous normal variable declaration of the same name is shadowed,
|
||
|
* temporarily.
|
||
|
*/
|
||
|
|
||
|
try {
|
||
|
/* -> foo, Error, foo, try finished */
|
||
|
eval("var e='foo'; print(e);\n" +
|
||
|
"try { throw new Error('error') } catch(e) { print(e.name) };\n" +
|
||
|
"print(e);");
|
||
|
print("try finished");
|
||
|
} catch(e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
/* multiple shadowing -> foo, bar, foo */
|
||
|
eval("try { throw 'foo' } catch(e) { print(e); try { throw 'bar' } catch(e) { print(e) }; print(e) }");
|
||
|
} catch(e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
/* XXX: test shadowing of arguments and function declarations too */
|
||
|
|
||
|
/*===
|
||
|
===*/
|
||
|
|
||
|
/* The catch variable scope may be accessible through a function expression
|
||
|
* created inside the catch clause. The closure may persist indefinitely.
|
||
|
*/
|
||
|
|
||
|
/* FIXME */
|
||
|
|
||
|
/*===
|
||
|
SyntaxError
|
||
|
SyntaxError
|
||
|
SyntaxError
|
||
|
try
|
||
|
finally
|
||
|
try finished
|
||
|
===*/
|
||
|
|
||
|
/* The try-catch-finally statement syntax uses Block (instead of Statement)
|
||
|
* in its syntax for each of the parts. In other words, the parts cannot
|
||
|
* consist of a single statement and MUST begin with an opening curly brace.
|
||
|
* Otherwise, SyntaxError.
|
||
|
*/
|
||
|
|
||
|
try {
|
||
|
/* try-part is not a Block -> SyntaxError */
|
||
|
eval("try\n" +
|
||
|
" print('try');\n" +
|
||
|
"catch (e)\n" +
|
||
|
" { print('catch'); }\n" +
|
||
|
"finally\n" +
|
||
|
" { print('finally'); }");
|
||
|
print("never here");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
/* catch-part is not a Block -> SyntaxError */
|
||
|
eval("try\n" +
|
||
|
" { print('try'); }\n" +
|
||
|
"catch (e)\n" +
|
||
|
" print('catch');\n" +
|
||
|
"finally\n" +
|
||
|
" { print('finally'); }");
|
||
|
print("never here");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
/* finally-part is not a Block -> SyntaxError */
|
||
|
|
||
|
/* Note: 'rhino' rejects a non-Block Statement in try and catch
|
||
|
* parts but allows it here in the finally part.
|
||
|
*/
|
||
|
|
||
|
eval("try\n" +
|
||
|
" { print('try'); }\n" +
|
||
|
"catch (e)\n" +
|
||
|
" { print('catch'); }\n" +
|
||
|
"finally\n" +
|
||
|
" print('finally');");
|
||
|
print("never here");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
/* all parts are Blocks -> 'try' and 'finally' printed */
|
||
|
eval("try\n" +
|
||
|
" { print('try'); }\n" +
|
||
|
"catch (e)\n" +
|
||
|
" { print('catch'); }\n" +
|
||
|
"finally\n" +
|
||
|
" { print('finally'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
/*===
|
||
|
SyntaxError
|
||
|
try
|
||
|
try finished
|
||
|
try
|
||
|
try finished
|
||
|
SyntaxError
|
||
|
SyntaxError
|
||
|
===*/
|
||
|
|
||
|
/* Catch variable name cannot be a reserved word. In strict mode, it also
|
||
|
* cannot be 'eval' or arguments'.
|
||
|
*/
|
||
|
|
||
|
try {
|
||
|
eval("try { print('try'); } catch(if) { print('catch'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
eval("try { print('try'); } catch(eval) { print('catch'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
eval("try { print('try'); } catch(arguments) { print('catch'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
eval("'use strict'; try { print('try'); } catch(eval) { print('catch'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
eval("'use strict'; try { print('try'); } catch(arguments) { print('catch'); }");
|
||
|
print("try finished");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
/*===
|
||
|
false
|
||
|
foo
|
||
|
foo
|
||
|
bar
|
||
|
===*/
|
||
|
|
||
|
/* The catch variable is a non-deletable mutable binding. Attempt to
|
||
|
* delete the variable should fail ('delete' evaluates to false).
|
||
|
*/
|
||
|
|
||
|
try {
|
||
|
/* non-deletable */
|
||
|
eval("try { throw 'foo' } catch (e) { print(delete(e)); print(e); }");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
/* mutable */
|
||
|
eval("try { throw 'foo' } catch (e) { print(e); e = 'bar'; print(e); }");
|
||
|
} catch (e) {
|
||
|
print(e.name);
|
||
|
}
|
||
|
|
||
|
|