mirror of
https://github.com/bellard/quickjs.git
synced 2024-11-22 21:58:12 +08:00
feat: add column number
This commit is contained in:
parent
2788d71e82
commit
00ed5215e2
10
cutils.c
10
cutils.c
@ -303,6 +303,16 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
|
||||
return c;
|
||||
}
|
||||
|
||||
int utf8_str_len(const uint8_t *p_start, const uint8_t *p_end) {
|
||||
int count = 0;
|
||||
while (p_start < p_end) {
|
||||
if (!unicode_from_utf8(p_start, UTF8_CHAR_LEN_MAX, &p_start))
|
||||
break;
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
|
||||
|
1
cutils.h
1
cutils.h
@ -277,6 +277,7 @@ static inline void dbuf_set_error(DynBuf *s)
|
||||
|
||||
int unicode_to_utf8(uint8_t *buf, unsigned int c);
|
||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
|
||||
int utf8_str_len(const uint8_t *p_start, const uint8_t *p_end);
|
||||
|
||||
static inline int from_hex(int c)
|
||||
{
|
||||
|
@ -81,6 +81,7 @@ DEF(empty_string, "")
|
||||
DEF(length, "length")
|
||||
DEF(fileName, "fileName")
|
||||
DEF(lineNumber, "lineNumber")
|
||||
DEF(columnNumber, "columnNumber")
|
||||
DEF(message, "message")
|
||||
DEF(errors, "errors")
|
||||
DEF(stack, "stack")
|
||||
|
@ -284,6 +284,7 @@ def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phas
|
||||
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
|
||||
|
||||
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
|
||||
def( column_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
|
||||
|
||||
#if SHORT_OPCODES
|
||||
DEF( push_minus1, 1, 0, 1, none_int)
|
||||
|
@ -407,6 +407,7 @@ typedef struct JSMemoryUsage {
|
||||
int64_t shape_count, shape_size;
|
||||
int64_t js_func_count, js_func_size, js_func_code_size;
|
||||
int64_t js_func_pc2line_count, js_func_pc2line_size;
|
||||
int64_t js_func_pc2column_count, js_func_pc2column_size;
|
||||
int64_t c_func_count, array_count;
|
||||
int64_t fast_array_count, fast_array_elements;
|
||||
int64_t binary_object_count, binary_object_size;
|
||||
|
240
tests/test_line_column.js
Normal file
240
tests/test_line_column.js
Normal file
@ -0,0 +1,240 @@
|
||||
"use strict";
|
||||
|
||||
function assert(actual, expected, message) {
|
||||
if (arguments.length == 1) expected = true;
|
||||
|
||||
if (actual === expected) return;
|
||||
|
||||
if (actual !== null && expected !== null && typeof actual == 'object' &&
|
||||
typeof expected == 'object' && actual.toString() === expected.toString())
|
||||
return;
|
||||
|
||||
throw Error(
|
||||
'assertion failed: got |' + actual + '|' +
|
||||
', expected |' + expected + '|' + (message ? ' (' + message + ')' : ''));
|
||||
}
|
||||
|
||||
/** id not exists -> should be located at id */
|
||||
function test_line_column1() {
|
||||
try {
|
||||
eval(`'【';A;`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column1');
|
||||
assert(e.columnNumber, 5, 'test_line_column1');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* memeber call should be located at id:
|
||||
* a.b.c() and c is null -> c will be located
|
||||
*/
|
||||
function test_line_column2() {
|
||||
try {
|
||||
eval(`
|
||||
var a = { b: { c: { d: null }} };
|
||||
a.b.c.d();
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 3, 'test_line_column2');
|
||||
assert(e.columnNumber, 7, 'test_line_column2');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* memeber call should be located at id:
|
||||
* a.b.c() and b is null -> c will be located
|
||||
*/
|
||||
function test_line_column3() {
|
||||
try {
|
||||
eval(`
|
||||
var a = { b: { c: { d: null }} };
|
||||
a.f.c.d();
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 3, 'test_line_column3');
|
||||
assert(e.columnNumber, 5, 'test_line_column3');
|
||||
}
|
||||
}
|
||||
|
||||
/** if id not exists -> should be located at id */
|
||||
function test_line_column4() {
|
||||
try {
|
||||
eval(`(function(){'use strict';a;}());`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column4');
|
||||
assert(e.columnNumber, 26, 'test_line_column4');
|
||||
}
|
||||
}
|
||||
|
||||
/** if id not exists -> should be located at id */
|
||||
function test_line_column5() {
|
||||
try {
|
||||
eval(`'【';1+1;new A();`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column5');
|
||||
assert(e.columnNumber, 13, 'test_line_column5');
|
||||
}
|
||||
}
|
||||
|
||||
/** new call should be located at 'new' */
|
||||
function test_line_column6() {
|
||||
try {
|
||||
eval(`'【';1+1;throw new Error();`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column6');
|
||||
assert(e.columnNumber, 15, 'test_line_column6');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* normal call should be located at function name:
|
||||
* a() and a is null or occur error -> a will be located
|
||||
*/
|
||||
function test_line_column7() {
|
||||
try {
|
||||
eval(`1+1;a();`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column7');
|
||||
assert(e.columnNumber, 5, 'test_line_column7');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if comment is first line,
|
||||
* the line number of one line should be locate at next line
|
||||
*/
|
||||
function test_line_column8() {
|
||||
try {
|
||||
eval(`
|
||||
/**
|
||||
* something
|
||||
* comment
|
||||
* here
|
||||
*/
|
||||
1+1;a();
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 7, 'test_line_column8');
|
||||
assert(e.columnNumber, 5, 'test_line_column8');
|
||||
}
|
||||
}
|
||||
|
||||
/** nest function call */
|
||||
function test_line_column9() {
|
||||
try {
|
||||
eval(`(function(){'【'(function(){'use strict';a;}())}())`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column9');
|
||||
assert(e.columnNumber, 41, 'test_line_column9');
|
||||
}
|
||||
}
|
||||
|
||||
/** multi function call */
|
||||
function test_line_column10() {
|
||||
try {
|
||||
eval(`
|
||||
function a(){
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
function b(){
|
||||
a();
|
||||
}
|
||||
|
||||
b();
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 3, 'test_line_column10');
|
||||
assert(e.columnNumber, 11, 'test_line_column10');
|
||||
}
|
||||
}
|
||||
|
||||
/** syntax error should be located at latest token position */
|
||||
function test_line_column11() {
|
||||
try {
|
||||
eval(`
|
||||
var a = {
|
||||
b: if(1){}
|
||||
}
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 3, 'test_line_column11');
|
||||
assert(e.columnNumber, 7, 'test_line_column11');
|
||||
}
|
||||
}
|
||||
|
||||
/** string template cases */
|
||||
function test_line_column12() {
|
||||
// case 1
|
||||
try {
|
||||
eval(`
|
||||
var a = \`\$\{b;\}
|
||||
1+1
|
||||
\`;
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 2, 'test_line_column12');
|
||||
assert(e.columnNumber, 12, 'test_line_column12');
|
||||
}
|
||||
|
||||
// case 2
|
||||
try {
|
||||
eval(`
|
||||
var a = \`1+1
|
||||
\$\{b;\}
|
||||
2+2
|
||||
\`;
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 3, 'test_line_column12');
|
||||
assert(e.columnNumber, 3, 'test_line_column12');
|
||||
}
|
||||
|
||||
// case 3
|
||||
try {
|
||||
eval(`
|
||||
var a = \`1+1
|
||||
2+2
|
||||
\${b\}\`;
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 4, 'test_line_column12');
|
||||
assert(e.columnNumber, 3, 'test_line_column12');
|
||||
}
|
||||
|
||||
// case 4
|
||||
try {
|
||||
eval(`
|
||||
var a = \`1+1
|
||||
2+2
|
||||
\${3+3\}\`;b;
|
||||
`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 4, 'test_line_column12');
|
||||
assert(e.columnNumber, 9, 'test_line_column12');
|
||||
}
|
||||
}
|
||||
|
||||
/** dynamic Function parse error should be located the latest token */
|
||||
function test_line_column13() {
|
||||
try {
|
||||
eval(`Function("===>", "a");`);
|
||||
} catch (e) {
|
||||
assert(e.lineNumber, 1, 'test_line_column13');
|
||||
assert(e.columnNumber, 20, 'test_line_column13');
|
||||
}
|
||||
}
|
||||
|
||||
test_line_column1();
|
||||
test_line_column2();
|
||||
test_line_column3();
|
||||
test_line_column4();
|
||||
test_line_column5();
|
||||
test_line_column6();
|
||||
test_line_column7();
|
||||
test_line_column8();
|
||||
test_line_column9();
|
||||
test_line_column10();
|
||||
test_line_column11();
|
||||
test_line_column12();
|
||||
test_line_column13();
|
Loading…
Reference in New Issue
Block a user