mirror of
https://github.com/bellard/quickjs.git
synced 2024-11-23 06:08:13 +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;
|
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 0
|
||||||
|
|
||||||
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
|
#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_to_utf8(uint8_t *buf, unsigned int c);
|
||||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
|
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)
|
static inline int from_hex(int c)
|
||||||
{
|
{
|
||||||
|
@ -81,6 +81,7 @@ DEF(empty_string, "")
|
|||||||
DEF(length, "length")
|
DEF(length, "length")
|
||||||
DEF(fileName, "fileName")
|
DEF(fileName, "fileName")
|
||||||
DEF(lineNumber, "lineNumber")
|
DEF(lineNumber, "lineNumber")
|
||||||
|
DEF(columnNumber, "columnNumber")
|
||||||
DEF(message, "message")
|
DEF(message, "message")
|
||||||
DEF(errors, "errors")
|
DEF(errors, "errors")
|
||||||
DEF(stack, "stack")
|
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( 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( 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
|
#if SHORT_OPCODES
|
||||||
DEF( push_minus1, 1, 0, 1, none_int)
|
DEF( push_minus1, 1, 0, 1, none_int)
|
||||||
|
@ -407,6 +407,7 @@ typedef struct JSMemoryUsage {
|
|||||||
int64_t shape_count, shape_size;
|
int64_t shape_count, shape_size;
|
||||||
int64_t js_func_count, js_func_size, js_func_code_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_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 c_func_count, array_count;
|
||||||
int64_t fast_array_count, fast_array_elements;
|
int64_t fast_array_count, fast_array_elements;
|
||||||
int64_t binary_object_count, binary_object_size;
|
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