├── .gitattributes ├── .gitignore ├── LICENSE.txt ├── README.md ├── dist └── .gitignore ├── scripts ├── archive_test262.js ├── data │ ├── id_continue.txt │ ├── id_other.txt │ ├── id_space_separator.txt │ └── id_start.txt ├── postinstall.js └── unicode_binary_search.js ├── src ├── common.h ├── constants.h ├── interface.h ├── interface.js ├── memory.h ├── messages.h ├── nodes.h ├── package.json ├── parser.c ├── parser.h ├── parser_wasm.c ├── scanner.h ├── scope.h └── unicode │ ├── id_continue.h │ └── id_start.h └── test ├── benchmark.js ├── compare.js ├── data ├── native │ ├── declarations │ │ ├── class.js │ │ ├── function │ │ │ ├── function.js │ │ │ └── generator.js │ │ ├── module │ │ │ ├── export.js │ │ │ └── import.js │ │ └── variable │ │ │ ├── array_binding.js │ │ │ ├── object_binding.js │ │ │ └── variable.js │ ├── expressions │ │ ├── arrow_cover.js │ │ ├── arrow_function.js │ │ ├── assignment │ │ │ ├── assignment.js │ │ │ └── destructuring.js │ │ ├── binary.js │ │ ├── call.js │ │ ├── function.js │ │ ├── identifier.js │ │ ├── member.js │ │ ├── optional.js │ │ ├── super.js │ │ └── unary.js │ ├── literals │ │ ├── .gitattributes │ │ ├── array.js │ │ ├── numeric.js │ │ ├── object.js │ │ ├── regexp.js │ │ ├── string.js │ │ └── template.js │ ├── misc │ │ ├── auto_semicolon.js │ │ ├── code.js │ │ ├── contextual_keywords.js │ │ ├── keywords │ │ │ ├── _keywords.js │ │ │ ├── _keywords.tmpl.js │ │ │ ├── await_in_module.js │ │ │ ├── contextual.js │ │ │ ├── reserved_words.js │ │ │ ├── reserved_words.manual.js │ │ │ └── strict_mode.js │ │ ├── lexical_uniqueness │ │ │ ├── arrow_expression.js │ │ │ ├── declarative_statements.js │ │ │ ├── formal_parameters.js │ │ │ ├── function_declaration.js │ │ │ └── variable_declarations.js │ │ └── strict_mode │ │ │ ├── directive.js │ │ │ ├── invalid.js │ │ │ ├── keywords │ │ │ ├── _keywords.js │ │ │ ├── _keywords.tmpl.js │ │ │ └── keywords.js │ │ │ └── literals.js │ ├── statements │ │ ├── directive.js │ │ ├── for.js │ │ ├── if.js │ │ ├── jump.js │ │ ├── labeled.js │ │ ├── switch.js │ │ ├── try.js │ │ └── with.js │ └── tokenizer │ │ ├── .gitattributes │ │ ├── comment.js │ │ ├── context.js │ │ ├── identifier.js │ │ ├── location.js │ │ ├── newline.js │ │ ├── regexp.js │ │ └── whitespace.js ├── pass │ └── libraries │ │ ├── acorn-8.0.1.es6.js │ │ ├── angular-1.8.0.js │ │ ├── angular-1.8.0.min.js │ │ ├── jquery-3.5.1.js │ │ ├── jquery-3.5.1.min.js │ │ └── tsserver-3.4.5.js └── test262 │ └── .gitignore ├── debug ├── main.js └── parser.html ├── expander.js ├── object_diff.js ├── package-lock.json ├── package.json └── test.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.h linguist-language=C 2 | test/data/pass/libraries/* linguist-vendored 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ignore 2 | build 3 | node_modules 4 | src/simd 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Eumerics Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Falcon Parser 2 | 3 | A blazing fast, memory efficient ECMAScript parser written in C and compiled to WebAssembly. It is a standalone library with no dependencies and a lean code. The library can be compiled to WebAssembly without the need for heavy toolchains such as Emscripten. Hence the glue code required to load the WebAssembly code is minimal. 4 | 5 | 6 | # Performance 7 | 8 | On average `falcon` parser is **5x-7x** faster than the best performing cold run library `web-tree-sitter`, while **3x-4x** faster than the best performing hot run library `meriyah`. 9 | 10 | Benchmark results of cold parse times computed with [benchmark.js](https://benchmarkjs.com/) library are tabulated below. Each parse is executed in a separate worker thread to prevent JIT compiler optimizations from kicking in. 11 | 12 | | | falcon-0.x.0 | acorn-8.0.1 | meriyah-2.1.0 | tree-sitter-0.17.1 | 13 | |-------------------:|-------------------:|-------------------:|-------------------:|-------------------:| 14 | | jquery-3.5.1.js | ` 6.9 ms ± 3%`| `127.6 ms ± 1%`| ` 83.1 ms ± 1%`| ` 45.0 ms ± 2%`| 15 | | angular-1.8.0.js | ` 22.0 ms ± 2%`| `217.3 ms ± 1%`| `176.0 ms ± 1%`| `108.8 ms ± 3%`| 16 | | react-17.0.1.js | ` 2.6 ms ± 3%`| ` 64.9 ms ± 1%`| ` 51.4 ms ± 3%`| ` 18.4 ms ± 4%`| 17 | 18 | Tabulated below are the benchmark results of hot parse times which reflect JIT compiler optimizations that kick in after repetitive invocations of parsing possibly within a short span of time. 19 | 20 | | | falcon-0.x.0 | acorn-8.0.1 | meriyah-2.1.0 | tree-sitter-0.17.1 | 21 | |-------------------:|-------------------:|-------------------:|-------------------:|-------------------:| 22 | | jquery-3.5.1.js | ` 4.6 ms ± 1%`| ` 24.4 ms ± 8%`| ` 16.6 ms ±18%`| ` 38.8 ms ± 1%`| 23 | | angular-1.8.0.js | ` 10.0 ms ± 1%`| ` 53.5 ms ± 8%`| ` 45.7 ms ±13%`| ` 99.1 ms ± 1%`| 24 | | react-17.0.1.js | ` 1.3 ms ± 1%`| ` 3.9 ms ± 1%`| ` 2.2 ms ± 2%`| ` 12.0 ms ± 1%`| 25 | 26 | ##### Caveats 27 | The above benchmarks measure pure parsing performance. Accessing syntax tree built on the WebAssembly side via JavaScript bindings introduces additional overheads. [WebAssembly GC Propsoal](https://github.com/WebAssembly/gc/blob/master/proposals/gc/Overview.md "WebAssembly GC Propsoal") will reduce these overheads. 28 | -------------------------------------------------------------------------------- /dist/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /scripts/archive_test262.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const child_process = require('child_process'); 4 | const base = `${__dirname}/../test/node_modules/test262-parser-tests`; 5 | const incorrect_fail_tests = [ 6 | '0d5e450f1da8a92a.js', // ('\9') 7 | '748656edbfb2d0bb.js', // ('\8') 8 | '79f882da06f88c9f.js', // "\8"; 9 | '92b6af54adef3624.js', // "\9"; 10 | '647e21f8f157c338.js', // '' 11 | '8af69d8f15295ed2.js', // '' 12 | 'e3fbcf63d7e43ead.js' // for-in var initializer 13 | ]; 14 | const incorrect_early_tests = [ 15 | '0f5f47108da5c34e.js', 16 | '12a74c60f52a60de.js', 17 | '1aff49273f3e3a98.js', 18 | 'be7329119eaa3d47.js', 19 | 'ec31fa5e521c5df4.js' 20 | ]; 21 | for(const test_name of incorrect_fail_tests) { 22 | const file_path = path.normalize(`${base}/fail/${test_name}`); 23 | if(fs.existsSync(file_path)) fs.renameSync(file_path, `${base}/pass/${test_name}`); 24 | } 25 | for(const test_name of incorrect_early_tests) { 26 | const file_path = path.normalize(`${base}/early/${test_name}`); 27 | if(fs.existsSync(file_path)) fs.renameSync(file_path, `${base}/pass/${test_name}`); 28 | } 29 | for(const suite of ['pass', 'pass-explicit', 'fail', 'early']) { 30 | child_process.spawn( 31 | path.normalize(`${__dirname}/../test/node_modules/.bin/asar`), [ 32 | 'p', 33 | path.normalize(`${base}/${suite}`), 34 | path.normalize(`${__dirname}/../test/data/test262/${suite}.asar`) 35 | ], {shell: true} 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /scripts/data/id_other.txt: -------------------------------------------------------------------------------- 1 | # Extracted from https://www.unicode.org/Public/UCD/latest/ucd/PropList.txt 2 | 3 | # ================================================ 4 | 5 | 1885..1886 ; Other_ID_Start # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA 6 | 2118 ; Other_ID_Start # Sm SCRIPT CAPITAL P 7 | 212E ; Other_ID_Start # So ESTIMATED SYMBOL 8 | 309B..309C ; Other_ID_Start # Sk [2] KATAKANA-HIRAGANA VOICED SOUND MARK..KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK 9 | 10 | # Total code points: 6 11 | 12 | # ================================================ 13 | 14 | 00B7 ; Other_ID_Continue # Po MIDDLE DOT 15 | 0387 ; Other_ID_Continue # Po GREEK ANO TELEIA 16 | 1369..1371 ; Other_ID_Continue # No [9] ETHIOPIC DIGIT ONE..ETHIOPIC DIGIT NINE 17 | 19DA ; Other_ID_Continue # No NEW TAI LUE THAM DIGIT ONE 18 | 19 | # Total code points: 12 20 | -------------------------------------------------------------------------------- /scripts/data/id_space_separator.txt: -------------------------------------------------------------------------------- 1 | # Extracted from https://www.unicode.org/Public/UCD/latest/ucd/Scripts.txt 2 | # There is no section for Space_Separator, the following entries are collated 3 | 4 | 0020 ; Common # Zs SPACE 5 | 00A0 ; Common # Zs NO-BREAK SPACE 6 | 1680 ; Ogham # Zs OGHAM SPACE MARK 7 | 2000..200A ; Common # Zs [11] EN QUAD..HAIR SPACE 8 | 202F ; Common # Zs NARROW NO-BREAK SPACE 9 | 205F ; Common # Zs MEDIUM MATHEMATICAL SPACE 10 | 3000 ; Common # Zs IDEOGRAPHIC SPACE 11 | -------------------------------------------------------------------------------- /scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | //require('./archive_test262'); 2 | 3 | const fs = require('fs'); 4 | const url = require('url'); 5 | const https = require('https'); 6 | const download = function(link, file_path) { 7 | return new Promise((resolve, reject) => { 8 | const options = url.parse(link); 9 | const file = fs.createWriteStream(file_path); 10 | https.get(options, function(res) { 11 | res.on('data', function(data) { 12 | file.write(data); 13 | }).on('end', function() { 14 | file.end(); 15 | resolve(); 16 | }); 17 | }).on('error', function(err) { 18 | file.end(); 19 | reject(err); 20 | }); 21 | }); 22 | }; 23 | const tsparser_url = 'https://raw.githubusercontent.com/tree-sitter/tree-sitter.github.io/master/tree-sitter-javascript.wasm'; 24 | const tsparser_path = `${__dirname}/../test/node_modules/web-tree-sitter/tree-sitter-javascript.wasm`; 25 | download(tsparser_url, tsparser_path); 26 | -------------------------------------------------------------------------------- /scripts/unicode_binary_search.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const file_name = process.argv[2]; 3 | const content = fs.readFileSync(file_name).toString(); 4 | const property = file_name.replace(/^(?:.+\/)?([^/]+)\.[^.]+$/, '$1'); 5 | 6 | let range_first, range_last, ranges = []; 7 | const pad = (s, n1, n2, c) => ( 8 | (Array(s.length > n1 ? n2 : n1).fill(c).join('') + s).substring(s.length) 9 | ); 10 | const hex_literal = n => '0x' + pad(n.toString(16).toUpperCase(), 4, 6, '0'); 11 | for(const line of content.split(/\r\n?|\n/g)) 12 | { 13 | if(line.length == 0 || line.startsWith('#')) continue; 14 | let [first, last = first] = line.split(';')[0].trim().split('..'); 15 | [first, last] = [first, last].map(x => Number(`0x${x}`)); 16 | // join consequent ranges 17 | if(range_last + 1 == first){ 18 | range_last = last; 19 | } else { 20 | if(range_first !== undefined) { 21 | //if(!((range_first & 0xffffff80) == 0 && (range_last & 0xffffff80) == 0)) { 22 | ranges.push({first: range_first, last: range_last}); 23 | //console.log(hex_literal(range_first), hex_literal(range_last)); 24 | //} 25 | } 26 | range_first = first; 27 | range_last = last; 28 | } 29 | } 30 | ranges.push({first: range_first, last: range_last}); 31 | function generate_binary_lookup_tree_code(ranges, indent) { 32 | indent += ' '; 33 | if(ranges.length == 1) { 34 | console.log(`${indent}return (c >= ${hex_literal(ranges[0].first)} && c <= ${hex_literal(ranges[0].last)});`); 35 | } else { 36 | const center = Math.ceil(ranges.length / 2); 37 | const ranges_left = ranges.slice(0, center); 38 | const ranges_right = ranges.slice(center, ranges.length); 39 | console.log(`${indent}if(c < ${hex_literal(ranges[center].first)}){`) 40 | generate_binary_lookup_tree_code(ranges_left, indent); 41 | console.log(`${indent}} else {`); 42 | generate_binary_lookup_tree_code(ranges_right, indent); 43 | console.log(`${indent}}`); 44 | } 45 | } 46 | 47 | //console.log(hex_literal(range_first), hex_literal(range_last)); 48 | console.log(`int is_unicode_${property}(uint32_t c){`); 49 | generate_binary_lookup_tree_code(ranges, ''); 50 | console.log('}'); 51 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMMON_H_ 2 | #define _COMMON_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #define nullptr 0 9 | 10 | #ifdef SIMD 11 | #include 12 | #endif 13 | #define wasm_export 14 | 15 | #if defined(verbose) && !defined(debug) 16 | #define debug 17 | #endif 18 | #define suppress(x) x 19 | #if defined(debug) 20 | #define if_debug(x) x 21 | #if defined(verbose) 22 | #define if_verbose(x) x 23 | #else 24 | #define if_verbose(x) 25 | #endif 26 | #define if_not_debug(x) 27 | #define if_else_debug(x, y) x 28 | #else 29 | #define if_debug(x) 30 | #define if_verbose(x) 31 | #define if_not_debug(x) x 32 | #define if_else_debug(x, y) y 33 | #endif 34 | #if defined(profile) 35 | #define if_profile(x) x 36 | #else 37 | #define if_profile(x) 38 | #endif 39 | //#define inline_spec if_else_debug(__attribute__((noinline)), static inline) 40 | #define inline_spec if_else_debug(__attribute__((noinline)), static __attribute__((always_inline))) 41 | 42 | #define pnot(ptr) (~(uintptr_t)(ptr)) 43 | #define pand(ptr, mask) ((uintptr_t)(ptr) & (uintptr_t)(mask)) 44 | #define por(ptr, mask) ((uintptr_t)(ptr) | (uintptr_t)(mask)) 45 | #define pxor(ptr, mask) ((uintptr_t)(ptr) ^ (uintptr_t)(mask)) 46 | #define pcast(type, ptr) ((type)(ptr)) 47 | 48 | #if defined(__GNUC__) && !defined(__clang__) 49 | #if defined(__i386__) 50 | static __inline__ unsigned long long __rdtsc(void) 51 | { 52 | unsigned long long int x; 53 | __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 54 | return x; 55 | } 56 | #elif defined(__x86_64__) 57 | static __inline__ unsigned long long __rdtsc(void) 58 | { 59 | unsigned hi, lo; 60 | __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 61 | return ((unsigned long long) lo) | (((unsigned long long) hi) << 32); 62 | } 63 | #endif 64 | #endif 65 | 66 | size_t strlen16(char16_t const* s) 67 | { 68 | uint16_t const* a = s; 69 | for(; *s; s++); 70 | return s-a; 71 | } 72 | int strncmp16(char16_t const* l, char16_t const* r, size_t n) 73 | { 74 | if(!n--) return 0; 75 | for(; n && *l == *r ; ++l, ++r, --n); 76 | return *l - *r; 77 | } 78 | 79 | #if !defined(UTF16) 80 | typedef char char_t; 81 | #define stringize(x) #x 82 | #define strncmp_impl(x, y, z) strncmp(x, y, z) 83 | #define strlen_impl(x) strlen(x) 84 | #define format_specifier "s" 85 | #else 86 | typedef char16_t char_t; 87 | #define stringize(x) u ## #x 88 | #define strncmp_impl(x, y, z) strncmp16(x, y, z) 89 | #define strlen_impl(x) strlen16(x) 90 | #define format_specifier "zu" 91 | #endif 92 | 93 | // red: 31, green: 32, yellow: 33, blue: 34, magenta: 35, cyan: 36, white: 37 94 | // normal: [0;m, bold: [1;m, reset [0m 95 | #define color_bold_red(x) "\033[1;31m" x "\033[0m" 96 | #define color_bold_green(x) "\033[1;32m" x "\033[0m" 97 | #define color_bold_magenta(x) "\033[1;35m" x "\033[0m" 98 | #define color_bold_cyan(x) "\033[1;36m" x "\033[0m" 99 | #define color_bold_bright_black(x) "\033[1;90m" x "\033[0m" 100 | 101 | #ifdef SIMD 102 | #include "simd.h" 103 | typedef u08x32 unit_t; 104 | typedef struct { 105 | char const* current; 106 | char const* const begin; 107 | char const* const end; 108 | unit_t const* unit_ptr; 109 | unit_t const* const unit_begin; 110 | unit_t const* const unit_end; 111 | size_t unit_bytes_consumed; 112 | } scanner_status_t; 113 | #endif 114 | 115 | #endif //_COMMON_H_ 116 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef _MEMORY_H_ 2 | #define _MEMORY_H_ 3 | 4 | size_t const token_capacity = 32; 5 | size_t const page_size = 1 << 12; // 4kB 6 | 7 | typedef struct _memory_page_t { 8 | uint8_t* buffer; 9 | size_t available; 10 | size_t allocated; 11 | struct _memory_page_t* next; 12 | struct _memory_page_t* prev; 13 | } memory_page_t; 14 | 15 | typedef struct { 16 | memory_page_t* head; 17 | memory_page_t* current; 18 | size_t page_count; 19 | } memory_state_t; 20 | 21 | #define max(a, b) ((a) > (b) ? (a) : (b)) 22 | void* parser_malloc_impl(memory_state_t* const memory, size_t size) 23 | { 24 | size_t const remainder = (size % 4); // align to 4-bytes 25 | size += (remainder == 0 ? 0 : 4 - remainder); 26 | memory_page_t* current = memory->current; 27 | if(current == nullptr || current->available < size) { 28 | current = (memory_page_t*) malloc(sizeof(memory_page_t)); 29 | current->buffer = (uint8_t*) malloc(max(size, page_size)); 30 | current->available = current->allocated = max(size, page_size); 31 | current->prev = memory->current; 32 | current->next = nullptr; 33 | ++memory->page_count; 34 | if(memory->head == nullptr) { 35 | memory->head = current; 36 | memory->current = current; 37 | } else { 38 | if(size >= page_size) { 39 | current->prev = memory->current->prev; 40 | current->next = memory->current; 41 | if(current->prev) { 42 | current->prev->next = current; 43 | } else { 44 | memory->head = current; 45 | } 46 | memory->current->prev = current; 47 | } else { 48 | memory->current->next = current; 49 | memory->current = current; 50 | } 51 | } 52 | } 53 | size_t offset = (current->allocated - current->available); 54 | current->available -= size; 55 | return current->buffer + offset; 56 | } 57 | 58 | #ifdef DBGMEM 59 | #define parser_malloc(memory_metric_id, size) ( \ 60 | memory_metric[memory_metric_id] += size, \ 61 | parser_malloc_impl(state->memory, size) \ 62 | ) 63 | #else 64 | #define parser_malloc(ignored, size) parser_malloc_impl(state->memory, size) 65 | #endif 66 | 67 | #endif //_MEMORY_H_ 68 | -------------------------------------------------------------------------------- /src/messages.h: -------------------------------------------------------------------------------- 1 | #ifndef _MESSAGES_H_ 2 | #define _MESSAGES_H_ 3 | 4 | char const* const unknown_token = "unknown token"; 5 | char const* parse_token_name[256] = {unknown_token}; 6 | 7 | #define define_error(_id, type, _message) \ 8 | parse_error_t const error_##type = {.id = _id, .message = _message}; 9 | #define set_error(x) state->parse_error = &error_##x; 10 | #define set_scan_error(x, _code) { \ 11 | set_error(x); \ 12 | state->code = _code; \ 13 | state->error_position = make_position(state); \ 14 | } 15 | #define return_error(x, value) { set_error(x); return value; } 16 | #define return_scan_error(x, _code, value) { \ 17 | set_scan_error(x, _code); \ 18 | return value; \ 19 | } 20 | #define return_compiled_error(compiled_string, value) { \ 21 | compiled_string_t const* _compiled_string = compiled_string; \ 22 | state->parse_error = _compiled_string->offending_error; \ 23 | state->error_position = _compiled_string->offending_position; \ 24 | return value; \ 25 | } 26 | #define return_position_error(x, position, value) { \ 27 | state->error_position = position; \ 28 | return_error(x, value); \ 29 | } 30 | #define return_location_error(x, location, value) { \ 31 | location_t const* _location = location; \ 32 | if(_location) state->error_position = _location->begin; \ 33 | return_error(x, value); \ 34 | } 35 | #define return_location_end_error(x, location, value) { \ 36 | location_t const* _location = location; \ 37 | if(_location) state->error_position = _location->end; \ 38 | return_error(x, value); \ 39 | } 40 | #define return_node_error(x, node, value) { \ 41 | return_location_error(x, ((parse_node_t*)(node))->location, value); \ 42 | } 43 | #define return_token_error(x, token, value) { \ 44 | return_location_error(x, &(token->location), value); \ 45 | } 46 | 47 | define_error(0x0001, lvalue, "assigning to non-lvalue"); 48 | define_error(0x0006, binding_identifier, "lvalue of a binding pattern must be an identifier"); 49 | define_error(0x0002, middle_rest, "rest element must be the last element in a sequence"); 50 | define_error(0x0003, rest_argument, "invalid assignment target for a rest element"); 51 | define_error(0x0004, object_assignment_rest, "invalid assignment target for a rest element in an object assigment"); 52 | define_error(0x0004, object_binding_rest, "invalid assignment target for a rest element in an object pattern"); 53 | define_error(0x0005, non_assignment, 54 | "invalid assignment operator in a binding or assignment pattern" 55 | ); 56 | define_error(0x0006, unexpected_await, "await is valid only in async functions and async generators"); 57 | define_error(0x0007, missing_binding_initializer, "missing initializer in a destructuring declaration"); 58 | define_error(0x0008, missing_const_initializer, "missing initializer in a const declaration"); 59 | define_error(0x0009, missing_import_specifier, "missing import specifier"); 60 | define_error(0x000a, expecting_unicode_sequence, "expecting unicode escape sequence"); 61 | define_error(0x000b, not_enough_hexdigits, "not enough hex digits in unicode escape sequence"); 62 | define_error(0x000c, missing_unicode_closing, "missing closing parenthesis in unicode escape sequence"); 63 | define_error(0x000d, missing_leading_surrogate, "UTF16 coding error; missing leading surrogate"); 64 | define_error(0x000e, missing_trailing_surrogate, "UTF16 coding error; missing trailing surrogate"); 65 | define_error(0x000f, surrogate_in_identifier, 66 | "Unicode character in an identifier must not be a surrogate. " 67 | "Instead of specifying a surrogate pair, use unicode escape sequence format \\u{xxxxx}." 68 | ); 69 | define_error(0x0010, contextual_identifier, "identifier cannot be a contextual reserved word"); 70 | define_error(0x0011, contextual_label, "label cannot be a contextual reserved word"); 71 | define_error(0x0012, trailing_comma, "unexpected trailing comma"); 72 | define_error(0x0013, invalid_binding_element, "invalid binding element"); 73 | define_error(0x0014, initializer_in_for, "initialier is not allowed in for-in/for-of statement"); 74 | define_error(0x0015, missing_try_handler, "one of catch or finally handler must be defined for try"); 75 | define_error(0x0016, octal_in_strict, "octal string literal is not allowed in strict mode"); 76 | define_error(0x0017, for_of_begins_with_let, "for-of statement cannot begin with non-declarative let"); 77 | define_error(0x0018, invalid_for_assignment, "invalid assignment target in for-in / for-of left-hand-side"); 78 | define_error(0x0019, standalone_super, "super keyword can only be used to access super class properties and methods"); 79 | define_error(0x001a, import_in_non_module, "import keyword can only appear in a module"); 80 | define_error(0x001b, new_meta, "new meta property can only appear inside a function"); 81 | define_error(0x001c, invalid_strict_mode_identifier, "invalid strict mode identifier"); 82 | define_error(0x001d, unicode_keyword, "keywords cannot be specified with unicode escape sequences"); 83 | define_error(0x001e, yield_in_strict_mode, "yield is a reserved word in strict mode"); 84 | define_error(0x001f, await_in_module, "await is a reserved word in module"); 85 | define_error(0x0020, eval_args_in_strict_mode, "eval and arguments are invalid as references in strict mode"); 86 | define_error(0x0021, invalid_update, "invalid increment/decrement operand"); 87 | define_error(0x0022, invalid_labeled, "labeled statement is not allowed here"); 88 | define_error(0x0023, duplicate_symbol, "redeclaration of variable"); 89 | define_error(0x0024, duplicate_label, "redeclaration of label"); 90 | define_error(0x0025, let_in_lexical, "a lexical declaration cannot declare a variable named let"); 91 | define_error(0x0026, with_in_strict_mode, "with statement cannot be used in strict mode"); 92 | define_error(0x0027, invalid_constructor, "constructor must not be a getter, setter, async, generator or async-generator"); 93 | define_error(0x0028, unsyntatic_continue, "continue statement must be inside a loop"); 94 | define_error(0x0029, unsyntatic_break, "unlabeled break statement must be inside a loop or switch statement"); 95 | define_error(0x002a, unsyntatic_return, "return statement must be inside a function"); 96 | define_error(0x002b, undefined_label, "undefined label"); 97 | define_error(0x002c, misplaced_super_property, "super property can only be accessed inside methods"); 98 | define_error(0x002d, misplaced_super_call, "super call can only appear in class constructors"); 99 | define_error(0x002e, eval_or_arguments_in_strict_mode, "eval/arguments cannot be used as a binding identifier in strict mode"); 100 | define_error(0x0031, duplicate_export, "duplicate export symbol"); 101 | define_error(0x0032, duplicate_default_export, "duplicate default export"); 102 | define_error(0x0033, missing_export_reference, "missing export reference"); 103 | define_error(0x0034, elision_in_binding_pattern, "elisiion is not allowed in a destructuring pattern"); 104 | define_error(0x0035, expecting_binding_identifier, "expecting a binding indentifier"); 105 | define_error(0x0036, duplicate_constructor, "duplicate constructor"); 106 | define_error(0x0037, static_prototype, "static prototype method is not allowed"); 107 | define_error(0x0038, identifier_deletion, "deleting a variable is not allowed in strict mode"); 108 | define_error(0x0039, invalid_strict_mode, "strict mode is not allowed when formal parameters are not simple"); 109 | define_error(0x003a, no_labeled_function, "labeled function cannot be used here"); 110 | define_error(0x003b, yield_await_in_arrow_params, "yield or arrow expression in arrow parameters"); 111 | define_error(0x003c, duplicate_prototype, "duplicate __proto__ property"); 112 | define_error(0x003d, duplicate_regexp_flag, "duplicate regular expression flag"); 113 | define_error(0x003e, invalid_regexp_flag, "invalid regular expression flag"); 114 | define_error(0x003f, annex_numeral, "numeric literals cannot start with 0 in strcit mode"); 115 | define_error(0x0040, expecting_of, "expecting 'of' token in a for-of statement"); 116 | define_error(0x0041, newline_in_string_literal, "unescaped line feed and carriage return are not allowed in a string literal"); 117 | define_error(0x0042, invalid_escape_sequence, "octal or decimal escape sequence is not allowed here"); 118 | define_error(0x0043, unterminated_string, "unterminated string literal"); 119 | define_error(0x0044, unterminated_template, "unterminated template literal"); 120 | define_error(0x0045, unterminated_regexp, "unterminated regular expression"); 121 | define_error(0x0046, terminated_regexp, "line terminator in a regular expression is invalid"); 122 | define_error(0x0047, unicode_range, "unicode code point is out of unicode range"); 123 | define_error(0x0048, unexpected_for_await, "for-await statement can only appear in async functions and async generators"); 124 | define_error(0x0049, duplicate_default_clause, "duplicate default clause in a switch statement"); 125 | define_error(0x004a, invalid_assignment_target, "invalid assignment target"); 126 | define_error(0x004b, invalid_binding_target, "invalid binding target"); 127 | define_error(0x004c, invalid_cover_grammar, "invalid cover grammar"); 128 | define_error(0x004d, empty_parenthetical, "empty parenthesized expression"); 129 | define_error(0x004e, missing_parenthesis, "expecting closing parenthesis"); 130 | define_error(0x004f, missing_variable_name, "missing variable name"); 131 | define_error(0x0050, reserved_word_as_variable, "reserved word cannot be used a variable name"); 132 | 133 | define_error(0x1000, missing_assignment_or_binding_flag, 134 | "internal-error: change flags must have one of assignment or binding flag" 135 | ); 136 | define_error(0x1001, is_not_a_property_node, 137 | "internal-error: all the properties of an object node must be of property_t type" 138 | ); 139 | define_error(0x1002, null_node_in_change_types, 140 | "internal-error: null node encounted while changing node types of cover grammar" 141 | ); 142 | define_error(0x1003, null_node_in_bind_nodes, 143 | "internal-error: null node encounted while binding nodes of cover grammar" 144 | ); 145 | 146 | #endif //_MESSAGES_H_ 147 | -------------------------------------------------------------------------------- /src/nodes.h: -------------------------------------------------------------------------------- 1 | #ifndef _NODES_H_ 2 | #define _NODES_H_ 3 | 4 | #include "memory.h" 5 | #include "interface.h" 6 | #include "messages.h" 7 | 8 | #endif //_NODES_H_ 9 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /src/parser.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define log_token(__VA_ARGS__) 8 | 9 | typedef struct { 10 | uint64_t punctuator; 11 | uint64_t identifier; 12 | uint64_t reserved_word; 13 | uint64_t string_compares; 14 | uint64_t whitespace; 15 | uint64_t terminator; 16 | uint64_t comment; 17 | uint64_t numeric_literal; 18 | uint64_t string_literal; 19 | uint64_t regexp_literal; 20 | } elements_t; 21 | elements_t counts1 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 22 | elements_t counts2 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 23 | elements_t timings1 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 24 | elements_t timings2 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 25 | elements_t characters1 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 26 | elements_t characters2 = {0, 0, 0, 0, 0, 0, 0, 0, 0}; 27 | 28 | #define print_string(x) printf(" %s", x) 29 | #define print_number(x) printf(" %d", x) 30 | #define print_double(x) printf(" %g", x) 31 | #ifdef verbose 32 | #define profile 33 | #endif 34 | 35 | #include "common.h" 36 | #include "constants.h" 37 | #include "nodes.h" 38 | #ifdef verbose 39 | void assert(int value, char const* file_name, size_t line_number) 40 | { 41 | if(!value) { 42 | printf(color_bold_red("assertion failed at %s:%zu") "\n", file_name, line_number); 43 | fflush(stdout); 44 | abort(); 45 | } 46 | } 47 | void print_params(params_t params) { 48 | printf( 49 | color_bold_bright_black("(%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s )") " \n", 50 | (params & param_flag_strict_mode ? " strict" : ""), 51 | (params & param_flag_loose_mode ? " loose" : ""), 52 | (params & param_flag_module ? " module" : ""), 53 | (params & param_flag_annex ? " annex" : ""), 54 | (params & param_flag_await ? " await" : ""), 55 | (params & param_flag_yield ? " yield" : ""), 56 | (params & param_flag_default ? " default" : ""), 57 | (params & param_flag_in ? " in" : ""), 58 | (params & param_flag_return ? " return" : ""), 59 | (params & cover_flag_parameters ? " cover-params" : ""), 60 | (params & param_flag_covered_call ? " cover-call" : ""), 61 | (params & param_flag_for_binding ? " for-binding" : ""), 62 | (params & param_flag_loose_binding ? " loose-binding" : ""), 63 | (params & param_flag_unique_params ? " unique-params" : ""), 64 | (params & param_flag_vanilla_function ? " vanilla-function" : ""), 65 | (params & param_flag_function ? " function" : ""), 66 | (params & param_flag_class ? " class" : ""), 67 | (params & param_flag_formal ? " formal" : ""), 68 | (params & param_flag_export ? " export" : "") 69 | ); 70 | fflush(stdout); 71 | } 72 | #define _print_parse_descent(type, remove_filter, add_filter) { \ 73 | uint32_t new_params = make_params(remove_filter, add_filter); \ 74 | printf( "%*s=> %s [%d]", (state->depth % 60), "", #type, state->depth); \ 75 | print_params(new_params); \ 76 | ++state->depth; \ 77 | } 78 | #define _print_parse_ascent(node) { \ 79 | --state->depth; \ 80 | printf("%*s<= [%d]", (state->depth % 60), "", state->depth); \ 81 | if(node == nullptr) printf(" nullptr"); \ 82 | printf("\n"); \ 83 | fflush(stdout); \ 84 | } 85 | #define print_make_node(node_type) { \ 86 | printf( \ 87 | color_bold_magenta("%*s-- making node %s") "\n", \ 88 | state->depth % 60, "", #node_type \ 89 | ); \ 90 | fflush(stdout); \ 91 | } 92 | #define print_token(token, length) printf("%.*s\n", (int)(length), token) 93 | #if !defined(UTF16) 94 | #define print_token_consumption() ( \ 95 | printf( \ 96 | color_bold_cyan("%*s-- consumed token '%.*s'") "\n", \ 97 | state->depth % 60, "", \ 98 | (int)(state->parse_token->end - state->parse_token->begin), \ 99 | state->parse_token->begin \ 100 | ), \ 101 | fflush(stdout) \ 102 | ) 103 | #else 104 | #define print_token_consumption() ( \ 105 | printf( \ 106 | color_bold_cyan("%*s-- consumed token '%.*s'") "\n", \ 107 | state->depth % 60, "", \ 108 | 2 * (int)(state->parse_token->end - state->parse_token->begin), \ 109 | state->parse_token->begin \ 110 | ), \ 111 | fflush(stdout) \ 112 | ) 113 | #endif 114 | #else 115 | #define _print_parse_descent(type, remove_filter, add_filter) 116 | #define _print_parse_ascent(depth) 117 | #define print_make_node(node_type) 118 | #define print_token_consumption() 119 | #define print_token(token, length) 120 | #define print_params(params) 121 | #endif 122 | #define begin_group(name) 123 | #define end_group() 124 | 125 | #include "scanner.h" 126 | #if defined(SIMD) 127 | #include "simd/literals.h" 128 | #include "simd/identifier.h" 129 | #include "simd/punctuator.h" 130 | #include "simd/comment.h" 131 | #include "simd/scanner.h" 132 | #endif 133 | #include "parser.h" 134 | 135 | /* 136 | int parse_line(char* line){ 137 | // This assumes that a digit will be found and the line ends in " Kb". 138 | int i = strlen(line); 139 | const char* p = line; 140 | while (*p <'0' || *p > '9') p++; 141 | line[i-3] = '\0'; 142 | i = atoi(p); 143 | return i; 144 | } 145 | 146 | void print_memeory_usage(){ //Note: this value is in KB! 147 | FILE* file = fopen("/proc/self/status", "r"); 148 | int virtual = -1, resident = -1; 149 | char line[128]; 150 | 151 | while(fgets(line, 128, file) != NULL){ 152 | if(strncmp(line, "VmSize:", 7) == 0){ 153 | virtual = parse_line(line); 154 | if(resident != -1) break; 155 | } else if(strncmp(line, "VmRSS:", 6) == 0){ 156 | resident = parse_line(line); 157 | if(virtual != -1) break; 158 | } 159 | } 160 | fclose(file); 161 | printf("virtual: %d resident: %d\n", virtual, resident); 162 | } 163 | //*/ 164 | 165 | int main(int argc, char* argv[]) 166 | { 167 | if(argc > 1) { 168 | FILE* fp = fopen(argv[1], "r"); 169 | bool is_module = false; 170 | if(fp != NULL) { 171 | fseek(fp, 0L, SEEK_END); 172 | size_t file_size = ftell(fp); 173 | size_t buffer_size = (file_size | 0x1f) + 0x01 + 0x20; 174 | fseek(fp, 0L, SEEK_SET); 175 | char* source = (char *) aligned_alloc(32, buffer_size); 176 | //char* source = (char *) malloc(file_size + 1); 177 | fread(source, 1, file_size, fp); 178 | fclose(fp); 179 | source[file_size] = 0; 180 | #if defined(verbose) || defined(profile) 181 | int iterations = 1; 182 | #else 183 | int iterations = (argc > 2 ? atoi(argv[2]) : 1000); 184 | #endif 185 | ///* 186 | { 187 | //scan_result_t result; 188 | //parse_result_t result; 189 | clock_t cbegin = clock(); 190 | uint64_t begin = __rdtsc(); 191 | uint32_t params = param_flag_annex; 192 | if((argc > 2 && strcmp(argv[2], "-s") == 0) || 193 | (argc > 3 && strcmp(argv[3], "-s") == 0) 194 | ) params |= param_flag_streaming; 195 | if((argc > 2 && strcmp(argv[2], "-m") == 0) || 196 | (argc > 3 && strcmp(argv[3], "-m") == 0) 197 | ) is_module = true; 198 | for(int it = 0; it < iterations; ++it) { 199 | //result = tokenize(source, source + file_size); 200 | //free(result.token_begin); 201 | parse_result_t result = parse(source, source + file_size, is_module, params); 202 | if(it != iterations - 1) parser_free(&result.state); 203 | else { 204 | uint64_t end = __rdtsc(); 205 | clock_t cend = clock(); 206 | if(result.state.tokenization_status == status_flag_complete && 207 | result.state.parsing_status == status_flag_complete 208 | ){ 209 | printf(color_bold_green("parsing successful") "\n"); 210 | } else { 211 | if(result.state.tokenization_status == status_flag_complete) { 212 | printf(color_bold_red("parsing failed") "\n"); 213 | } else { 214 | printf(color_bold_red("tokenization failed") "\n"); 215 | } 216 | if(result.state.parse_error != nullptr) { 217 | printf(color_bold_red("%s") "\n", result.state.parse_error->message); 218 | } 219 | char_t const* begin = result.state.parse_token->begin; 220 | int length = result.state.parse_token->end - begin; 221 | printf("\nparsing failed at character index %zu %.*s\n", begin - result.state.code_begin, length, begin); 222 | printf("token found: %x %x %c\n", result.state.parse_token->id, result.state.parse_token->group, result.state.parse_token->id); 223 | printf("token expected: %x %c\n", result.state.expected_token_id, result.state.expected_token_id); 224 | //printf("token found: %x %x %c\n", result.state.parse_token->id, result.state.parse_token->group, result.state.parse_token->id); 225 | //printf("token expected: %x %c\n", result.state.expected_token_id, result.state.expected_token_id); 226 | } 227 | //printf("%lu\n", (end - begin) / iterations); 228 | printf("%lu %.3f\n", (end - begin) / iterations, 1000 * ((double)(cend - cbegin)) / CLOCKS_PER_SEC / iterations); 229 | //print_memeory_usage(); 230 | } 231 | } 232 | } 233 | //*/ 234 | #if 0 235 | //defined(SIMD) 236 | { 237 | int result; 238 | clock_t cbegin = clock(); 239 | uint64_t begin = __rdtsc(); 240 | for(int it = 0; it < iterations; ++it) { 241 | result = tokenize_vectorized3(source, source + file_size); 242 | } 243 | uint64_t end = __rdtsc(); 244 | clock_t cend = clock(); 245 | if(result == 1) { 246 | printf(color_bold_green("tokenization successful") "\n"); 247 | } else { 248 | printf(color_bold_red("tokenization failed") "\n"); 249 | } 250 | //printf("%lu\n", (end - begin) / iterations); 251 | printf("%lu %ld\n", (end - begin) / iterations, 1000 * (cend - cbegin) / CLOCKS_PER_SEC); 252 | } 253 | #endif 254 | //*/ 255 | #if defined(profile) 256 | #define print_element(name) printf( \ 257 | "%16s: %9ld %9ld %9ld %9ld %10ld %10ld\n", #name, \ 258 | counts1.name / iterations, counts2.name / iterations, \ 259 | characters1.name / iterations, characters2.name / iterations, \ 260 | timings1.name / iterations, timings2.name / iterations \ 261 | ) 262 | #else 263 | #define print_element(name) 264 | #endif 265 | print_element(identifier); 266 | print_element(reserved_word); 267 | print_element(string_compares); 268 | print_element(punctuator); 269 | print_element(whitespace); 270 | print_element(terminator); 271 | print_element(comment); 272 | print_element(numeric_literal); 273 | print_element(string_literal); 274 | print_element(regexp_literal); 275 | } 276 | } 277 | 278 | return 0; 279 | } 280 | -------------------------------------------------------------------------------- /src/parser_wasm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "common.h" 4 | #include "nodes.h" 5 | #include "interface.js.h" 6 | 7 | #define wasm_export __attribute__ ((visibility ("default"))) 8 | #define start_clock(x) 9 | #define print_string(x) log_string(x, strlen(x)) 10 | #define print_number(x) log_number(x) 11 | #define print_double(x) log_double(x) 12 | 13 | //#define if_verbose(x) x 14 | extern void log_node(void*, int, int, int, void*); 15 | extern void log_string(void const* string_pointer, size_t length); 16 | extern void log_number(uint32_t number); 17 | extern void log_double(double number); 18 | /* 19 | extern void printf1(char const* const); 20 | extern void printf2(char const* const, char const* const); 21 | extern void printf3(char const* const, char const* const, char const* const); 22 | extern void printf4(char const* const, char const* const, char const* const, char const* const); 23 | extern void printf5(char const* const, char const* const, char const* const, char const* const, char const* const); 24 | #define __get_6th_arg(arg1, arg2, arg3, arg4, arg5, arg6, ...) arg6 25 | //#define __get_5th_arg(arg1, arg2, arg3, arg4, arg5, ...) arg5 26 | #define _choose_printf(...) __get_6th_arg(__VA_ARGS__, printf5, printf4, printf3, printf2, printf1, ) 27 | #define printf(...) _choose_printf(__VA_ARGS__)(__VA_ARGS__) 28 | //*/ 29 | //#define fflush(x) 30 | //#define printf print 31 | //#define printf(__VA_ARGS__) print(__VA_ARGS__) 32 | extern void print(char const*, ...); 33 | extern void log_pointer(void*); 34 | 35 | extern void log_parse_descent( 36 | char const* type_pointer, size_t type_length, uint32_t depth, uint32_t params 37 | ); 38 | extern void log_parse_ascent(uint32_t depth, void* node); 39 | extern void log_token_consumption(void const* buffer, size_t begin, size_t end, uint32_t depth); 40 | extern void log_make_node(char const* type_pointer, size_t type_length, uint32_t depth); 41 | extern void begin_group_impl(char const* type_pointer, size_t type_length); 42 | extern void end_group(); 43 | extern void log_token(char_t const* token, size_t length); 44 | extern void log_assertion(char const* file_name, size_t length, size_t line_number); 45 | extern void log_params(params_t params); 46 | 47 | #ifdef verbose 48 | void assert(int value, char const* file_name, size_t line_number) 49 | { 50 | if(!value) { 51 | log_assertion(file_name, strlen(file_name), line_number); 52 | abort(); 53 | } 54 | } 55 | #define _print_parse_descent(type, remove_filter, add_filter) { \ 56 | uint32_t new_params = make_params(remove_filter, add_filter); \ 57 | log_parse_descent(#type, strlen(#type), state->depth, new_params); \ 58 | ++state->depth; \ 59 | } 60 | #define _print_parse_ascent(node) { --state->depth; log_parse_ascent(state->depth, node); } 61 | #define print_make_node(node_type) log_make_node(#node_type, strlen(#node_type), state->depth) 62 | #define print_token_consumption() \ 63 | log_token_consumption(state->code_begin, state->parse_token->begin - state->code_begin, state->parse_token->end - state->code_begin, state->depth) 64 | #define begin_group(name) begin_group_impl(name, strlen(name)) 65 | #define print_token(token, length) log_token(token, length) 66 | #define print_params(params) log_params(params); 67 | #else 68 | #define _print_parse_descent(type, remove_filter, add_filter) 69 | #define _print_parse_ascent(node) 70 | #define print_make_node(node_type) 71 | #define print_token_consumption() 72 | #define begin_group(name) 73 | #define print_token(token, length) 74 | #define print_params(params) 75 | #endif 76 | 77 | #include "scanner.h" 78 | #include "parser.h" 79 | #include 80 | 81 | void* wasm_malloc(int size) { 82 | return malloc(size); 83 | } 84 | void wasm_free(void* pointer) { 85 | return free(pointer); 86 | } 87 | void* get_empty_list() { 88 | return &empty_list; 89 | } 90 | -------------------------------------------------------------------------------- /test/benchmark.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import {performance} from 'perf_hooks'; 3 | import {Worker, isMainThread, parentPort, workerData} from 'worker_threads'; 4 | import Benchmark from 'benchmark'; 5 | 6 | import {fileURLToPath} from 'url'; 7 | const __filename = fileURLToPath(import.meta.url); 8 | 9 | process.on('unhandledRejection', (reason, p) => { 10 | console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); 11 | }); 12 | 13 | const parsers = { 14 | falcon: { 15 | name: 'falcon', version: () => '0.x.0', 16 | make_options: function(_options) { 17 | let options = {is_module: _options.is_module}; 18 | return options; 19 | }, 20 | import: async function() { 21 | this.Parser = (await import('../src/interface.js')).Parser; 22 | await this.Parser.load_wasm('../dist/parser.wasm'); 23 | }, 24 | init: async function() { 25 | this.parser = new this.Parser; 26 | }, 27 | load: function(utf8_vew, script) { 28 | if(!this.parser.code.view) this.parser.load_script(script); 29 | }, 30 | parse: function(script, options) { 31 | const result = this.parser.parse_code(options.is_module, 0); 32 | const length = result.program.body.length; 33 | return length; 34 | }, 35 | free: function() { this.parser.free(); } 36 | }, 37 | acorn: { 38 | name: 'acorn', version: function(){ return this.parser.version; }, 39 | make_options: function(_options){ 40 | let options = {locations: _options.locations, ranges: _options.ranges}; 41 | if(_options.ecma_version) options.ecmaVersion = _options.ecma_version; 42 | if(_options.is_module) options.sourceType = 'module'; 43 | return options; 44 | }, 45 | import: async function() { 46 | this.parser = await import('acorn'); 47 | }, 48 | init: function(){}, 49 | load: function(utf8_vew, script){}, 50 | parse: function(script, options){ 51 | const ast = this.parser.parse(script, options); 52 | return ast.body.length; 53 | }, 54 | free: function(){} 55 | }, 56 | meriyah: { 57 | name: 'meriyah', version: function(){ return this.parser.version; }, 58 | require_directive: () => 'const meriyah = require("meriyah")', 59 | make_options: function(_options){ 60 | let options = {loc: _options.locations, ranges: _options.ranges}; 61 | if(_options.is_module) options.module = true; 62 | return options; 63 | }, 64 | import: async function() { 65 | this.parser = (await import('meriyah')).default; 66 | }, 67 | init: function(){}, 68 | load: function(utf8_vew, script){}, 69 | parse: function(script, options){ 70 | const ast = this.parser.parseScript(script, options); 71 | return ast.body.length; 72 | }, 73 | free: function(){} 74 | }, 75 | 'tree-sitter': { 76 | name: 'tree-sitter', version: () => '0.17.1', 77 | make_options: function(_options){ 78 | let options = {loc: _options.locations, ranges: _options.ranges}; 79 | return options; 80 | }, 81 | import: async function() { 82 | this.Parser = (await import('web-tree-sitter')).default; 83 | await this.Parser.init(); 84 | this.JavaScript = await this.Parser.Language.load( 85 | 'node_modules/web-tree-sitter/tree-sitter-javascript.wasm' 86 | ); 87 | }, 88 | init: async function(){ 89 | this.parser = new this.Parser; 90 | this.parser.setLanguage(this.JavaScript); 91 | }, 92 | load: function(script){}, 93 | parse: function(script, options){ 94 | const ast = this.parser.parse(script); 95 | const length = ast.rootNode.childCount; 96 | //tsparser.reset(); 97 | //tsparser.delete(); 98 | return length; 99 | }, 100 | free: function(){} 101 | } 102 | }; 103 | 104 | let invoke_parser = () => {}; 105 | const flushed_write = string => new Promise( 106 | resolve => { process.stdout.write(string, resolve); } 107 | ); 108 | const _options = {ecma_version: 2020, locations: true}; 109 | const parser_field_length = 18 /*24*/, test_filed_length = 18; 110 | const benchmark_parse = (name, parse, independent) => { 111 | return new Promise(resolve => { 112 | const benchmark = new Benchmark(name, parse, { 113 | defer: independent, 114 | onComplete: async function(event) { 115 | const ms = (1000 * this.times.period).toFixed(1).padStart(5); 116 | const delta = `${Math.round(this.stats.rme)}%`.padStart(3); 117 | let stats = `${ms} ms ±${delta}`; 118 | if(this.__memory__) { 119 | stats = `\`${Math.round(this.__memory__)} MB / ${stats}\``; 120 | } else { 121 | stats = `\`${stats}\``; 122 | } 123 | await flushed_write(' ' + stats.padStart(parser_field_length) + '|'); 124 | resolve(); 125 | }, 126 | onCycle: (event) => { 127 | //if(global && global.gc) global.gc(); 128 | //const stats = event.target.stats; 129 | //console.log(event.target.name, event.target.count, event.target.cycles, stats.sample.length, event.target.times.cycle); 130 | } 131 | }); 132 | benchmark.run(); 133 | }); 134 | }; 135 | 136 | (async () => { 137 | if(isMainThread) { 138 | const parseArgs = (await import('minimist')).default; 139 | 140 | const libraries = [ 141 | {name: 'jQuery', file: 'jquery-3.5.1.js'}, 142 | {name: 'Angular', file: 'angular-1.8.0.js'}, 143 | {name: 'React', file: 'react-17.0.1.js'}, 144 | //{name: 'TypeScript', file: 'typescript-3.9.7.js'} 145 | ]; 146 | 147 | const args = parseArgs(process.argv.slice(2)); 148 | const independent = !!args.independent; 149 | await flushed_write('| ' + ''.padStart(test_filed_length) + ' |'); 150 | for await(const parser of Object.values(parsers)) { 151 | await parser.import(); // just to get version 152 | const name = `${parser.name}-${parser.version()}`; 153 | await flushed_write(' ' + name.padStart(parser_field_length) + ' |'); 154 | } 155 | await flushed_write('\n'); 156 | await flushed_write('|-' + ''.padStart(test_filed_length, '-') + ':|'); 157 | for await(const parser of Object.values(parsers)) { 158 | await flushed_write('-' + ''.padStart(parser_field_length, '-') + ':|'); 159 | } 160 | await flushed_write('\n'); 161 | for await(const library of libraries) { 162 | const file_path = `data/pass/libraries/${library.file}`; 163 | const utf8_view = fs.readFileSync(file_path); 164 | const script = utf8_view.toString(); 165 | const worker_data = {utf8_view: utf8_view, script: script}; 166 | await flushed_write('| ' + library.file.padStart(test_filed_length) + ' |'); 167 | for await(const parser of Object.values(parsers)) { 168 | //if(parser.name != 'falcon') continue; 169 | //if(use_worker && parser.name != 'falcon') continue; 170 | const name = `${library.name}-${parser.name}`; 171 | let parse_event = {library_name: library.name, parser_name: parser.name}; 172 | await new Promise(async resolve => { 173 | if(independent) { 174 | parse_event.action = 'parse'; 175 | const parse = deferred => { 176 | const worker = new Worker(__filename, {workerData: worker_data}); 177 | worker.on('message', async event => { 178 | if(event.message == 'ready') { 179 | worker.postMessage(parse_event); 180 | } else if(event.message == 'done') { 181 | const stats = deferred.benchmark.stats; 182 | deferred.resolve(); 183 | // hack to force the actual elapsed time for parsing excluding 184 | // the overhead introduced by the setup and teardown of worker 185 | deferred.benchmark.minTime = 0; 186 | deferred.elapsed = event.elapsed; 187 | //deferred.benchmark._original.__memory__ = event.memory; 188 | worker.terminate(); 189 | } 190 | }); 191 | }; 192 | await benchmark_parse(name, parse, independent); 193 | resolve(); 194 | } else { 195 | const worker = new Worker(__filename, {workerData: worker_data}); 196 | worker.on('message', async event => { 197 | if(event.message == 'ready') { 198 | parse_event.action = 'benchmark'; 199 | worker.postMessage(parse_event); 200 | } else if(event.message == 'done') { 201 | worker.terminate(); 202 | resolve(); 203 | } 204 | }); 205 | } 206 | }); 207 | } 208 | await flushed_write('\n'); 209 | } 210 | } else { 211 | parentPort.once('message', async event => { 212 | const parser = parsers[event.parser_name]; 213 | const name = `${event.library_name}-${event.parser_name}`; 214 | const options = parser.make_options(_options); 215 | await parser.import(); 216 | await parser.init(); 217 | await parser.load(workerData.utf8_view, workerData.script); 218 | if(event.action == 'parse') { 219 | // perform a single parse 220 | const begin = performance.now(); 221 | const memory_begin = 0; //process.memoryUsage().heapUsed; 222 | const result = parser.parse(workerData.script, options); 223 | const elapsed = (performance.now() - begin) / 1000; 224 | const memory = (process.memoryUsage().heapUsed - memory_begin) / (1024**2); 225 | parser.free(); 226 | parentPort.postMessage({message: 'done', result: result, elapsed: elapsed, memory: memory}); 227 | } else { 228 | // perform multiple parses and extract benchmark details 229 | const parse = () => { 230 | const result = parser.parse(workerData.script, options); 231 | parser.free(); 232 | return result; 233 | }; 234 | await benchmark_parse(name, parse, false); 235 | parentPort.postMessage({message: 'done'}); 236 | } 237 | }); 238 | parentPort.postMessage({message: 'ready'}); 239 | } 240 | })(); 241 | -------------------------------------------------------------------------------- /test/compare.js: -------------------------------------------------------------------------------- 1 | import {Parser} from '../src/interface.js'; 2 | import TSParser from 'web-tree-sitter'; 3 | import Tenko from 'tenko'; 4 | 5 | (async () => { 6 | /* 7 | { 8 | let start = new Date; 9 | for(let it = 0; it < 1000; ++it) { 10 | tokenize(data_string, 0, data_string.length); 11 | } 12 | console.log((new Date - start)); 13 | } 14 | */ 15 | //console.log(await parse_file('../../data/jquery-3.5.1.js')); 16 | ///* 17 | if(!process.versions || !process.versions.electron) { 18 | let args = (await import('minimist')).default(process.argv.slice(2)); 19 | await Parser.load_wasm('../dist/parser.wasm'); 20 | let parser = new Parser(); 21 | if(args.f) { 22 | const is_module = /\.module\.js$|\.mjs$/.test(args.f); 23 | const params = (args.s ? Parser.constants.param_flag_streaming: 0) 24 | if(args.b) { 25 | let result; 26 | await parser.load_file(args.f); 27 | let start = new Date; 28 | let iterations = args.i || 1000; 29 | let parse_result; 30 | for(let it = 0; it < iterations; ++it) { 31 | parse_result = parser.parse_code(is_module, params); 32 | if(it != iterations - 1) parser.free(); 33 | } 34 | const elapsed = (new Date - start) / iterations; 35 | const program = parse_result.program; 36 | if(args.s) { 37 | console.log(elapsed); 38 | } else { 39 | const script = parser.code.utf8_view.toString(); 40 | const source_type = (is_module ? 'module' : 'script'); 41 | const acorn = await import('acorn'); 42 | const options = {ecmaVersion: 2020, sourceType: source_type, locations: true, sourceFile: ''}; 43 | let acorn_result; 44 | start = new Date(); 45 | for(let it = 0; it < iterations; ++it) { 46 | acorn_result = acorn.parse(script, options); 47 | } 48 | const acorn_elapsed = (new Date - start) / iterations; 49 | const meriyah = (await import('meriyah')).default; 50 | // 51 | let meriyah_result; 52 | start = new Date(); 53 | for(let it = 0; it < iterations; ++it) { 54 | meriyah_result = meriyah.parseScript(script, {loc: true}); 55 | } 56 | const meriyah_elapsed = (new Date - start) / iterations; 57 | // 58 | let tenko_result; 59 | start = new Date(); 60 | for(let it = 0; it < iterations; ++it) { 61 | tenko_result = Tenko(script, {goalMode: source_type, sourceField: ''}); 62 | } 63 | const tenko_elapsed = (new Date - start) / iterations; 64 | // 65 | await TSParser.init(); 66 | const tsparser = new TSParser; 67 | const JavaScript = await TSParser.Language.load('node_modules/web-tree-sitter/tree-sitter-javascript.wasm'); 68 | tsparser.setLanguage(JavaScript); 69 | let tsparser_result; 70 | start = new Date(); 71 | for(let it = 0; it < iterations; ++it) { 72 | tsparser_result = tsparser.parse(script); 73 | } 74 | const tsparser_elapsed = (new Date - start) / iterations; 75 | // 76 | console.log( 77 | 'falcon:', elapsed, 'acorn:', acorn_elapsed, 78 | 'meriyah:', meriyah_elapsed, 'tenko:', tenko_elapsed, 79 | 'tree-parser:', tsparser_elapsed 80 | ); 81 | } 82 | } else { 83 | const parse_result = await parser.parse_file(args.f, is_module, params); 84 | const program = parse_result.program; 85 | if(args.c) { 86 | const acorn = await import('acorn'); 87 | const source_type = (is_module ? 'module' : 'script'); 88 | const options = {ecmaVersion: 2020, sourceType: source_type, locations: true, sourceFile: ''}; 89 | const fs = await import('fs'); 90 | const script = fs.readFileSync(args.f).toString(); 91 | let reference_result; 92 | reference_result = acorn.parse(script, options); 93 | //reference_result = Tenko(script, {goalMode: source_type, sourceField: '', ranges: true}).ast; 94 | //reference_result = Tenko(script, {goalMode: source_type, sourceField: ''}).ast; 95 | const {object_diff} = await import('./object_diff.js'); 96 | let sb = new Date; const s = JSON.stringify(program); let se = new Date - sb; 97 | let tb = new Date; const t = JSON.stringify(reference_result); let te = new Date - tb; 98 | let spb = new Date; const source = JSON.parse(s); let spe = new Date - spb; 99 | const target = JSON.parse(t); 100 | if(!args.nodump) { 101 | fs.writeFileSync('../.ignore/log1', JSON.stringify(source, null, ' ')); 102 | fs.writeFileSync('../.ignore/log2', JSON.stringify(target, null, ' ')); 103 | } 104 | const diff = object_diff(source, target); 105 | console.log(JSON.stringify(diff, null, ' ')); 106 | let vt = new Date; program.visit(); let visitation_time = new Date - vt; 107 | //console.log('visitation', visitation_time, Parser.visitation_count, spe); 108 | //console.log('stringification times', se, Parser.to_json_time, Parser.list_time, te); 109 | } else { 110 | console.log(JSON.stringify(program, null, ' ')); 111 | } 112 | //console.log(JSON.stringify(result.program, null, ' ')); 113 | } 114 | } 115 | } 116 | //*/ 117 | { 118 | /* 119 | 120 | /* 121 | start = new Date(); 122 | let tkn_base = 0x80, base = 0xc0; 123 | let symbols = new Map(); 124 | symbols.set(tkn_base + 1, Symbol('numeric_literal')); 125 | symbols.set(tkn_base + 2, Symbol('string_literal')); 126 | symbols.set(tkn_base + 3, Symbol('regexp_literal')); 127 | symbols.set(tkn_base + 4, Symbol('identifier')); 128 | symbols.set(tkn_base + 5, Symbol('punctuator')); 129 | symbols.set(tkn_base + 6, Symbol('terminator')); 130 | symbols.set(tkn_base + 7, Symbol('whitespace')); 131 | symbols.set(tkn_base + 8, Symbol('comment')); 132 | symbols.set(tkn_base + 9, Symbol('keyword')); 133 | symbols.set(base + 0, Symbol('await')); 134 | symbols.set(base + 1, Symbol('break')); 135 | symbols.set(base + 2, Symbol('case')); 136 | symbols.set(base + 3, Symbol('catch')); 137 | symbols.set(base + 4, Symbol('class')); 138 | symbols.set(base + 5, Symbol('const')); 139 | symbols.set(base + 6, Symbol('continue')); 140 | symbols.set(base + 7, Symbol('debugger')); 141 | symbols.set(base + 8, Symbol('default')); 142 | symbols.set(base + 9, Symbol('delete')); 143 | symbols.set(base + 10, Symbol('do')); 144 | symbols.set(base + 11, Symbol('else')); 145 | symbols.set(base + 12, Symbol('enum')); 146 | symbols.set(base + 13, Symbol('export')); 147 | symbols.set(base + 14, Symbol('extends')); 148 | symbols.set(base + 15, Symbol('false')); 149 | symbols.set(base + 16, Symbol('finally')); 150 | symbols.set(base + 17, Symbol('for')); 151 | symbols.set(base + 18, Symbol('function')); 152 | symbols.set(base + 19, Symbol('if')); 153 | symbols.set(base + 20, Symbol('import')); 154 | symbols.set(base + 21, Symbol('in')); 155 | symbols.set(base + 22, Symbol('instanceof')); 156 | symbols.set(base + 23, Symbol('new')); 157 | symbols.set(base + 24, Symbol('null')); 158 | symbols.set(base + 25, Symbol('return')); 159 | symbols.set(base + 26, Symbol('super')); 160 | symbols.set(base + 27, Symbol('switch')); 161 | symbols.set(base + 28, Symbol('this')); 162 | symbols.set(base + 29, Symbol('throw')); 163 | symbols.set(base + 30, Symbol('true')); 164 | symbols.set(base + 31, Symbol('try')); 165 | symbols.set(base + 32, Symbol('typeof')); 166 | symbols.set(base + 33, Symbol('var')); 167 | symbols.set(base + 34, Symbol('void')); 168 | symbols.set(base + 35, Symbol('while')); 169 | symbols.set(base + 36, Symbol('with')); 170 | symbols.set(base + 37, Symbol('yield')); 171 | symbols.set(base + 38, Symbol('implements')); 172 | symbols.set(base + 39, Symbol('interface')); 173 | symbols.set(base + 40, Symbol('package')); 174 | symbols.set(base + 41, Symbol('private')); 175 | symbols.set(base + 42, Symbol('protected')); 176 | symbols.set(base + 43, Symbol('public')); 177 | 178 | let token_size = 12; 179 | //let pointer = result[0], token_count = result[1]; 180 | let pointer = result[2], token_count = (result[3] - result[2]) / token_size + 1; 181 | result = new Uint32Array(memory.buffer, pointer, token_size*token_count/4); 182 | let tokens = new Array(token_count); 183 | for(let i = 0; i < 3*token_count; i += 3) { 184 | let begin = result[i], end = result[i + 1]; 185 | let value = result[i + 2]; 186 | let type = value & 0xff; 187 | let id = (value >> 8) & 0xff; 188 | let group = (value >> 16) & 0xffff; 189 | tokens[i/3] = { 190 | type: symbols.get(type), id: symbols.get(id) || id, 191 | value: data_string.substring(begin, end), 192 | group: group, begin: begin, end: end 193 | } 194 | } 195 | console.log('token binding took', (new Date - start)); 196 | //console.log(tokens); 197 | //*/ 198 | } 199 | })(); 200 | 201 | //return exports; 202 | //}); 203 | -------------------------------------------------------------------------------- /test/data/native/declarations/class.js: -------------------------------------------------------------------------------- 1 | /// empty declarations 2 | class a {} //? <+> 3 | class a {;} //? <+> 4 | class a { ''(){} } //? <+^> 5 | 6 | /// class declarations are always in strict mode 7 | //- eval_args_in_strict_mode 8 | class eval {} //? <-> @1:7 9 | class arguments {} //? <-> @1:7 10 | class a extends eval {} //? <+> 11 | class a extends arguments {} //? <+> 12 | ///class a extends eval = b {} //? <-> @1:22 13 | ///class a extends arguments = b {} //? <-> @1:27 14 | 15 | /// constructors 16 | class a { constructor(){} } //? <+> 17 | class a { 'constructor'(){} } //? <+> 18 | class a { ['constructor'](){} } //? <+> 19 | class a { static constructor(){} } //? <+> 20 | class a { static get constructor(){} } //? <+> 21 | class a { static set constructor(b){} } //? <+> 22 | 23 | /// super 24 | class a { b(){ super.c ; }} //? <+> 25 | class a extends b { constructor(){ super(); } } //? <+> 26 | class a { *b(){ super[yield]; } } //? <+> 27 | 28 | /// early errors 29 | //- misplaced_super_call 30 | class a { constructor(){ super(); } } //? <-> @1:26 31 | class a extends b { c(){ super(); } } //? <-> @1:26 32 | class a { static b(){ super(); } } //? <-> @1:23 33 | //- duplicate_constructor 34 | class a { constructor(){} constructor(){} } //? <-> @1:27 35 | class a { constructor(){} 'constructor'(){} } //? <-> @1:27 36 | class a { constructor(){} ['constructor'](){} } //? <+> 37 | //- invalid_constructor 38 | class a { * constructor(){} } //? <-> @1:13 39 | class a { async constructor(){} } //? <-> @1:17 40 | class a { async* constructor(){} } //? <-> @1:18 41 | class a { get constructor(){} } //? <-> @1:15 42 | class a { set constructor(b){} } //? <-> @1:15 43 | /// 44 | class a { * 'constructor'(){} } //? <-> @1:13 45 | class a { async 'constructor'(){} } //? <-> @1:17 46 | class a { async* 'constructor'(){} } //? <-> @1:18 47 | class a { get 'constructor'(){} } //? <-> @1:15 48 | class a { set 'constructor'(b){} } //? <-> @1:15 49 | /// 50 | class a { * ['constructor'](){} } //? <+> 51 | class a { async ['constructor'](){} } //? <+> 52 | class a { async* ['constructor'](){} } //? <+> 53 | class a { get ['constructor'](){} } //? <+> 54 | class a { set ['constructor'](b){} } //? <+> 55 | //- static_prototype 56 | class a { static prototype(){} } //? <-> @1:18 57 | class a { static get prototype(){} } //? <-> @1:22 58 | class a { static set prototype(b){} } //? <-> @1:22 59 | class a { static ['prototype'](){} } //? <+> 60 | class a { static get ['prototype'](){} } //? <+> 61 | class a { static set ['prototype'](b){} } //? <+> 62 | class a { prototype(){} } //? <+> 63 | class a { get prototype(){} } //? <+> 64 | class a { set prototype(b){} } //? <+> 65 | 66 | /// method definitions 67 | /// regular methods 68 | class a { b(){} } //? <+> 69 | class a { b(c){} } //? <+> 70 | class a { 'a'(b, c){} } //? <+> 71 | class a { [b](...c){} } //? <+> 72 | class a { [(b)](c, ...d){} } //? <+> 73 | class a { 0(b,){} } //? <+> 74 | /// generator methods 75 | class a { * b([c]){} } //? <+> 76 | class a { * 'a'({b}){} } //? <+> 77 | class a { * [b](...[c]){} } //? <+> 78 | class a { * [(b)](...{c}){} } //? <+> 79 | class a { * 0([b], {c}, ...[d]){} } //? <+> 80 | /// async methods 81 | class a { async b(c = 0){} } //? <+> 82 | class a { async 'a'([b = 0]){} } //? <+> 83 | class a { async [b]({c = 0}){} } //? <+> 84 | class a { async [(b)](...[c = 0]){} } //? <+> 85 | class a { async 0(...{b = 0}){} } //? <+> 86 | /// async generator methods 87 | class a { async* b(){} } //? <+> 88 | class a { async* 'a'(b){} } //? <+> 89 | class a { async* [b](c,d){} } //? <+> 90 | class a { async* [(b)](...c){} } //? <+> 91 | class a { async* 1(b, ...c){} } //? <+> 92 | /// getters 93 | class a { get b(){} } //? <+> 94 | class a { get 'a'(){} } //? <+> 95 | class a { get [b](){} } //? <+> 96 | class a { get [(b)](){} } //? <+> 97 | class a { get 0(){} } //? <+> 98 | /// setters 99 | class a { set b(c){} } //? <+> 100 | class a { set 'a'(b){} } //? <+> 101 | class a { set [b](c){} } //? <+> 102 | class a { set [(b)](c){} } //? <+> 103 | class a { set 0(b){} } //? <+> 104 | 105 | /// static method definitions 106 | /// static methods 107 | class a { static b(c){} } //? <+> 108 | class a { static 'a'(b, c){} } //? <+> 109 | class a { static [b](...c){} } //? <+> 110 | class a { static [(b)](c, ...d){} } //? <+> 111 | class a { static 0(b,){} } //? <+> 112 | /// static generator methods 113 | class a { static * b([c]){} } //? <+> 114 | class a { static * 'a'({b}){} } //? <+> 115 | class a { static * [b](...[c]){} } //? <+> 116 | class a { static * [(b)](...{c}){} } //? <+> 117 | class a { static * 0([b], {c}, ...[d]){} } //? <+> 118 | /// static async methods 119 | class a { static async b(c = 0){} } //? <+> 120 | class a { static async 'a'([b = 0]){} } //? <+> 121 | class a { static async [b]({c = 0}){} } //? <+> 122 | class a { static async [(b)](...[c = 0]){} } //? <+> 123 | class a { static async 0(...{b = 0}){} } //? <+> 124 | /// static async generator methods 125 | class a { static async* b(){} } //? <+> 126 | class a { static async* 'a'(b){} } //? <+> 127 | class a { static async* [b](c,d){} } //? <+> 128 | class a { static async* [(b)](...c){} } //? <+> 129 | class a { static async* 1(b, ...c){} } //? <+> 130 | /// static getters 131 | class a { static get b(){} } //? <+> 132 | class a { static get 'a'(){} } //? <+> 133 | class a { static get [b](){} } //? <+> 134 | class a { static get [(b)](){} } //? <+> 135 | class a { static get 0(){} } //? <+> 136 | /// static setters 137 | class a { static set b(c){} } //? <+> 138 | class a { static set 'a'(b){} } //? <+> 139 | class a { static set [b](c){} } //? <+> 140 | class a { static set [(b)](c){} } //? <+> 141 | class a { static set 0(b){} } //? <+> 142 | 143 | /// keyword method definitions 144 | class a { get(){} } //? <+> 145 | class a { set(){} } //? <+> 146 | class a { async(){} } //? <+> 147 | class a { static(){} } //? <+> 148 | /// get 149 | class a { get(){} } //? <+> 150 | class a { * get(){} } //? <+> 151 | class a { async get(){} } //? <+> 152 | class a { async* get(){} } //? <+> 153 | class a { get get(){} } //? <+> 154 | class a { set get(b){} } //? <+> 155 | class a { static get(){} } //? <+> 156 | /// set 157 | class a { set(b){} } //? <+> 158 | class a { * set(b){} } //? <+> 159 | class a { async set(b){} } //? <+> 160 | class a { async* set(b){} } //? <+> 161 | class a { get set(){} } //? <+> 162 | class a { set set(b){} } //? <+> 163 | class a { static set(b){} } //? <+> 164 | /// async 165 | class a { async(){} } //? <+> 166 | class a { * async(){} } //? <+> 167 | class a { async async(){} } //? <+> 168 | class a { async* async(){} } //? <+> 169 | class a { get async(){} } //? <+> 170 | class a { set async(b){} } //? <+> 171 | class a { static async(){} } //? <+> 172 | /// static 173 | class a { static(){} } //? <+> 174 | class a { * static(){} } //? <+> 175 | class a { async static(){} } //? <+> 176 | class a { async* static(){} } //? <+> 177 | class a { get static(){} } //? <+> 178 | class a { set static(b){} } //? <+> 179 | class a { static static(){} } //? <+> 180 | 181 | /// derivation 182 | class a extends b {} //? <+> 183 | class a extends b.c {} //? <+> 184 | class a extends b() {} //? <+> 185 | class a extends (b) {} //? <+> 186 | class a extends function(){} {} //? <+> 187 | class a extends class{} {} //? <+> 188 | -------------------------------------------------------------------------------- /test/data/native/declarations/function/function.js: -------------------------------------------------------------------------------- 1 | /// different types of function declarations 2 | function a(){} //? <+> 3 | function* a(){} //? <+> 4 | async function a(){} //? <+> 5 | async function* a(){} //? <+> 6 | async 7 | function a(){} //? <+> 8 | 9 | /// contextual keywords 10 | function* a() { yield; } //? <+> 11 | async function a() { await 0; } //? <+> 12 | async function* a() { yield; await 0; } //? <+> 13 | async function a(){ function b(){ await 0; } } //? <-> @1:41 14 | 15 | /// pedantic contextual keywords 16 | function* yield(){}; //? <+?> 17 | async function await(){}; //? <+?> 18 | async function* yield(){}; //? <+?> 19 | async function* await(){}; //? <+?> 20 | 21 | /// formal parameters 22 | function a(b) {} //? <+> 23 | function a(b = 2) {} //? <+> 24 | function a(...b) {} //? <+> 25 | function a(b, ...c) {} //? <+> 26 | function a(b, c = 2, ...d) {} //? <+> 27 | -------------------------------------------------------------------------------- /test/data/native/declarations/function/generator.js: -------------------------------------------------------------------------------- 1 | /// variations of function* tokens 2 | function* a() {} //? <+> 3 | function *a() {} //? <+> 4 | function * a() {} //? <+> 5 | function 6 | * a() {} //? <+> 7 | function 8 | * 9 | a() {} //? <+> 10 | 11 | /// formal parameters 12 | function* a(b) {} //? <+> 13 | function* a(b,) {} //? <+> 14 | function* a(b, c) {} //? <+> 15 | function* a(b,,c) {} //? <-> @1:15 16 | function* a(...b) {} //? <+> 17 | function* a(...b,) {} //? <-> @1:17 -middle_rest 18 | function* a(...b, c) {} //? <-> @1:17 -middle_rest 19 | function* a(b, ...c) {} //? <+> 20 | function* a([b]) {} //? <+> 21 | function* a(b = 0) {} //? <+> 22 | function* a([b] = [0]) {} //? <+> 23 | 24 | // yield as function name 25 | function* yield() {} //? <+?> 26 | 27 | /// yield as an identifier in parameter list 28 | //- contextual_identifier 29 | function* a(yield) {} //? <-> @1:13 30 | function* a([yield]) {} //? <-> @1:14 31 | function* a(b = yield) {} //? <-> @1:17 32 | function* a(b = yield.a) {} //? <-> @1:17 33 | function* a(b = [yield]) {} //? <-> @1:18 34 | function* a(b = [...yield]) {} //? <-> @1:21 35 | function* a(b = {yield}) {} //? <-> @1:18 36 | function* a(b = {yield = 0}) {} //? <-> @1:18 37 | function* a(b = {[yield]: 0}) {} //? <-> @1:19 38 | function* a(b = {...yield}) {} //? <-> @1:21 39 | /// yield as non-identifier in parameter list 40 | function* a(b = {yield(){}}) {} //? <+> 41 | function* a(b = {c(yield){}}) {} //? <+> 42 | 43 | /// yield in body 44 | function* a(){ yield; } //? <+> 45 | function* a(){ yield.a; } //? <-> @1:21 -default 46 | function* a(){ [yield]; } //? <+> 47 | function* a(){ [...yield]; } //? <+> 48 | function* a(){ !{yield}; } //? <-> @1:18 49 | function* a(){ !{yield = 0}; } //? <-> @1:18 50 | function* a(){ !{[yield]: 0}; } //? <+> 51 | function* a(){ !{...yield}; } //? <+> 52 | function* a(){ !{yield(){}}; } //? <+> 53 | function* a(){ !{b(yield){}}; } //? <+> 54 | function* a(){ yield = 0; } //? <-> @1:22 -default 55 | 56 | //- contextual_identifier 57 | function* a(){ ({b = yield} = {}); } //? <+> 58 | function* a(){ ({yield: 0}); } //? <+> 59 | function* a(){ ({0: yield}); } //? <+> 60 | function* a(){ ({[yield]: 0}); } //? <+> 61 | function* a(){ ({yield(){}}); } //? <+> 62 | function* a(){ ({b(yield){}}); } //? <+> 63 | function* a(){ ({yield(yield){}}); } //? <+> 64 | function* a(){ ({[yield](){}}); } //? <+> 65 | function* a(){ ({[yield](yield){}}); } //? <+> 66 | function* a(){ ({get yield(){}}); } //? <+> 67 | function* a(){ ({set yield(a){}}); } //? <+> 68 | function* a(){ ({set b(yield){}}); } //? <+> 69 | function* a(){ ({set yield(yield){}}); } //? <+> 70 | function* a(){ ({...yield}); } //? <+> 71 | function* a(){ (function(yield){}); } //? <+> 72 | function* a(){ (function(){ yield.a }); } //? <+> 73 | function* a(){ (function(){ var yield; }); } //? <+> 74 | function* a(){ (function(){ let yield; }); } //? <+> 75 | function* a(){ (function(){ yield: ; }); } //? <+> 76 | function* a(){ (async function(yield){}); } //? <+> 77 | function* a(){ (async function(){ yield.a }); } //? <+> 78 | function* a(){ (async function(){ var yield; }); } //? <+> 79 | function* a(){ (async function(){ let yield; }); } //? <+> 80 | function* a(){ (async function(){ yield: ; }); } //? <+> 81 | function* a(){ `${yield}`; } //? <+> 82 | function* a(){ (yield); } //? <+> 83 | function* a(){ b[yield]; } //? <+> 84 | function* a(){ b`${yield}`; } //? <+> 85 | function* a(){ new yield; } //? <-> @1:20 86 | function* a(){ new b(yield); } //? <+> 87 | function* a(){ true ? yield : 0; } //? <+> 88 | function* a(){ false ? 0 : yield; } //? <+> 89 | function* a(){ b(yield); } //? <+> 90 | function* a(){ b(...yield); } //? <+> 91 | function* a(){ yield => {}; } //? <-> @1:22 -default 92 | function* a(){ (yield) => {}; } //? <-> @1:17 -yield_await_in_arrow_params 93 | function* a(){ (b = yield) => {}; } //? <-> @1:21 -yield_await_in_arrow_params 94 | function* a(){ var yield; } //? <-> @1:20 95 | function* a(){ let yield; } //? <-> @1:20 96 | function* a(){ yield: ; } //? <-> @1:16 97 | -------------------------------------------------------------------------------- /test/data/native/declarations/module/export.js: -------------------------------------------------------------------------------- 1 | export * from 'a'; //? <+#> 2 | export * as a from 'a'; //? <+#> 3 | 4 | export {} from 'a'; //? <+#> 5 | export {a} from 'a'; //? <+#> 6 | export {a as b} from 'a'; //? <+#> 7 | export {a, b as c, d,} from 'a'; //? <+#> 8 | 9 | export {}; //? <+#> 10 | let a; export {a}; //? <+#> 11 | let a; export {a as b}; //? <+#> 12 | let a; export {a as default}; //? <+#> 13 | let a, b, d; export {a, b as c, d,}; //? <+#> 14 | 15 | export var a; //? <+#> 16 | export let a; //? <+#> 17 | export const a = 0; //? <+#> 18 | export var [a] = []; //? <+#> 19 | export let [a] = []; //? <+#> 20 | export const [a] = []; //? <+#> 21 | export var {a} = {}; //? <+#> 22 | export let {a} = {}; //? <+#> 23 | export const {a} = {}; //? <+#> 24 | 25 | export function a(){} //? <+#> 26 | export function* a(){} //? <+#> 27 | export async function a(){} //? <+#> 28 | export async function* a(){} //? <+#> 29 | export class a {} //? <+#> 30 | 31 | export default function a(){} //? <+#> 32 | export default function* a(){} //? <+#> 33 | export default async function a(){} //? <+#> 34 | export default async function* a(){} //? <+#> 35 | export default class a {} //? <+#> 36 | 37 | export default function(){} //? <+#> 38 | export default function*(){} //? <+#> 39 | export default async function(){} //? <+#> 40 | export default async function*(){} //? <+#> 41 | export default class {} //? <+#> 42 | 43 | export default 0; //? <+#> 44 | export default async; //? <+#> 45 | export default [a] = []; //? <+#> 46 | export default {a} = {}; //? <+#> 47 | 48 | export var a; export default b; //? <+#> 49 | 50 | /// lexical uniqueness of export declarations 51 | //- duplicate_export 52 | /// var-var 53 | export var a, a; //? <-#> @1:15 54 | export var [a, a] = []; //? <-#> @1:16 55 | export var a; export var a; //? <-#> @1:26 56 | export var a; var a; //? <+#> 57 | export var [a] = []; var a; //? <+#> 58 | export var {a} = {}; var a; //? <+#> 59 | var a; export var a; //? <+#> 60 | var a; export var [a] = []; //? <+#> 61 | var a; export var {a} = {}; //? <+#> 62 | //- duplicate_symbol 63 | /// let-let 64 | export let a, a; //? <-#> @1:15 65 | export let [a, a] = []; //? <-#> @1:16 66 | export let a; export let a; //? <-#> @1:26 67 | export let a; let a; //? <-#> @1:19 68 | export let [a] = []; let a; //? <-#> @1:26 69 | export let {a} = {}; let a; //? <-#> @1:26 70 | export let a; { let a; } //? <+#> 71 | export let [a] = []; { let a; } //? <+#> 72 | export let {a} = {}; { let a; } //? <+#> 73 | let a; export let a; //? <-#> @1:19 74 | let a; export let [a] = []; //? <-#> @1:20 75 | let a; export let {a} = {}; //? <-#> @1:20 76 | { let a; } export let a; //? <+#> 77 | { let a; } export let [a] = []; //? <+#> 78 | { let a; } export let {a} = {}; //? <+#> 79 | /// var-let 80 | export var a; export let a; //? <-#> @1:26 81 | export let a; export var a; //? <-#> @1:26 82 | export var a; let a; //? <-#> @1:19 83 | export var [a] = []; let a; //? <-#> @1:26 84 | export var {a} = {}; let a; //? <-#> @1:26 85 | export var a; { let a; } //? <+#> 86 | export var [a] = []; { let a; } //? <+#> 87 | export var {a} = {}; { let a; } //? <+#> 88 | var a; export let a; //? <-#> @1:19 89 | var a; export let [a] = []; //? <-#> @1:20 90 | var a; export let {a} = {}; //? <-#> @1:20 91 | /// let-var 92 | export let a; export var a; //? <-#> @1:26 93 | export let a; var a; //? <-#> @1:19 94 | export let [a] = []; var a; //? <-#> @1:26 95 | export let {a} = {}; var a; //? <-#> @1:26 96 | let a; export var a; //? <-#> @1:19 97 | let a; export var [a] = []; //? <-#> @1:20 98 | let a; export var {a} = {}; //? <-#> @1:20 99 | { let a; } export var a; //? <+#> 100 | { let a; } export var [a] = []; //? <+#> 101 | { let a; } export var {a} = {}; //? <+#> 102 | /// named-var, named-let 103 | //- duplicate_export 104 | export {a}; export var a; //? <-#> @1:24 105 | export {a}; export let a; //? <-#> @1:24 106 | export var a; export {a}; //? <-#> @1:23 107 | export let a; export {a}; //? <-#> @1:23 108 | export {a as b}; export var a; //? <+#> 109 | export {a as b}; export let a; //? <+#> 110 | export var a; export {a as b}; //? <+#> 111 | export let a; export {a as b}; //? <+#> 112 | var a; export {a as b}; var b; //? <+#> 113 | var a; export {a as b}; let b; //? <+#> 114 | var a; var b; export {a as b}; //? <+#> 115 | var a; let b; export {a as b}; //? <+#> 116 | var a; export {a as b}; export var b; //? <-#> @1:36 117 | var a; export {a as b}; export let b; //? <-#> @1:36 118 | var a; export var b; export {a as b}; //? <-#> @1:35 119 | var a; export let b; export {a as b}; //? <-#> @1:35 120 | /// default-var default-let 121 | export var a; export default a; //? <+#> 122 | export let a; export default a; //? <+#> 123 | export default a; export var a; //? <+#> 124 | export default a; export let a; //? <+#> 125 | //- duplicate_symbol 126 | export var a; export default function a(){}; //? <-#> @1:39 127 | export let a; export default function a(){}; //? <-#> @1:39 128 | //- duplicate_default_export 129 | export default a; export default b; //? <-#> @1:34 130 | export default a; var b; export {b as default}; //? <-#> @1:39 131 | var a; export {a as default}; export default b; //? <-#> @1:46 132 | 133 | /// missing exported reference 134 | //- missing_export_reference 135 | export {a}; //? <-#> @1:9 136 | export {a as b}; //? <-#> @1:9 137 | var a; export {b as a}; //? <-#> @1:16 138 | /// 139 | export {a}; var a; //? <+#> 140 | export {a}; let a; //? <+#> 141 | export {a}; for(var a;;); //? <+#> 142 | export {a}; for(let a;;); //? <-#> @1:9 143 | export {a}; function a(){} //? <+#> 144 | export {a}; class a {} //? <+#> 145 | var a; export {a}; //? <+#> 146 | let a; export {a}; //? <+#> 147 | export {a as b}; var a; //? <+#> 148 | export {a as b}; let a; //? <+#> 149 | var a; export {a as b}; //? <+#> 150 | let a; export {a as b}; //? <+#> 151 | /// 152 | export {a}; { var a; } //? <+#> 153 | export {a}; { let a; } //? <-#> @1:9 154 | export {a}; { for(var a;;); } //? <+#> 155 | export {a}; { for(let a;;); } //? <-#> @1:9 156 | export {a}; { function a(){} } //? <-#> @1:9 157 | export {a}; { class a {} } //? <-#> @1:9 158 | { var a; } export {a}; //? <+#> 159 | { let a; } export {a}; //? <-#> @1:20 160 | -------------------------------------------------------------------------------- /test/data/native/declarations/module/import.js: -------------------------------------------------------------------------------- 1 | import 'a'; //? <+#> 2 | import * as a from 'a'; //? <+#> 3 | import a from 'a'; //? <+#> 4 | import {} from 'a'; //? <+#> 5 | import {a} from 'a'; //? <+#> 6 | import {a as b} from 'a'; //? <+#> 7 | import a, * as b from 'a'; //? <+#> 8 | import a, {b, c as d, e,} from 'a'; //? <+#> 9 | import('a'); //? <+#> 10 | 11 | import; //? <-#> @1:7 -missing_import_specifier 12 | 13 | /// lexical uniqueness of import declarations 14 | //- duplicate_symbol 15 | import a from 'a'; var a; //? <-#> @1:24 16 | import a from 'a'; let a; //? <-#> @1:24 17 | import a from 'a'; { var a; } //? <-#> @1:26 18 | import a from 'a'; { let a; } //? <+#> 19 | import * as a from 'a'; var a; //? <-#> @1:29 20 | import * as a from 'a'; let a; //? <-#> @1:29 21 | import * as a from 'a'; { var a; } //? <-#> @1:31 22 | import * as a from 'a'; { let a; } //? <+#> 23 | import {a} from 'a'; var a; //? <-#> @1:26 24 | import {a} from 'a'; let a; //? <-#> @1:26 25 | import {a} from 'a'; { var a; } //? <-#> @1:28 26 | import {a} from 'a'; { let a; } //? <+#> 27 | import {a as b} from 'a'; var b; //? <-#> @1:31 28 | import {a as b} from 'a'; let b; //? <-#> @1:31 29 | import {a as b} from 'a'; { var b; } //? <-#> @1:33 30 | import {a as b} from 'a'; { let b; } //? <+#> 31 | -------------------------------------------------------------------------------- /test/data/native/declarations/variable/array_binding.js: -------------------------------------------------------------------------------- 1 | /// simple binding 2 | let [a] = [1]; // a = 1 //? <+> 3 | let [a, b, c] = [1, 2, 3]; // a = 1, b = 2, c = 3 //? <+> 4 | 5 | /// rest element 6 | let [...a] = [1, 2]; // a = [1, 2] //? <+> 7 | let [a, ...b] = [1, 2, 3]; // a = 1, b = [2, 3] //? <+> 8 | let [a, b, ...c] = [1, 2, 3, 4]; // a = 1, b = 2, c = [3, 4] //? <+> 9 | 10 | /// elision 11 | let [, a] = [1, 2]; // a = 2 //? <+> 12 | let [,, a] = [1, 2, 3]; // a = 3 //? <+> 13 | let [a,] = [1]; // a = 1 //? <+> 14 | let [a,,b] = [1, 2, 3]; // a = 1, b = 3 //? <+> 15 | let [a,,,] = [1]; // a = 1 //? <+> 16 | 17 | /// nesting 18 | let [a, [b, c]] = [1, [2, 3]]; // a = 1, b = 2, c = 3 //? <+> 19 | // [NOTE] is there a useful use case for rest element + array binding? 20 | let [...[a, b]] = [1, 2]; // a = 1, b = 2 //? <+> 21 | let [a, [b, [, c], ...d], e] = [1, [2, [3, 4], 5, 6], 7]; // a = 1, b = 2, c = 4, d = [5, 6], e = 7 //? <+> 22 | 23 | /// default initializations 24 | let [a, b = 10] = [1]; // a = 1, b = 10 //? <+> 25 | let [[a, b] = [1, 2]] = []; // a = 1, b = 2 //? <+> 26 | 27 | /// multiple binding patterns 28 | let [a] = [1, 2], [b] = [3]; // a = 1, b = 3 //? <+> 29 | -------------------------------------------------------------------------------- /test/data/native/declarations/variable/object_binding.js: -------------------------------------------------------------------------------- 1 | /// simple binding 2 | let {a} = {a: 1}; // a = 1 //? <+> 3 | let {a, b, c} = {a: 1, b: 2, c: 3}; // a = 1, b = 2, c = 3 //? <+> 4 | 5 | /// rest element 6 | let {...a} = {a: 1, b: 2}; // a = {a: 1, b: 2} //? <+> 7 | let {a, ...b} = {a: 1, b: 2, c: 3}; // a = 1, b = {b: 2, c: 3} //? <+> 8 | let {a, b, ...c} = {a: 1, b: 2, c: 3, d: 4}; // a = 1, b = 2, c = {c: 3, d: 4} //? <+> 9 | 10 | /// elision is meaningless for object binding 11 | 12 | /// nesting 13 | let {a, b: {c, d}} = {a: 1, b: {c: 2, d: 3}}; // a = 1, c = 2, d = 3 //? <+> 14 | let {a, b: {c, d: {e}, ...f}, g} = {a: 1, b: {c: 2, d: {a: 3, e: 4}, c: 5, d: 6}, g: 7}; // a = 1, c = 2, e = 4, f = {c: 5, d: 6}, g = 7 //? <+> 15 | 16 | /// default initializations 17 | let {a, b = 10} = {a: 1}; // a = 1, a = 10 //? <+> 18 | let {a: {a, b} = {a: 1, b: 2}} = {}; // a = 1, b = 2 //? <+> 19 | 20 | /// multiple binding patterns 21 | let {a} = {a: 1, b: 2}, {c = 3} = {}; // a = 1, c = 3 //? <+> 22 | -------------------------------------------------------------------------------- /test/data/native/declarations/variable/variable.js: -------------------------------------------------------------------------------- 1 | var a; //? <+> 2 | var a = 1; //? <+> 3 | var a = 1, b = 2; //? <+> 4 | var a = 1, b, c = 2; //? <+> 5 | var a, b = 2, c; //? <+> 6 | 7 | let a; //? <+> 8 | let a = 1; //? <+> 9 | let a = 1, b = 2; //? <+> 10 | let a = 1, b, c = 2; //? <+> 11 | let a, b = 2, c; //? <+> 12 | 13 | //- missing_const_initializer 14 | const a; //? <-> @1:8 15 | const a = 1; //? <+> 16 | const a = 1, b = 2; //? <+> 17 | const a = 1, b, c = 2; //? <-> @1:15 18 | const a = 1, b = 2, c; //? <-> @1:22 19 | 20 | let a = b = 1; //? <+> 21 | -------------------------------------------------------------------------------- /test/data/native/expressions/arrow_cover.js: -------------------------------------------------------------------------------- 1 | (a.b) => {}; //? <-> @1:2 -invalid_binding_target 2 | (); //? <-> @1:2 -empty_parenthetical 3 | (a); //? <+> 4 | (a.b); //? <+> 5 | (a,); //? <-> @1:3 -trailing_comma 6 | (...a); //? <-> @1:2 -invalid_cover_grammar 7 | (...a,); //? <-> @1:6 -missing_parenthesis 8 | (...a, ...b); //? <-> @1:6 -missing_parenthesis 9 | /// 10 | ([]); //? <+> 11 | ([a]); //? <+> 12 | ([a,]); //? <+> 13 | ([a,,b]); //? <+> 14 | ([a.b]); //? <+> 15 | ([...a]); //? <+> 16 | ([...a,]); //? <+> 17 | ([...a, ...b]); //? <+> 18 | /// 19 | ({}); //? <+> 20 | ({a}); //? <+> 21 | ({a,}); //? <+> 22 | ({a.b}); //? <-> @1:4 -default 23 | ({...a}); //? <+> 24 | ({...a,}); //? <+> 25 | ({...a, ...b}); //? <+> 26 | /// 27 | () => {}; //? <+> 28 | (a) => {}; //? <+> 29 | (a.b) => {}; //? <-> @1:2 -invalid_binding_target 30 | (a,) => {}; //? <+> 31 | (...a) => {}; //? <+> 32 | (...(a)) => {}; //? <-> @1:5 -invalid_binding_target 33 | (...a,) => {}; //? <-> @1:6 -missing_parenthesis 34 | (...a, ...b) => {}; //? <-> @1:6 -missing_parenthesis 35 | /// 36 | ([]) => {}; //? <+> 37 | ([a]) => {}; //? <+> 38 | ([a,]) => {}; //? <+> 39 | ([a,,b]) => {}; //? <+> 40 | ([a.b]) => {}; //? <-> @1:3 -invalid_binding_target 41 | ([...a]) => {}; //? <+> 42 | ([...(a)]) => {}; //? <-> @1:6 -invalid_binding_target 43 | ([...a,]) => {}; //? <-> @1:3 -middle_rest 44 | ([...a, ...b]) => {}; //? <-> @1:3 -middle_rest 45 | /// 46 | ({}) => {}; //? <+> 47 | ({a}) => {}; //? <+> 48 | ({a,}) => {}; //? <+> 49 | ({a.b}) => {}; //? <-> @1:4 -default 50 | ({...a}) => {}; //? <+> 51 | ({...(a)}) => {}; //? <-> @1:6 -invalid_binding_target 52 | ({...a,}) => {}; //? <-> @1:3 -middle_rest 53 | ({...a, ...b}) => {}; //? <-> @1:3 -middle_rest 54 | /// 55 | (a = yield); //? <+> 56 | !function*(){ (a = yield); } //? <+> 57 | !async function(){ (a = await 0); } //? <+> 58 | !function*(){ (a = !function(){ yield; }); } //? <+> 59 | !function*(){ (a = () => { yield; }) } //? <+> 60 | /// 61 | (a = yield) => {}; //? <+> 62 | !function*(){ (a = yield) => {}; } //? <-> @1:20 -yield_await_in_arrow_params 63 | !function*(){ (a = (yield)) => {}; } //? <-> @1:21 -yield_await_in_arrow_params 64 | !function*(){ (a = yield, b = ([])) => {}; } //? <-> @1:20 -yield_await_in_arrow_params 65 | !function*(){ (a = !function(){ yield; }) => {}; } //? <+> 66 | !function*(){ (a = !function*(){ yield; }) => {}; } //? <+> 67 | !function*(){ (a = () => { yield; }) => {} } //? <+> 68 | /// 69 | !async function(){ (a = await 0) => {}; } //? <-> @1:25 -yield_await_in_arrow_params 70 | !async function(){ (a = (await 0)) => {}; } //? <-> @1:26 -yield_await_in_arrow_params 71 | !async function(){ (a = await 0, b = ([])) => {}; } //? <-> @1:25 -yield_await_in_arrow_params 72 | !async function(){ (a = !function(){ await; }) => {}; } //? <+> 73 | !async function(){ (a = !async function(){ await 0; }) => {}; } //? <+> 74 | !async function(){ (a = async() => { await 0; }) => {} } //? <+> 75 | /// 76 | ///!function*(){ (a, a, b = yield) => {}; } //? <-> @1:19 -duplicate_symbol 77 | !function*(){ (a, b = yield, a) => {}; } //? <-> @1:23 -yield_await_in_arrow_params 78 | 79 | async(a, a); //? <+> 80 | 81 | async(await); //? <+> 82 | async(await 0); //? <-> @1:13 -default 83 | async(a = await); //? <+> 84 | async(a = await 0); //? <-> @1:17 -default 85 | !async function(){ async(await); } //? <-> @1:31 -default 86 | !async function(){ async(await 0); } //? <+> 87 | !async function(){ async(a = await); } //? <-> @1:35 -default 88 | !async function(){ async(a = await 0); } //? <+> 89 | 90 | (yield) => {}; //? <+> 91 | (yield 0) => {}; //? <-> @1:8 -default 92 | (a = yield) => {}; //? <+> 93 | (a = yield 0) => {}; //? <-> @1:12 -default 94 | (a = !function yield(){}) => {}; //? <+> 95 | (a = !class yield{}) => {}; //? <-> @1:13 -yield_in_strict_mode 96 | (a = {yield(){}}); //? <+> 97 | (a = {*b(){ yield 0; }}); //? <+> 98 | (a = !function*(){ yield 0; }) => {}; //? <+> 99 | (a = !class{*b(){ yield 0; }}) => {}; //? <+> 100 | 101 | async (yield) => {}; //? <+> 102 | async (yield 0) => {}; //? <-> @1:14 -default 103 | async (a = yield) => {}; //? <+> 104 | async (a = yield 0) => {}; //? <-> @1:18 -default 105 | async (a = !function yield(){}) => {}; //? <+> 106 | async (a = !class yield{}) => {}; //? <-> @1:19 -yield_in_strict_mode 107 | async (a = {yield(){}}); //? <+> 108 | async (a = {*b(){ yield 0; }}); //? <+> 109 | async (a = !function*(){ yield 0; }) => {}; //? <+> 110 | async (a = !class{*b(){ yield 0; }}) => {}; //? <+> 111 | 112 | (await) => {}; //? <+> 113 | (await 0) => {}; //? <-> @1:8 -default 114 | (a = await) => {}; //? <+> 115 | (a = await 0) => {}; //? <-> @1:12 -default 116 | (a = !function await(){}) => {}; //? <+> 117 | (a = !class await{}) => {}; //? <+> 118 | (a = {await(){}}); //? <+> 119 | (a = {async b(){ await 0; }}); //? <+> 120 | (a = !async function(){ await 0; }) => {}; //? <+> 121 | (a = !class{async b(){ await 0; }}) => {}; //? <+> 122 | 123 | async (await) => {}; //? <-> @1:8 -yield_await_in_arrow_params 124 | async (await 0) => {}; //? <-> @1:14 -default 125 | async (a = await) => {}; //? <-> @1:12 -yield_await_in_arrow_params 126 | async (a = await 0) => {}; //? <-> @1:18 -default 127 | async (a = !function await(){}) => {}; //? <-> @1:22 -yield_await_in_arrow_params 128 | async (a = !class await{}) => {}; //? <-> @1:19 -yield_await_in_arrow_params 129 | async (a = {await(){}}); //? <+> 130 | async (a = {async b(){ await 0; }}); //? <+> 131 | async (a = !async function(){ await 0; }) => {}; //? <+> 132 | async (a = !class{async b(){ await 0; }}) => {}; //? <+> 133 | 134 | async 135 | () => {}; //? <-> @2:4 -default 136 | () => {} /./ //? <-> @1:10 -default 137 | async () 138 | => {}; //? <-> @2:1 -default 139 | -------------------------------------------------------------------------------- /test/data/native/expressions/arrow_function.js: -------------------------------------------------------------------------------- 1 | let a = () => {}; //? <+> 2 | let a = () => 0; //? <+> 3 | let a = () => ({}); //? <+> 4 | let a = () => { return 0; }; //? <+> 5 | let a = () => function b(){}; //? <+> 6 | let a = () => class b{}; //? <+> 7 | let a = () => () => {}; //? <+> 8 | let a = b => b; //? <+> 9 | let a = b => (b); //? <+> 10 | let a = b => b, c; //? <+> 11 | let a, b = c => (a, c); //? <+> 12 | let a = (b) => b; //? <+> 13 | let a = (b) => { return b; }; //? <+> 14 | let a = (b, c,) => { return b; }; //? <+> 15 | let a = (b, c = 1) => { return c; }; //? <+> 16 | 17 | let a = (...b) => { return b; }; //? <+> 18 | let a = (b, ...c) => { return c; }; //? <+> 19 | let a = (...[b = 1, c]) => { return {b, c}; }; //? <+> 20 | let a = (...{b, c = 2}) => { return {b, c}; }; //? <+> 21 | 22 | let a = ([b, c]) => { return {b, c}; }; //? <+> 23 | let a = ({b, c}) => { return {b, c}; }; //? <+> 24 | let a = (b, [c, d], e, {f, g}, h, ...i) => { 25 | return {b, c, d, e, f, g, h, i}; 26 | }; //? <+> 27 | let a = (b = 1, [c = 2, d, {e = 3, f}], {g = 3, h}) => { 28 | return {b, c, d, e, f, g, h}; 29 | }; //? <+> 30 | 31 | let a = async () => {}; //? <+> 32 | let a = async () => 0; //? <+> 33 | let a = async () => ({}); //? <+> 34 | let a = async () => { return 0; }; //? <+> 35 | let a = async () => function b(){}; //? <+> 36 | let a = async () => class b{}; //? <+> 37 | let a = async () => () => {}; //? <+> 38 | let a = async b => b; //? <+> 39 | let a = async b => (b); //? <+> 40 | let a = async b => b, c; //? <+> 41 | let a, b = async c => (a, c); //? <+> 42 | let a = async (b) => b; //? <+> 43 | let a = async (b) => { return b; }; //? <+> 44 | let a = async (b, c,) => { return b; }; //? <+> 45 | let a = async (b, c = 1) => { return c; }; //? <+> 46 | 47 | let a = async (...b) => { return b; }; //? <+> 48 | let a = async (b, ...c) => { return c; }; //? <+> 49 | let a = async (...[b = 1, c]) => { return {b, c}; }; //? <+> 50 | let a = async (...{b, c = 2}) => { return {b, c}; }; //? <+> 51 | 52 | let a = async ([b, c]) => { return {b, c}; }; //? <+> 53 | let a = async ({b, c}) => { return {b, c}; }; //? <+> 54 | let a = async (b, [c, d], e, {f, g}, h, ...i) => { 55 | return {b, c, d, e, f, g, h, i}; 56 | }; //? <+> 57 | let a = async (b = 1, [c = 2, d, {e = 3, f}], {g = 3, h}) => { 58 | return {b, c, d, e, f, g, h}; 59 | }; //? <+> 60 | -------------------------------------------------------------------------------- /test/data/native/expressions/assignment/assignment.js: -------------------------------------------------------------------------------- 1 | //- invalid_assignment_target 2 | this = 0; //? <-> @1:1 3 | a = 0; //? <+> 4 | null = 0; //? <-> @1:1 5 | true = 0; //? <-> @1:1 6 | false = 0; //? <-> @1:1 7 | 0 = 0; //? <-> @1:1 8 | 'a' = 0; //? <-> @1:1 9 | (function(){} = 0); //? <-> @1:2 10 | (function*(){} = 0); //? <-> @1:2 11 | (async function(){} = 0); //? <-> @1:2 12 | (async function*(){} = 0); //? <-> @1:2 13 | (class{} = 0); //? <-> @1:2 14 | /a/ = 0; //? <-> @1:1 15 | `a` = 0; //? <-> @1:1 16 | a.b = 0; //? <+> 17 | a[b] = 0; //? <+> 18 | a`b` = 0; //? <-> @1:1 19 | !{a(){ super.b = 0; }}; //? <+> 20 | !{a(){ super[b] = 0; }}; //? <+> 21 | !function(){ new.target = 0; } //? <-> @1:14 22 | import.meta = 0; //? <-#> @1:1 23 | new a = 0; //? <-> @1:1 24 | a() = 0; //? <-> @1:1 25 | a().b = 0; //? <+> 26 | a()[b] = 0; //? <+> 27 | class a extends b { constructor(){ super() = 0; }}; //? <-> @1:36 28 | a?.b = 0; //? <-> @1:1 29 | ++a = 0; //? <-> @1:1 30 | /// 31 | (a) = 0; //? <+> 32 | (a.b) = 0; //? <+> 33 | (a[b]) = 0; //? <+> 34 | (a().b) = 0; //? <+> 35 | (a()[b]) = 0; //? <+> 36 | (((a()[b]))) = 0; //? <+> 37 | /// 38 | [] = []; //? <+> 39 | ({} = {}); //? <+> 40 | -------------------------------------------------------------------------------- /test/data/native/expressions/assignment/destructuring.js: -------------------------------------------------------------------------------- 1 | /// elision 2 | [a] = [1]; //? <+> 3 | [a,] = [1]; //? <+> 4 | [,a] = [1, 2]; //? <+> 5 | [a,,b] = [1, 2, 3]; //? <+> 6 | /// rest 7 | [...a] = [1, 2, 3]; //? <+> 8 | [a, ...b] = [1, 2, 3]; //? <+> 9 | [, a, b, ...c] = [1, 2, 3]; //? <+> 10 | [...[a, ...b]] = [1, 2, 3]; //? <+> 11 | [...[...[...[...a]]]] = [1, 2]; //? <+> 12 | //- middle_rest 13 | [...a, ] = []; //? <-> @1:2 14 | [...a, b] = []; //? <-> @1:2 15 | [...a, ...b] = []; //? <-> @1:2 16 | [...a, b, ...c] = []; //? <-> @1:2 17 | [...{a = 0}, ] = 0; //? <-> @1:2 18 | /// initialization and nesting 19 | [a = [1, 2]] = []; //? <+> 20 | [a = [b, c] = [1, 2]] = []; //? <+> 21 | [a = [b, c = 1, [d, e] = [f, [, g = 2] = [3, [4]]]]] = []; //? <+> 22 | /// lhs expressions other than identifier 23 | [...a.b] = []; //? <+> 24 | [...a().b] = []; //? <+> 25 | [...(a.b)] = []; //? <+> 26 | [...(a().b)] = []; //? <+> 27 | [a.b, [a.c, ...[a.d, a.e, f().g]]] = [1, 2, 3, 4, 5]; //? <+> 28 | 29 | 30 | /// object assignment 31 | z = {a: {a}, 'b': {b}, 1: {c}, [d]: d, e} = {}; //? <+> 32 | /// rest 33 | z = {...a} = {a: 1, b: 2}; //? <+> 34 | z = {a, ...b} = {a: 1, b: 2, c: 3}; //? <+> 35 | //- middle_rest 36 | z = {...a, } = {}; //? <-> @1:6 37 | z = {...a, b} = {}; //? <-> @1:6 38 | z = {...a, ...b} = {}; //? <-> @1:6 39 | z = {...a, b, ...c} = {}; //? <-> @1:6 40 | // 12.15.7.1: Static Semantics: Early Errors 41 | // AssignmentRestProperty: ... DestructuringAssignmentTarget 42 | // It is a Syntax Error if DestructuringAssignmentTarget is an 43 | // ArrayLiteral or an ObjectLiteral 44 | //z = {...{l, ...m}} = {l: 1, x: 2, y: 3}; // not valid for some reason 45 | //z = {...{...{...{...n}}}} = {x: 1, y: 2, z: 3}; 46 | /// initialization 47 | z = {a = {a: 1, b: 2}, b = 3} = {}; //? <+> 48 | z = {a = {b, c} = {b: 1, c: 2}} = {}; //? <+> 49 | z = {a, b: {c = 10}} = {a: 1, b: {}}; //? <+> 50 | /// lhs expressions other than identifier 51 | z = {...a.b} = {}; //? <+a> 52 | z = {...a().b} = {}; //? <+a> 53 | z = {...(a.b)} = {}; //? <+a> 54 | z = {...(a().b)} = {}; //? <+a> 55 | z = {a.b, {a.c, ...{a.d, a.e, a().f}}} = {}; //? <+a> 56 | 57 | [a, {b, c}] = [1, {b: 2, c: 3}]; //? <+> 58 | z = {a, b: [c, d]} = {a: 1, b: [2, 3]}; //? <+> 59 | [a, {b = 1, c} = {b: 1, c: 2}] = [1, {b: 0, c: 0}]; //? <+> 60 | z = {a, b = [1, 2]} = {a: 1}; //? <+> 61 | [a, ...{0: b, c: {d} = {d: 3}}] = [1, 2]; //? <+> 62 | [a, ...{0: b, c: {d} = {e, f} = {d: 3}}] = [1, 2]; //? <+> 63 | 64 | //- invalid_assignment_target 65 | z = {a(){}} = {}; //? <-> @1:6 66 | z = {*a(){}} = {}; //? <-> @1:6 67 | z = {async a(){}} = {}; //? <-> @1:6 68 | z = {async* a(){}} = {}; //? <-> @1:6 69 | z = {get a(){}} = {}; //? <-> @1:6 70 | z = {set a(b){}} = {}; //? <-> @1:6 71 | ([a]) = 1; //? <-> @1:1 72 | //- invalid_cover_grammar 73 | z = {a = 0}; //? <-> @1:6 74 | -------------------------------------------------------------------------------- /test/data/native/expressions/binary.js: -------------------------------------------------------------------------------- 1 | /// multiplicative operators 2 | 1 * 2; //? <+> 3 | 1 / 2; //? <+> 4 | 1 % 2; //? <+> 5 | 6 | /// additive operators 7 | 1 + 2; //? <+> 8 | 1 - 2; //? <+> 9 | 10 | /// shift operators 11 | 1 << 2; //? <+> 12 | 1 >> 2; //? <+> 13 | -1 >>> 2; //? <+> 14 | 15 | /// relational operators 16 | 1 < 2; //? <+> 17 | 1 > 2; //? <+> 18 | 1 <= 2; //? <+> 19 | 1 >= 2; //? <+> 20 | [] instanceof Array; //? <+> 21 | a in {a: 1}; //? <+> 22 | 23 | /// equality operators 24 | 1 == 2; //? <+> 25 | 1 != 2; //? <+> 26 | undefined === null; //? <+> 27 | undefined !== null; //? <+> 28 | 29 | /// bitwise: descending precedence 30 | 1 & 2; //? <+> 31 | 1 ^ 2; //? <+> 32 | 1 | 2; //? <+> 33 | 34 | /// logical: descending precedence 35 | true && false; //? <+> 36 | true || false; //? <+> 37 | undefined ?? null; //? <+> 38 | 39 | /// test operator precedence 40 | 1 + 2 + 3; //? <+> 41 | 1 - 2 - 3; //? <+> 42 | 1 + 2 - 3; //? <+> 43 | 1 - 2 + 3; //? <+> 44 | /// 45 | 1 + 2 * 3; //? <+> 46 | 1 * 2 + 3; //? <+> 47 | (1 + 2) * 3; //? <+> 48 | 1 * (2 + 3); //? <+> 49 | /// 50 | 1 + 2 + 3 + 4; //? <+> 51 | 52 | async function a() { await a ** b; } //? <-> @1:30 53 | -------------------------------------------------------------------------------- /test/data/native/expressions/call.js: -------------------------------------------------------------------------------- 1 | [1,2,3](); //? <+> 2 | async()()(); //? <+> 3 | async(await); //? <+> 4 | async 5 | (); //? <+> 6 | -------------------------------------------------------------------------------- /test/data/native/expressions/function.js: -------------------------------------------------------------------------------- 1 | //- contextual_identifier 2 | !function* yield(){}; //? <-> @1:12 3 | !function*(){ yield.a; }; //? <-> @1:20 -default 4 | !function*(){ var yield; }; //? <-> @1:19 5 | !function*(){ let yield; }; //? <-> @1:19 6 | !function*(){ yield: }; //? <-> @1:15 7 | /// 8 | !async function await(){}; //? <-> @1:17 9 | !async function(){ await.a; }; //? <-> @1:25 -default 10 | !async function(){ var await; }; //? <-> @1:24 11 | !async function(){ let await; }; //? <-> @1:24 12 | !async function(){ await: }; //? <-> @1:20 13 | /// 14 | !async function* yield(){}; //? <-> @1:18 15 | !async function*(){ yield.a; }; //? <-> @1:26 -default 16 | !async function*(){ var yield; }; //? <-> @1:25 17 | !async function*(){ let yield; }; //? <-> @1:25 18 | !async function*(){ yield: }; //? <-> @1:21 19 | /// 20 | !async function* await(){}; //? <-> @1:18 21 | !async function*(){ await.a; }; //? <-> @1:26 -default 22 | !async function*(){ var await; }; //? <-> @1:25 23 | !async function*(){ let await; }; //? <-> @1:25 24 | !async function*(){ await: }; //? <-> @1:21 25 | -------------------------------------------------------------------------------- /test/data/native/expressions/identifier.js: -------------------------------------------------------------------------------- 1 | let \u0061wait; // let await; //? <+?a> 2 | \u0061wait = 0; // await = 0; //? <+?> 3 | \u0061wait: ; // await: ; //? <+?> 4 | 5 | let yiel\u0064; // let yield; //? <+?> 6 | yiel\u0064 = 0; // yield = 0; //? <+?> 7 | yiel\u0064: ; // yield: ; //? <+?> 8 | 9 | 'use strict'; ev\u0061l: ; //? <+> 10 | 'use strict'; \u0061rguments: ; //? <+> 11 | 12 | //- unicode_keyword 13 | \u0069f(true){} // if(true){} //? <-> @1:1 14 | for(;;) \u0062reak; // for(;;) break; //? <-> @1:9 15 | switch(a) { c\u0061se 0: } // switch(a) { case 0: } //? <-> @1:13 16 | //- default 17 | l\u0065t a = 0; //? <-?> @1:1 18 | 'use strict'; l\u0065t a = 0; // let a = 0; //? <-?> @1:15 19 | 'use strict'; p\u0061ckage: ; // package: //? <-?> @1:15 20 | 'use strict'; let yi\u0065ld; // let yield; //? <-?> @1:19 21 | 22 | //- contextual_identifier 23 | function* a(){ let yi\u0065ld; } //? <-?> @1:20 24 | function* a(){ yi\u0065ld = 0; } //? <-?> @1:27 -default 25 | function* a(){ yi\u0065ld: ; } //? <-?> @1:16 26 | 27 | //- eval_args_in_strict_mode 28 | 'use strict'; let ev\u0061l; //? <-?> @1:19 29 | 'use strict'; let \u0061rguments; //? <-?> @1:19 30 | -------------------------------------------------------------------------------- /test/data/native/expressions/member.js: -------------------------------------------------------------------------------- 1 | a.b; //? <+> 2 | a[b]; //? <+> 3 | a`b`; //? <+> 4 | a.b.c; //? <+> 5 | a.b[c]; //? <+> 6 | a.b`c`; //? <+> 7 | a[b].c; //? <+> 8 | a[b][c]; //? <+> 9 | a[b]`c`; //? <+> 10 | a`b`.c; //? <+> 11 | a`b`[c]; //? <+> 12 | a`b``c`; //? <+> 13 | ````; //? <+> 14 | 15 | a.await; //? <+> 16 | a.yield; //? <+> 17 | a.let; //? <+> 18 | a.static; //? <+> 19 | a.implements; //? <+> 20 | a.interface; //? <+> 21 | a.package; //? <+> 22 | a.private; //? <+> 23 | a.protected; //? <+> 24 | a.public; //? <+> 25 | a.as; //? <+> 26 | a.async; //? <+> 27 | a.from; //? <+> 28 | a.get; //? <+> 29 | a.of; //? <+> 30 | a.set; //? <+> 31 | a.target; //? <+> 32 | a.if; //? <+> 33 | a.else; //? <+> 34 | a.for; //? <+> 35 | a.while 36 | 37 | new a; //? <+> 38 | new a(); //? <+> 39 | new new a; //? <+> 40 | new new a()(); //? <+> 41 | 42 | super; //? <-> @1:1 -standalone_super 43 | import.meta; //? <-> @1:1 -import_in_non_module 44 | new.target; //? <-> @1:1 -new_meta 45 | 46 | !{a(){ new.target; }}; //? <+> 47 | !{get a(){ new.target; }}; //? <+> 48 | !{set a(b){ new.target; }}; //? <+> 49 | !{a(b = new.target){}}; //? <+> 50 | !{set a(b = new.target){}}; //? <+> 51 | !function(){ new.target; } //? <+> 52 | !function(a = new.target){} //? <+> 53 | !class{ constructor(){ new.target; } } //? <+> 54 | !class{ a(){ new.target; } } //? <+> 55 | !class{ get a(){ new.target; } } //? <+> 56 | !class{ set a(b){ new.target; } } //? <+> 57 | !class{ constructor(a = new.target){} }; //? <+> 58 | !class{ a(b = new.target){} }; //? <+> 59 | !class{ set b(c = new.target){} }; //? <+> 60 | 61 | function a(){ new.target; } //? <+> 62 | function a(b = new.target){} //? <+> 63 | class a { constructor(){ new.target; } } //? <+> 64 | class a { b(){ new.target; } } //? <+> 65 | class a { get b(){ new.target; } } //? <+> 66 | class a { set b(c){ new.target; } } //? <+> 67 | class a { constructor(a = new.target){} }; //? <+> 68 | class a { a(b = new.target){} }; //? <+> 69 | class a { set b(c = new.target){} }; //? <+> 70 | -------------------------------------------------------------------------------- /test/data/native/expressions/optional.js: -------------------------------------------------------------------------------- 1 | a?.b; //? <+> 2 | a?.b?.c; //? <+> 3 | a.b?.c; //? <+> 4 | a?.b.c; //? <+> 5 | a?.b?.c; //? <+> 6 | 7 | a?.(); //? <+> 8 | a?.b?.(); //? <+> 9 | a.b?.(); //? <+> 10 | a?.b.c(); //? <+> 11 | a?.b?.c(); //? <+> 12 | a.b?.().c.d(); //? <+> 13 | -------------------------------------------------------------------------------- /test/data/native/expressions/super.js: -------------------------------------------------------------------------------- 1 | super; //? <-> @1:1 -standalone_super 2 | super.a; //? <-> @1:1 -misplaced_super_property 3 | super(); //? <-> @1:1 -misplaced_super_call 4 | 5 | !{ a(super){} }; //? <-> @1:6 -default 6 | !{ a(b = super){} }; //? <-> @1:10 -standalone_super 7 | !{ a(b = super()){} }; //? <-> @1:10 -misplaced_super_call 8 | !{ a(b = super.c){} }; //? <+> 9 | !{ a(){ super; } }; //? <-> @1:9 -standalone_super 10 | !{ a(){ b = super(); } }; //? <-> @1:13 -misplaced_super_call 11 | !{ a(){ super.c; } }; //? <+> 12 | 13 | !function a(super){} //? <-> @1:13 -default 14 | !function a(b = super){} //? <-> @1:17 -standalone_super 15 | !function a(b = super()){} //? <-> @1:17 -misplaced_super_call 16 | !function a(b = super.c){} //? <-> @1:17 -misplaced_super_property 17 | !function a(){ super; } //? <-> @1:16 -standalone_super 18 | !function a(){ b = super(); } //? <-> @1:20 -misplaced_super_call 19 | !function a(){ super.c; } //? <-> @1:16 -misplaced_super_property 20 | 21 | function a(super){} //? <-> @1:12 -default 22 | function a(b = super){} //? <-> @1:16 -standalone_super 23 | function a(b = super()){} //? <-> @1:16 -misplaced_super_call 24 | function a(b = super.c){} //? <-> @1:16 -misplaced_super_property 25 | function a(){ super; } //? <-> @1:15 -standalone_super 26 | function a(){ b = super(); } //? <-> @1:19 -misplaced_super_call 27 | function a(){ super.c; } //? <-> @1:15 -misplaced_super_property 28 | 29 | super => {}; //? <-> @1:1 -default 30 | (super) => {}; //? <-> @1:2 -default 31 | (a = super) => {}; //? <-> @1:6 -standalone_super 32 | (a = super.b) => {}; //? <-> @1:6 -misplaced_super_property 33 | (a = super()) => {}; //? <-> @1:6 -misplaced_super_call 34 | () => { super; }; //? <-> @1:9 -standalone_super 35 | () => { super.a; }; //? <-> @1:9 -misplaced_super_property 36 | () => { super(); }; //? <-> @1:9 -misplaced_super_call 37 | a => { super; }; //? <-> @1:8 -standalone_super 38 | a => { super.b; }; //? <-> @1:8 -misplaced_super_property 39 | a => { super(); }; //? <-> @1:8 -misplaced_super_call 40 | 41 | class a extends b { c(){ !{ d(super){} } } } //? <-> @1:31 -default 42 | class a extends b { c(){ !{ d(e = super){} } } } //? <-> @1:35 -standalone_super 43 | class a extends b { c(){ !{ d(e = super.f){} } } } //? <+> 44 | class a extends b { c(){ !{ d(e = super()){} } } } //? <-> @1:35 -misplaced_super_call 45 | class a extends b { c(){ !{ d(){ super; } } } } //? <-> @1:34 -standalone_super 46 | class a extends b { c(){ !{ d(){ super.e; } } } } //? <+> 47 | class a extends b { c(){ !{ d(){ super(); } } } } //? <-> @1:34 -misplaced_super_call 48 | class a extends b { c(){ !function d(super){} } } //? <-> @1:38 -default 49 | class a extends b { c(){ !function d(e = super){} } } //? <-> @1:42 -standalone_super 50 | class a extends b { c(){ !function d(e = super.f){} } } //? <-> @1:42 -misplaced_super_property 51 | class a extends b { c(){ !function d(e = super()){} } } //? <-> @1:42 -misplaced_super_call 52 | class a extends b { c(){ !function d(){ super; } } } //? <-> @1:41 -standalone_super 53 | class a extends b { c(){ !function d(){ super.e; } } } //? <-> @1:41 -misplaced_super_property 54 | class a extends b { c(){ !function d(){ super(); } } } //? <-> @1:41 -misplaced_super_call 55 | class a extends b { c(){ function d(super){} } } //? <-> @1:37 -default 56 | class a extends b { c(){ function d(e = super){} } } //? <-> @1:41 -standalone_super 57 | class a extends b { c(){ function d(e = super.f){} } } //? <-> @1:41 -misplaced_super_property 58 | class a extends b { c(){ function d(e = super()){} } } //? <-> @1:41 -misplaced_super_call 59 | class a extends b { c(){ function d(){ super; } } } //? <-> @1:40 -standalone_super 60 | class a extends b { c(){ function d(){ super.e; } } } //? <-> @1:40 -misplaced_super_property 61 | class a extends b { c(){ function d(){ super(); } } } //? <-> @1:40 -misplaced_super_call 62 | class a extends b { c(){ super => {} } } //? <-> @1:26 -default 63 | class a extends b { c(){ (super) => {} } } //? <-> @1:27 -default 64 | class a extends b { c(){ (d = super) => {} } } //? <-> @1:31 -standalone_super 65 | class a extends b { c(){ (d = super.e) => {} } } //? <+> 66 | class a extends b { c(){ (d = super()) => {} } } //? <-> @1:31 -misplaced_super_call 67 | class a extends b { c(){ () => { super; } } } //? <-> @1:34 -standalone_super 68 | class a extends b { c(){ () => { super.d; } } } //? <+> 69 | class a extends b { c(){ () => { super(); } } } //? <-> @1:34 -misplaced_super_call 70 | class a extends b { c(){ d => { super; } } } //? <-> @1:33 -standalone_super 71 | class a extends b { c(){ d => { super.e; } } } //? <+> 72 | class a extends b { c(){ d => { super(); } } } //? <-> @1:33 -misplaced_super_call 73 | 74 | class a { constructor(b = super()){} } //? <-> @1:27 -misplaced_super_call 75 | class a { constructor(){ super(); } } //? <-> @1:26 -misplaced_super_call 76 | 77 | class a { b(){ !{ c(d = super.e){} } } } //? <+> 78 | class b { b(){ !{ c(){ super.d; } } } } //? <+> 79 | class c { b(){ (d = super.e) => {} } } //? <+> 80 | class d { b(){ () => { super.c; } } } //? <+> 81 | class e { b(){ c => { super.d; } } } //? <+> 82 | class f { b(){ super.c; } } //? <+> 83 | 84 | class h extends f { constructor(g = super()){} } //? <+> 85 | class i extends f { constructor(){ super(); } } //? <+> 86 | class j extends f { constructor(){ (g = super()) => {} } } //? <+> 87 | class k extends f { constructor(){ () => { super(); } } } //? <+> 88 | class l extends f { constructor(){ g => { super(); } } } //? <+> 89 | -------------------------------------------------------------------------------- /test/data/native/expressions/unary.js: -------------------------------------------------------------------------------- 1 | delete 0; //? <+> 2 | void 0; //? <+> 3 | typeof 0; //? <+> 4 | +0; //? <+> 5 | -0; //? <+> 6 | ~0; //? <+> 7 | !0; //? <+> 8 | !async function(){ await 0; } //? <+> 9 | 10 | //- invalid_update 11 | this++; //? <-> @1:1 12 | this--; //? <-> @1:1 13 | ++this; //? <-> @1:3 14 | --this; //? <-> @1:3 15 | ++a; //? <+> 16 | ++null; //? <-> @1:3 17 | ++true; //? <-> @1:3 18 | ++false; //? <-> @1:3 19 | ++0; //? <-> @1:3 20 | ++'a'; //? <-> @1:3 21 | ++[]; //? <-> @1:3 22 | ++{}; //? <-> @1:3 23 | ++function(){}; //? <-> @1:3 24 | ++function*(){}; //? <-> @1:3 25 | ++async function(){}; //? <-> @1:3 26 | ++async function*(){}; //? <-> @1:3 27 | ++class{}; //? <-> @1:3 28 | ++/a/; //? <-> @1:3 29 | ++`a`; //? <-> @1:3 30 | ++a.b; //? <+> 31 | ++a[b]; //? <+> 32 | ++a`b`; //? <-> @1:3 33 | !{a(){ ++super.b; }}; //? <+> 34 | !{a(){ ++super[b]; }}; //? <+> 35 | !function(){ ++new.target; } //? <-> @1:16 36 | ++import.meta; //? <-#> @1:3 37 | ++new a; //? <-> @1:3 38 | ++a(); //? <-> @1:3 39 | ++a().b; //? <+> 40 | ++a()[b]; //? <+> 41 | class a extends b { constructor(){ ++super(); }}; //? <-> @1:38 42 | ++import('a'); //? <-#> @1:3 43 | ++a?.b; //? <-> @1:3 44 | ++ ++a; //? <-> @1:4 45 | /// 46 | ++(a); //? <+> 47 | ++(a.b); //? <+> 48 | ++(a[b]); //? <+> 49 | ++(a().b); //? <+> 50 | ++(a()[b]); //? <+> 51 | ++(((a()[b]))); //? <+> 52 | //- identifier_deletion 53 | 'use strict'; var a; delete a; //? <-> @1:29 54 | 'use strict'; var a; delete (a); //? <-> @1:30 55 | 'use strict'; var a; delete ((((a)))); //? <-> @1:33 56 | -------------------------------------------------------------------------------- /test/data/native/literals/.gitattributes: -------------------------------------------------------------------------------- 1 | * -text 2 | -------------------------------------------------------------------------------- /test/data/native/literals/array.js: -------------------------------------------------------------------------------- 1 | []; //? <+> 2 | [,]; //? <+> 3 | [1]; //? <+> 4 | [1,]; //? <+> 5 | [,1]; //? <+> 6 | [1,,2]; //? <+> 7 | [,1,,2,]; //? <+> 8 | [...a]; //? <+> 9 | [...a.b]; //? <+> 10 | [...a().b]; //? <+> 11 | [...(a)]; //? <+> 12 | [...(a.b)]; //? <+> 13 | [...(a().b)]; //? <+> 14 | [...[]]; //? <+> 15 | [...{}]; //? <+> 16 | [...[1, 2]]; //? <+> 17 | [...[l, ...m]]; //? <+> 18 | [...{a: 1, b: 2}]; //? <+> 19 | [...a = [1, 2]]; //? <+> 20 | [,...a]; //? <+> 21 | [...a,]; //? <+> 22 | [a, ...b]; //? <+> 23 | [...a, b]; //? <+> 24 | [, a, b, ...c]; //? <+> 25 | [, ...[], ...{}, a = 0]; //? <+> 26 | [...[...[...[...a]]]]; //? <+> 27 | 28 | [a = [1, 2]]; //? <+> 29 | [a = [b, c]]; //? <+> 30 | [a = [b, c = 1, [d, e] = [f, [, g = 2] = [3, [4]]]]]; //? <+> 31 | [a.b, [a.c, ...[a.d, a.e, a().f]]]; //? <+> 32 | -------------------------------------------------------------------------------- /test/data/native/literals/numeric.js: -------------------------------------------------------------------------------- 1 | /// decimal integer 2 | 0, 1, 12, 123; //? <+> 3 | 4 | /// binary integer 5 | 0b0, 0b1; //? <+> 6 | 0b00, 0b01, 0b10, 0b11; //? <+> 7 | 0b01010101, 0B10101010; //? <+> 8 | 9 | /// octal integer 10 | 0o0, 0o1, 0o2, 0o3, 0o4, 0o5, 0o6, 0o7; //? <+> 11 | 0o525, 0O252; //? <+> 12 | 13 | /// hexadecimal integer 14 | 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7; //? <+> 15 | 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf; //? <+> 16 | 0xA, 0xB, 0xC, 0xD, 0xE, 0xF; //? <+> 17 | 0x55, 0XAA; //? <+> 18 | 19 | /// real numbers 20 | 0., 1., 2.34, 5.067, 80.90, 0.e001, 2.03e+04, 56.70e-8; //? <+> 21 | .0, .1, .23, .045, .60e+07, .8e-9; //? <+> 22 | 0e0, 1E1, 2e00, 3e+0, 4e-0, 56e78, 9e01; //? <+> 23 | 24 | /// legacy octal 25 | 00, 007, 0123; //? <+> 26 | /// legacy decimal like 27 | 08, 09.0; //? <+> 28 | 07.0; //? <-> -default 29 | -------------------------------------------------------------------------------- /test/data/native/literals/object.js: -------------------------------------------------------------------------------- 1 | !{ a: 0 }; //? <+> 2 | !{ 'a': 0 }; //? <+> 3 | !{ 123: 0 }; //? <+> 4 | !{ [a]: 0 }; //? <+> 5 | !{ [(a)]: 0 }; //? <+> 6 | !{ a(){} }; //? <+> 7 | !{ 'a'(x){} }; //? <+> 8 | !{ 123(a, b){} }; //? <+> 9 | !{ [a + b](c){} }; //? <+> 10 | !{ [(a)](b){} }; //? <+> 11 | !{ a }; //? <+> 12 | !{ ...a }; //? <+> 13 | !{ *a(b){} }; //? <+> 14 | !{ async a(b){} }; //? <+> 15 | !{ async* a(b){} }; //? <+> 16 | !{ get a(){} }; //? <+> 17 | !{ get 'a'(){} }; //? <+> 18 | !{ get 123(){} }; //? <+> 19 | !{ get [a](){} }; //? <+> 20 | !{ get [(a)](){} }; //? <+> 21 | !{ set a(b){} }; //? <+> 22 | !{ set 'a'(b){} }; //? <+> 23 | !{ set 123(b){} }; //? <+> 24 | !{ set [a](b){} }; //? <+> 25 | !{ set [(a)](b){} }; //? <+> 26 | 27 | /// keywords 28 | !{ await: 0 }; //? <+> 29 | !{ yield: 0 }; //? <+> 30 | /// 31 | !{ let: 0 }; //? <+> 32 | !{ static: 0 }; //? <+> 33 | !{ implements: 0 }; //? <+> 34 | !{ interface: 0 }; //? <+> 35 | !{ package: 0 }; //? <+> 36 | !{ private: 0 }; //? <+> 37 | !{ protected: 0 }; //? <+> 38 | !{ public: 0 }; //? <+> 39 | /// 40 | !{ as: 0 }; //? <+> 41 | !{ async: 0 }; //? <+> 42 | !{ from: 0 }; //? <+> 43 | !{ get: 0 }; //? <+> 44 | !{ of: 0 }; //? <+> 45 | !{ set: 0 }; //? <+> 46 | !{ target: 0 }; //? <+> 47 | /// 48 | !{ break: 0 }; //? <+> 49 | !{ case: 0 }; //? <+> 50 | !{ catch: 0 }; //? <+> 51 | !{ class: 0 }; //? <+> 52 | !{ const: 0 }; //? <+> 53 | !{ continue: 0 }; //? <+> 54 | !{ debugger: 0 }; //? <+> 55 | !{ default: 0 }; //? <+> 56 | !{ delete: 0 }; //? <+> 57 | !{ do: 0 }; //? <+> 58 | !{ else: 0 }; //? <+> 59 | !{ enum: 0 }; //? <+> 60 | !{ export: 0 }; //? <+> 61 | !{ extends: 0 }; //? <+> 62 | !{ false: 0 }; //? <+> 63 | !{ finally: 0 }; //? <+> 64 | !{ for: 0 }; //? <+> 65 | !{ function: 0 }; //? <+> 66 | !{ if: 0 }; //? <+> 67 | !{ import: 0 }; //? <+> 68 | !{ in: 0 }; //? <+> 69 | !{ instanceof: 0 }; //? <+> 70 | !{ new: 0 }; //? <+> 71 | !{ null: 0 }; //? <+> 72 | !{ return: 0 }; //? <+> 73 | !{ super: 0 }; //? <+> 74 | !{ switch: 0 }; //? <+> 75 | !{ this: 0 }; //? <+> 76 | !{ throw: 0 }; //? <+> 77 | !{ true: 0 }; //? <+> 78 | !{ try: 0 }; //? <+> 79 | !{ typeof: 0 }; //? <+> 80 | !{ var: 0 }; //? <+> 81 | !{ void: 0 }; //? <+> 82 | !{ while: 0 }; //? <+> 83 | !{ with: 0 }; //? <+> 84 | 85 | /// class early errors that are not applicable to object literals 86 | !{ constructor(){}, constructor(){} }; //? <+> 87 | !{ * constructor(){} }; //? <+> 88 | !{ async constructor(){} }; //? <+> 89 | !{ async* constructor(){} }; //? <+> 90 | !{ get constructor(){} }; //? <+> 91 | !{ set constructor(b){} }; //? <+> 92 | 93 | //- duplicate_prototype 94 | !{__proto__: [], __proto__: []} //? <-&> @1:18 95 | !{__proto__: [], "__proto__": []} //? <-&> @1:18 96 | !{"__proto__": [], __proto__: []} //? <-&> @1:20 97 | !{__proto__: [], ["__proto__"]: []} //? <+> 98 | !{["__proto__"]: [], __proto__: []} //? <+> 99 | !{"__proto__": [], ["__proto__"]: []} //? <+> 100 | !{["__proto__"]: [], "__proto__": []} //? <+> 101 | !{__proto__: [], get __proto__(){}} //? <+> 102 | !{get __proto__(){}, __proto__: []} //? <+> 103 | !{__proto__: [], set __proto__(a){}} //? <+> 104 | !{set __proto__(a){}, __proto__: []} //? <+> 105 | 106 | //- invalid_cover_grammar 107 | !{a = 0}; //? <-> @1:3 108 | !{a: {b = 0}}; //? <-> @1:7 109 | !{a, b = 0, c: {d = 0}}; //? <-> @1:6 110 | -------------------------------------------------------------------------------- /test/data/native/literals/regexp.js: -------------------------------------------------------------------------------- 1 | /// line terminators 2 | //- terminated_regexp 3 | / 4 | /; //? <-> @1:2 5 | / /; //? <-> @1:2 6 | / 7 | /; //? <-> @1:2 8 | /
/; //? <-> @1:2 9 | /
/; //? <-> @1:2 10 | /\ 11 | /; //? <-> @1:3 12 | /\ /; //? <-> @1:3 13 | /\ 14 | /; //? <-> @1:3 15 | /\
/; //? <-> @1:3 16 | /\
/; //? <-> @1:3 17 | 18 | /// line terminators in classes 19 | //- terminated_regexp 20 | /[ 21 | ]/; //? <-> @1:3 22 | /[ ]/; //? <-> @1:3 23 | /[ 24 | ]/; //? <-> @1:3 25 | /[
]/; //? <-> @1:3 26 | /[
]/; //? <-> @1:3 27 | /[\ 28 | ]/; //? <-> @1:4 29 | /[\ ]/; //? <-> @1:4 30 | /[\ 31 | ]/; //? <-> @1:4 32 | /[\
]/; //? <-> @1:4 33 | /[\
]/; //? <-> @1:4 34 | 35 | //- unterminated_regexp 36 | / //? <-> @1:1 37 | -------------------------------------------------------------------------------- /test/data/native/literals/string.js: -------------------------------------------------------------------------------- 1 | '', "", 'a', 'bc', "d", "ef"; //? <+> 2 | /// SinglEscapeCharacter 3 | '\'', "\"", '\"', "\'"; //? <+> 4 | '\\', '\r', '\n', '\t', '\v', '\b', '\f'; //? <+> 5 | /// NonEscapeCharacter 6 | '\p'; //? <+> 7 | /// 8 | '\0'; //null character //? <+> 9 | '
'; //line separator //? <+> 10 | '
'; //paragraph separator //? <+> 11 | /// HexEscapeSequence 12 | '\x00', '\x80', '\xff'; //? <+> 13 | /// UnicodeEscapeSequence 14 | '\u2028', '\u{0}', '\u{1}', '\u{12}', '\u{123}', '\u{1234}'; //? <+> 15 | '\u{10000}', '\u{10ffff}', `\u{00000020}`; //? <+> 16 | // LineContinuation 17 | '\ 18 | '; //? <+> 19 | '\ '; //? <+> 20 | '\ 21 | '; //? <+> 22 | '\
'; // line separator //? <+> 23 | '\
'; // paragraph separator //? <+> 24 | /// legacy octal 25 | '\0', '\1', '\2', '\3', '\4', '\5', '\6', '\7'; //? <+&> 26 | '\00', '\01', '\77', '\000', '\001', '\377'; //? <+&> 27 | /// legacy non-octal 28 | '\8', '\9'; //? <+&> 29 | /// mixed octal 30 | '\08', '\78', '\81', '\91', '\378', '\381', '\401'; //? <+&> 31 | 32 | //- invalid_escape_sequence 33 | 'use strict'; '\1'; //? <-> @1:16 34 | 'use strict'; '\8'; //? <-> @1:16 35 | 'use strict'; '\01'; //? <-> @1:16 36 | 'use strict'; '\377'; //? <-> @1:16 37 | //- octal_in_strict 38 | '\1' 39 | 'use strict' //? <-?> @1:2 40 | '\1' 41 | 'use strict'; //? <-?> @1:2 42 | '' 43 | '\1' 44 | 'use strict' //? <-?> @2:2 45 | //- unicode_range 46 | '\u{110000}'; //? <-> @1:2 47 | 48 | /// line terminators 49 | //- newline_in_string_literal 50 | ' 51 | '; //? <-> @1:2 52 | ' '; //? <-> @1:2 53 | ' 54 | '; //? <-> @1:2 55 | '
'; //? <+> 56 | '
'; //? <+> 57 | '\ 58 | '; //? <+> 59 | '\ '; //? <+> 60 | '\ 61 | '; //? <+> 62 | '\
'; //? <+> 63 | '\
'; //? <+> 64 | -------------------------------------------------------------------------------- /test/data/native/literals/template.js: -------------------------------------------------------------------------------- 1 | /// simple templates 2 | ``; //? <+> 3 | `template`; //? <+> 4 | `${a}`; //? <+> 5 | `head-${a}`; //? <+> 6 | `${a}-tail`; //? <+> 7 | `${a}${b}`; //? <+> 8 | `head-${a}-tail`; //? <+> 9 | `head-${a}${b}`; //? <+> 10 | `${a}-middle-${b}`; //? <+> 11 | `${a}${b}-tail`; //? <+> 12 | `${a}${b}${c}`; //? <+> 13 | `head-${a}-middle-${b}-tail`; //? <+> 14 | `head-${a}${b}-tail`; //? <+> 15 | 16 | /// special characters 17 | `$`; //? <+> 18 | `{`; //? <+> 19 | `}`; //? <+> 20 | `\${`; //? <+> 21 | `$ {`; //? <+> 22 | `\``; //? <+> 23 | ` `; //? <+> 24 | ` 25 | `; //? <+> 26 | ` 27 | `; //? <+> 28 | 29 | /// nesting 30 | `${``}`, `${`${``}`}`; //? <+> 31 | `${``}-tail`, `head-${``}`; //? <+> 32 | `head-${`` - tail_expr}`; //? <+> 33 | `head-${`nested-head-${expr}` - tail_expr}`; //? <+> 34 | `head-${`${expr}-nested-tail` - tail_expr}`; //? <+> 35 | `head-${`nested-head-${expr}-nested-tail` - tail_expr}`; //? <+> 36 | `head-${head_expr - ``}`; //? <+> 37 | `head-${head_expr - `nested-head-${expr}`}`; //? <+> 38 | `head-${head_expr - `${expr}-nested-tail`}`; //? <+> 39 | `head-${head_expr - `nested-head-${expr}-nested-tail`}`; //? <+> 40 | `head-${head_expr - `` - tail_expr}`; //? <+> 41 | `head-${head_expr - `nested-head-${expr}` - tail_expr}`; //? <+> 42 | `head-${head_expr - `${expr}-nested-tail` - tail_expr}`; //? <+> 43 | `head-${head_expr - `nested-head-${expr}-nested-tail` - tail_expr}`; //? <+> 44 | 45 | /// tagged templates 46 | ````, a``; //? <+> 47 | `${````}`, `${a``}}`; //? <+> 48 | `` ``, `` `\``, `\`` ``, `\`` `\``; //? <+> 49 | 50 | /// special expressions / statements 51 | `${{a}}`; //? <+> 52 | { `${a}`; } //? <+> 53 | 54 | /// tagged not-escape sequences 55 | a`\01`, a`\1`; //? <+> 56 | a`\x`, a`\xg`, a`\x0g`; //? <+> 57 | a`\u`, a`\ug`, a`\u0g`, a`\u00g`, a`\u000g`; //? <+> 58 | a`\u{`, a`\u{g`, a`\u{0g`, a`\u{00g`, a`\u{000g`, a`\u{0000g`, a`\u{00000g`, a`\u{110000}`; //? <+> 59 | a`\u{ab`; //? <+> 60 | 61 | //- invalid_escape_sequence 62 | 'use strict'; '\1'; //? <-> @1:16 63 | 'use strict'; '\8'; //? <-> @1:16 64 | 'use strict'; '\01'; //? <-> @1:16 65 | 'use strict'; '\377'; //? <-> @1:16 66 | 67 | //- invalid_escape_sequence 68 | `\1`; //? <-> @1:2 69 | `\8`; //? <-> @1:2 70 | `\01`; //? <-> @1:2 71 | `\377`; //? <-> @1:2 72 | `\01`; //? <-> @1:2 73 | `\1`; //? <-> @1:2 74 | 75 | /// not-escape sequences 76 | //- invalid_escape_sequence 77 | `\x`; //? <-> @1:2 78 | `\xg`; //? <-> @1:2 79 | `\x0g`; //? <-> @1:2 80 | `\u`; //? <-> @1:2 81 | `\ug`; //? <-> @1:2 82 | `\u0g`; //? <-> @1:2 83 | `\u00g`; //? <-> @1:2 84 | `\u000g`; //? <-> @1:2 85 | `\u{`; //? <-> @1:2 86 | `\u{g`; //? <-> @1:2 87 | //- missing_unicode_closing 88 | `\u{0g`; //? <-> @1:2 89 | `\u{00g`; //? <-> @1:2 90 | `\u{000g`; //? <-> @1:2 91 | `\u{0000g`; //? <-> @1:2 92 | `\u{00000g`; //? <-> @1:2 93 | //- unicode_range 94 | `\u{110000}`; //? <-> @1:2 95 | -------------------------------------------------------------------------------- /test/data/native/misc/auto_semicolon.js: -------------------------------------------------------------------------------- 1 | for(;;){ continue } //? <+> 2 | for(;;){ break } //? <+> 3 | function a(){ return } //? <+> 4 | function* a(){ yield } //? <+> 5 | async function a(){ await 0 } //? <+> 6 | debugger 7 | {1 8 | 2} 3 //? <+> 9 | do ; while(false) //? <+> 10 | for(;;){ 11 | continue 12 | 1 13 | } //? <+> 14 | for(;;){ 15 | break 16 | 1 17 | } //? <+> 18 | function a(){ 19 | return 20 | 1; 21 | } //? <+> 22 | function* a(){ 23 | yield 24 | 1; 25 | } //? <+> 26 | a = b //? <+> 27 | ++a //? <+> 28 | a = b + c //? <+> 29 | (a + b).print() //? <+> 30 | function a() { 31 | return /* inline */ 1; 32 | } //? <+> 33 | function a() { 34 | return /* multi-line 35 | */ 1; 36 | } //? <+> 37 | function a() { 38 | return /* inline */ /* multi-line 39 | */1; 40 | } //? <+> 41 | function a() { 42 | return /* multi-line 43 | */ /* inline */ 1; 44 | } //? <+> 45 | function a() { 46 | return /* inline */ /* multi-line 47 | */ /* inline */ 1; 48 | } //? <+> 49 | -------------------------------------------------------------------------------- /test/data/native/misc/code.js: -------------------------------------------------------------------------------- 1 | //# {"allow_empty": true} 2 | //? <+> 3 | //? <+#> 4 | import.meta; //? <+#> 5 | -------------------------------------------------------------------------------- /test/data/native/misc/contextual_keywords.js: -------------------------------------------------------------------------------- 1 | import as from ''; //? <+#> 2 | import {as} from ''; //? <+#> 3 | import {as as as} from ''; //? <+#> 4 | export * as as from ''; //? <+#> 5 | export {as} from ''; //? <+#> 6 | export {as as as} from ''; //? <+#> 7 | 8 | !{ async async(){ async; } }; //? <+> 9 | async async => async; //? <+> 10 | async (async) => async; //? <+> 11 | async function async(){ async; } //? <+> 12 | class async { async async(){ async; }} //? <+> 13 | !async function async(){ async; } //? <+> 14 | !class async { async async(){ async; }} //? <+> 15 | /// 'async extends async' is not a compile time error but is a runtime error 16 | class async extends async { async async(){ async; }} //? <+> 17 | !class async extends async { async async(){ async; }} //? <+> 18 | 19 | import from from ''; //? <+#> 20 | 21 | !{ get get(){} }; //? <+> 22 | class get { get get(){} } //? <+> 23 | !class get { get get(){} }; //? <+> 24 | 25 | !{ set set(set){} }; //? <+> 26 | class set { set set(set){} } //? <+> 27 | !class set { set set(set){} }; //? <+> 28 | 29 | for(of of of); //? <+> 30 | -------------------------------------------------------------------------------- /test/data/native/misc/keywords/_keywords.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import url from 'url'; 3 | import path from 'path'; 4 | 5 | const file_path = url.fileURLToPath(import.meta.url); 6 | const parsed = path.parse(file_path); 7 | const test_dir_re = new RegExp(`${path.sep}test${path.sep}.+`); 8 | const test_dir = file_path.replace(test_dir_re, `${path.sep}test`); 9 | 10 | (async () => { 11 | const Expander = (await import(path.join(test_dir, 'expander.js'))).default; 12 | { 13 | const config = { 14 | keywords: [ 15 | 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 16 | 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 17 | 'false', 'finally', 'for', 'function', 'if', 'import', 'in', 18 | 'instanceof', 'new', 'null', 'return', 'super', 'switch', 'this', 19 | 'throw', 'true', 'try', 'typeof', 'var', 'void', 'while', 'with' 20 | ] 21 | } 22 | //const template_path = path.join(parsed.dir, '_contextual.tmpl.js'); 23 | const output_path = path.join(parsed.dir, 'reserved_words.js'); 24 | let expander = new Expander(output_path, config); 25 | expander.expand('!{keyword: 0}; //? <+>'); 26 | expander.expand('a.keyword; //? <+>'); 27 | expander.expand('var keyword; //? <-> @1:5', 'reserved_word_as_variable'); 28 | expander.expand('let keyword; //? <-> @1:5', 'expect ;', { 29 | in: '//? <-> @1:7 -default', instanceof: '//? <-> @1:15 -default' 30 | }); 31 | expander.expand('const keyword = 0; //? <-> @1:7', 'reserved_word_as_variable'); 32 | expander.expand(`'use strict'; let keyword; //? <-> @1:19`, 'reserved_word_as_variable'); 33 | expander.write(); 34 | } 35 | { 36 | const config = { 37 | keywords: [ 38 | 'eval', 'arguments', 'yield', 'await', 39 | 'let', 'static', 'implements', 'interface', 40 | 'package', 'private', 'protected', 'public' 41 | ], 42 | errors: { 43 | eval: 'eval_args_in_strict_mode', 44 | arguments: 'eval_args_in_strict_mode', 45 | yield: 'yield_in_strict_mode', 46 | await: 'await_in_module', 47 | __default__: 'invalid_strict_mode_identifier' 48 | }, 49 | error_overrides: new Set(['await']) 50 | } 51 | const template_path = path.join(parsed.dir, '_keywords.tmpl.js'); 52 | const output_path = path.join(parsed.dir, 'strict_mode.js'); 53 | let template = fs.readFileSync(template_path).toString(); 54 | let expander = new Expander(output_path, config); 55 | expander.group_expand(template); 56 | expander.write(); 57 | } 58 | { 59 | const keywords = ['as', 'async', 'from', 'get', 'of', 'set', 'target']; 60 | const config = { 61 | keywords: keywords, errors: {}, 62 | error_overrides: new Set(keywords) 63 | } 64 | const template_path = path.join(parsed.dir, '_keywords.tmpl.js'); 65 | const output_path = path.join(parsed.dir, 'contextual.js'); 66 | let template = fs.readFileSync(template_path).toString(); 67 | let expander = new Expander(output_path, config); 68 | expander.group_expand(template); 69 | expander.write(); 70 | } 71 | })(); 72 | -------------------------------------------------------------------------------- /test/data/native/misc/keywords/_keywords.tmpl.js: -------------------------------------------------------------------------------- 1 | keyword; //? <+> 2 | [keyword]; //? <+> 3 | [...keyword]; //? <+> 4 | !{keyword}; //? <+> 5 | !{keyword: 0}; //? <+> 6 | !{[keyword]: 0}; //? <+> 7 | !{keyword = 0}; //? <-> @1:3 -invalid_cover_grammar $override 8 | /*{ "skip-error-override": true }*/ 9 | !{ keyword(){} } //? <+> 10 | !{ [keyword](){} } //? <+> 11 | !{ a(keyword){} } //? <+> 12 | !{ a([keyword]){} } //? <+> 13 | !{ a({keyword}){} } //? <+> 14 | !{ a([...keyword]){} } //? <+> 15 | !{ a({...keyword}){} } //? <+> 16 | !{ a(...keyword){} } //? <+> 17 | !{ set a(keyword){} } //? <+> 18 | !{ set a([keyword]){} } //? <+> 19 | !{ set a({keyword}){} } //? <+> 20 | !{ set a([...keyword]){} } //? <+> 21 | !{ set a({...keyword}){} } //? <+> 22 | !{ set a(...keyword){} } //? <-> @1:10 -default $override 23 | /*{ "skip-error-override": true }*/ 24 | !function keyword(){} //? <+> 25 | !function a(keyword){} //? <+> 26 | !function a(b = keyword){} //? <+> 27 | !function a([keyword]){} //? <+> 28 | !function a({keyword}){} //? <+> 29 | !function a([...keyword]){} //? <+> 30 | !function a({...keyword}){} //? <+> 31 | !function a(...keyword){} //? <+> 32 | !class keyword {} //? <-> @1:8 33 | !class a extends keyword {} //? <-> @1:18 $override 34 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 35 | !class a { keyword(){} } //? <+> 36 | !class a { [keyword](){} } //? <-> @1:13 $override 37 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 38 | !class a { b(keyword){} } //? <-> @1:14 39 | !class a { b([keyword]){} } //? <-> @1:15 40 | !class a { b({keyword}){} } //? <-> @1:15 41 | !class a { b([...keyword]){} } //? <-> @1:18 42 | !class a { b({...keyword}){} } //? <-> @1:18 43 | !class a { b(...keyword){} } //? <-> @1:17 44 | `${keyword}`; //? <+> 45 | a.keyword; //? <+> 46 | ``.keyword; //? <+> 47 | keyword++; //? <+> 48 | ++keyword; //? <+> 49 | keyword = 0; //? <+> 50 | keyword *= 0; //? <+> 51 | [keyword] = []; //? <+> 52 | ({keyword} = {}); //? <+> 53 | ({keyword = 0} = {}); //? <+> 54 | [...keyword] = []; //? <+> 55 | ({...keyword} = {}); //? <+> 56 | keyword => {}; //? <+> 57 | (keyword) => {}; //? <+> 58 | ([keyword]) => {}; //? <+> 59 | ({keyword}) => {}; //? <+> 60 | ([...keyword]) => {}; //? <+> 61 | ({...keyword}) => {}; //? <+> 62 | (...keyword) => {}; //? <+> 63 | async (keyword) => {}; //? <+> $override 64 | /*{ "await": "<-> @1:8 -yield_await_in_arrow_params" }*/ 65 | async ([keyword]) => {}; //? <+> $override 66 | /*{ "await": "<-> @1:9 -yield_await_in_arrow_params" }*/ 67 | async ({keyword}) => {}; //? <+> $override 68 | /*{ "await": "<-> @1:9 -yield_await_in_arrow_params" }*/ 69 | async ([...keyword]) => {}; //? <+> $override 70 | /*{ "await": "<-> @1:12 -yield_await_in_arrow_params" }*/ 71 | async ({...keyword}) => {}; //? <+> $override 72 | /*{ "await": "<-> @1:12 -yield_await_in_arrow_params" }*/ 73 | async (...keyword) => {}; //? <+> $override 74 | /*{ "await": "<-> @1:11 -yield_await_in_arrow_params" }*/ 75 | keyword: ; //? <+> 76 | var keyword; //? <+> 77 | var [keyword] = []; //? <+> 78 | var {keyword} = {}; //? <+> 79 | var [...keyword] = []; //? <+> 80 | var {...keyword} = {}; //? <+> 81 | let keyword; //? <+> $override 82 | /*{ "let": "<-> @1:5 -let_in_lexical" }*/ 83 | let [keyword] = []; //? <+> $override 84 | /*{ "let": "<-> @1:6 -let_in_lexical" }*/ 85 | let {keyword} = {}; //? <+> $override 86 | /*{ "let": "<-> @1:6 -let_in_lexical" }*/ 87 | let [...keyword] = []; //? <+> $override 88 | /*{ "let": "<-> @1:9 -let_in_lexical" }*/ 89 | let {...keyword} = {}; //? <+> $override 90 | /*{ "let": "<-> @1:9 -let_in_lexical" }*/ 91 | const keyword = 0; //? <+> $override 92 | /*{ "let": "<-> @1:7 -let_in_lexical" }*/ 93 | const [keyword] = 0; //? <+> $override 94 | /*{ "let": "<-> @1:8 -let_in_lexical" }*/ 95 | const {keyword} = 0; //? <+> $override 96 | /*{ "let": "<-> @1:8 -let_in_lexical" }*/ 97 | const [...keyword] = 0; //? <+> $override 98 | /*{ "let": "<-> @1:11 -let_in_lexical" }*/ 99 | const {...keyword} = 0; //? <+> $override 100 | /*{ "let": "<-> @1:11 -let_in_lexical" }*/ 101 | function keyword(){} //? <+> 102 | function a(keyword){} //? <+> 103 | function a(b = keyword){} //? <+> 104 | function a([keyword]){} //? <+> 105 | function a({keyword}){} //? <+> 106 | function a([...keyword]){} //? <+> 107 | function a({...keyword}){} //? <+> 108 | function a(...keyword){} //? <+> 109 | class keyword {} //? <-> @1:7 110 | class a extends keyword {} //? <-> @1:17 $override 111 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 112 | class a { keyword(){} } //? <+> 113 | class a { [keyword](){} } //? <-> @1:12 $override 114 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 115 | class a { b(keyword){} } //? <-> @1:13 116 | class a { b([keyword]){} } //? <-> @1:14 117 | class a { b({keyword}){} } //? <-> @1:14 118 | class a { b([...keyword]){} } //? <-> @1:17 119 | class a { b({...keyword}){} } //? <-> @1:17 120 | class a { b(...keyword){} } //? <-> @1:16 121 | -------------------------------------------------------------------------------- /test/data/native/misc/keywords/await_in_module.js: -------------------------------------------------------------------------------- 1 | //- await_in_module 2 | await; //? <-#> @1:1 3 | await = 0; //? <-#> @1:1 4 | await *= 0; //? <-#> @1:1 5 | await++; //? <-#> @1:1 6 | ++await; //? <-#> @1:3 7 | !{await}; //? <-#> @1:3 8 | !{await = 0}; //? <-#> @1:3 9 | [await] = []; //? <-#> @1:2 10 | ({await} = {}); //? <-#> @1:3 11 | ({await = 0} = {}); //? <-#> @1:3 12 | [...await] = []; //? <-#> @1:5 13 | ({...await} = {}); //? <-#> @1:6 14 | await: ; //? <-#> @1:1 15 | var await; //? <-#> @1:5 16 | var [await] = []; //? <-#> @1:6 17 | var {await} = {}; //? <-#> @1:6 18 | var [...await] = []; //? <-#> @1:9 19 | var {...await} = {}; //? <-#> @1:9 20 | let await; //? <-#> @1:5 21 | let [await] = []; //? <-#> @1:6 22 | let {await} = {}; //? <-#> @1:6 23 | let [...await] = []; //? <-#> @1:9 24 | let {...await} = {}; //? <-#> @1:9 25 | const await = 0; //? <-#> @1:7 26 | const [await] = []; //? <-#> @1:8 27 | const {await} = {}; //? <-#> @1:8 28 | const [...await] = []; //? <-#> @1:11 29 | const {...await} = {}; //? <-#> @1:11 30 | function await(){} //? <-#> @1:10 31 | function a(await){} //? <-#> @1:12 32 | function a([await]){} //? <-#> @1:13 33 | function a({await}){} //? <-#> @1:13 34 | function a(...await){} //? <-#> @1:15 35 | !function await(){} //? <-#> @1:11 36 | !function a(await){} //? <-#> @1:13 37 | !function a([await]){} //? <-#> @1:14 38 | !function a({await}){} //? <-#> @1:14 39 | !function a(...await){} //? <-#> @1:16 40 | class await {} //? <-#> @1:7 41 | class a { await(){} } //? <+#> 42 | class a { b(await){} } //? <-#> @1:13 43 | class a { b([await]){} } //? <-#> @1:14 44 | class a { b({await}){} } //? <-#> @1:14 45 | class a { b(...await){} } //? <-#> @1:16 46 | !class await {} //? <-#> @1:8 47 | !class a { await(){} } //? <+#> 48 | !class a { b(await){} } //? <-#> @1:14 49 | !class a { b([await]){} } //? <-#> @1:15 50 | !class a { b({await}){} } //? <-#> @1:15 51 | !class a { b(...await){} } //? <-#> @1:17 52 | !{ await(){} } //? <+#> 53 | !{ a(await){} } //? <-#> @1:6 54 | !{ a([await]){} } //? <-#> @1:7 55 | !{ a({await}){} } //? <-#> @1:7 56 | !{ a(...await){} } //? <-#> @1:9 57 | await => {}; //? <-#> @1:1 58 | (await) => {}; //? <-#> @1:2 59 | ([await]) => {}; //? <-#> @1:3 60 | ({await}) => {}; //? <-#> @1:3 61 | (...await) => {}; //? <-#> @1:5 62 | async(await) => {}; //? <-#> @1:7 63 | async([await]) => {}; //? <-#> @1:8 64 | async({await}) => {}; //? <-#> @1:8 65 | async(...await) => {}; //? <-#> @1:10 66 | -------------------------------------------------------------------------------- /test/data/native/misc/keywords/reserved_words.js: -------------------------------------------------------------------------------- 1 | /// 2 | !{break: 0}; //? <+> 3 | !{case: 0}; //? <+> 4 | !{catch: 0}; //? <+> 5 | !{class: 0}; //? <+> 6 | !{const: 0}; //? <+> 7 | !{continue: 0}; //? <+> 8 | !{debugger: 0}; //? <+> 9 | !{default: 0}; //? <+> 10 | !{delete: 0}; //? <+> 11 | !{do: 0}; //? <+> 12 | !{else: 0}; //? <+> 13 | !{enum: 0}; //? <+> 14 | !{export: 0}; //? <+> 15 | !{extends: 0}; //? <+> 16 | !{false: 0}; //? <+> 17 | !{finally: 0}; //? <+> 18 | !{for: 0}; //? <+> 19 | !{function: 0}; //? <+> 20 | !{if: 0}; //? <+> 21 | !{import: 0}; //? <+> 22 | !{in: 0}; //? <+> 23 | !{instanceof: 0}; //? <+> 24 | !{new: 0}; //? <+> 25 | !{null: 0}; //? <+> 26 | !{return: 0}; //? <+> 27 | !{super: 0}; //? <+> 28 | !{switch: 0}; //? <+> 29 | !{this: 0}; //? <+> 30 | !{throw: 0}; //? <+> 31 | !{true: 0}; //? <+> 32 | !{try: 0}; //? <+> 33 | !{typeof: 0}; //? <+> 34 | !{var: 0}; //? <+> 35 | !{void: 0}; //? <+> 36 | !{while: 0}; //? <+> 37 | !{with: 0}; //? <+> 38 | 39 | /// 40 | a.break; //? <+> 41 | a.case; //? <+> 42 | a.catch; //? <+> 43 | a.class; //? <+> 44 | a.const; //? <+> 45 | a.continue; //? <+> 46 | a.debugger; //? <+> 47 | a.default; //? <+> 48 | a.delete; //? <+> 49 | a.do; //? <+> 50 | a.else; //? <+> 51 | a.enum; //? <+> 52 | a.export; //? <+> 53 | a.extends; //? <+> 54 | a.false; //? <+> 55 | a.finally; //? <+> 56 | a.for; //? <+> 57 | a.function; //? <+> 58 | a.if; //? <+> 59 | a.import; //? <+> 60 | a.in; //? <+> 61 | a.instanceof; //? <+> 62 | a.new; //? <+> 63 | a.null; //? <+> 64 | a.return; //? <+> 65 | a.super; //? <+> 66 | a.switch; //? <+> 67 | a.this; //? <+> 68 | a.throw; //? <+> 69 | a.true; //? <+> 70 | a.try; //? <+> 71 | a.typeof; //? <+> 72 | a.var; //? <+> 73 | a.void; //? <+> 74 | a.while; //? <+> 75 | a.with; //? <+> 76 | 77 | //- reserved_word_as_variable 78 | var break; //? <-> @1:5 79 | var case; //? <-> @1:5 80 | var catch; //? <-> @1:5 81 | var class; //? <-> @1:5 82 | var const; //? <-> @1:5 83 | var continue; //? <-> @1:5 84 | var debugger; //? <-> @1:5 85 | var default; //? <-> @1:5 86 | var delete; //? <-> @1:5 87 | var do; //? <-> @1:5 88 | var else; //? <-> @1:5 89 | var enum; //? <-> @1:5 90 | var export; //? <-> @1:5 91 | var extends; //? <-> @1:5 92 | var false; //? <-> @1:5 93 | var finally; //? <-> @1:5 94 | var for; //? <-> @1:5 95 | var function; //? <-> @1:5 96 | var if; //? <-> @1:5 97 | var import; //? <-> @1:5 98 | var in; //? <-> @1:5 99 | var instanceof; //? <-> @1:5 100 | var new; //? <-> @1:5 101 | var null; //? <-> @1:5 102 | var return; //? <-> @1:5 103 | var super; //? <-> @1:5 104 | var switch; //? <-> @1:5 105 | var this; //? <-> @1:5 106 | var throw; //? <-> @1:5 107 | var true; //? <-> @1:5 108 | var try; //? <-> @1:5 109 | var typeof; //? <-> @1:5 110 | var var; //? <-> @1:5 111 | var void; //? <-> @1:5 112 | var while; //? <-> @1:5 113 | var with; //? <-> @1:5 114 | 115 | //- expect ; 116 | let break; //? <-> @1:5 117 | let case; //? <-> @1:5 118 | let catch; //? <-> @1:5 119 | let class; //? <-> @1:5 120 | let const; //? <-> @1:5 121 | let continue; //? <-> @1:5 122 | let debugger; //? <-> @1:5 123 | let default; //? <-> @1:5 124 | let delete; //? <-> @1:5 125 | let do; //? <-> @1:5 126 | let else; //? <-> @1:5 127 | let enum; //? <-> @1:5 128 | let export; //? <-> @1:5 129 | let extends; //? <-> @1:5 130 | let false; //? <-> @1:5 131 | let finally; //? <-> @1:5 132 | let for; //? <-> @1:5 133 | let function; //? <-> @1:5 134 | let if; //? <-> @1:5 135 | let import; //? <-> @1:5 136 | let in; //? <-> @1:7 -default 137 | let instanceof; //? <-> @1:15 -default 138 | let new; //? <-> @1:5 139 | let null; //? <-> @1:5 140 | let return; //? <-> @1:5 141 | let super; //? <-> @1:5 142 | let switch; //? <-> @1:5 143 | let this; //? <-> @1:5 144 | let throw; //? <-> @1:5 145 | let true; //? <-> @1:5 146 | let try; //? <-> @1:5 147 | let typeof; //? <-> @1:5 148 | let var; //? <-> @1:5 149 | let void; //? <-> @1:5 150 | let while; //? <-> @1:5 151 | let with; //? <-> @1:5 152 | 153 | //- reserved_word_as_variable 154 | const break = 0; //? <-> @1:7 155 | const case = 0; //? <-> @1:7 156 | const catch = 0; //? <-> @1:7 157 | const class = 0; //? <-> @1:7 158 | const const = 0; //? <-> @1:7 159 | const continue = 0; //? <-> @1:7 160 | const debugger = 0; //? <-> @1:7 161 | const default = 0; //? <-> @1:7 162 | const delete = 0; //? <-> @1:7 163 | const do = 0; //? <-> @1:7 164 | const else = 0; //? <-> @1:7 165 | const enum = 0; //? <-> @1:7 166 | const export = 0; //? <-> @1:7 167 | const extends = 0; //? <-> @1:7 168 | const false = 0; //? <-> @1:7 169 | const finally = 0; //? <-> @1:7 170 | const for = 0; //? <-> @1:7 171 | const function = 0; //? <-> @1:7 172 | const if = 0; //? <-> @1:7 173 | const import = 0; //? <-> @1:7 174 | const in = 0; //? <-> @1:7 175 | const instanceof = 0; //? <-> @1:7 176 | const new = 0; //? <-> @1:7 177 | const null = 0; //? <-> @1:7 178 | const return = 0; //? <-> @1:7 179 | const super = 0; //? <-> @1:7 180 | const switch = 0; //? <-> @1:7 181 | const this = 0; //? <-> @1:7 182 | const throw = 0; //? <-> @1:7 183 | const true = 0; //? <-> @1:7 184 | const try = 0; //? <-> @1:7 185 | const typeof = 0; //? <-> @1:7 186 | const var = 0; //? <-> @1:7 187 | const void = 0; //? <-> @1:7 188 | const while = 0; //? <-> @1:7 189 | const with = 0; //? <-> @1:7 190 | 191 | //- reserved_word_as_variable 192 | 'use strict'; let break; //? <-> @1:19 193 | 'use strict'; let case; //? <-> @1:19 194 | 'use strict'; let catch; //? <-> @1:19 195 | 'use strict'; let class; //? <-> @1:19 196 | 'use strict'; let const; //? <-> @1:19 197 | 'use strict'; let continue; //? <-> @1:19 198 | 'use strict'; let debugger; //? <-> @1:19 199 | 'use strict'; let default; //? <-> @1:19 200 | 'use strict'; let delete; //? <-> @1:19 201 | 'use strict'; let do; //? <-> @1:19 202 | 'use strict'; let else; //? <-> @1:19 203 | 'use strict'; let enum; //? <-> @1:19 204 | 'use strict'; let export; //? <-> @1:19 205 | 'use strict'; let extends; //? <-> @1:19 206 | 'use strict'; let false; //? <-> @1:19 207 | 'use strict'; let finally; //? <-> @1:19 208 | 'use strict'; let for; //? <-> @1:19 209 | 'use strict'; let function; //? <-> @1:19 210 | 'use strict'; let if; //? <-> @1:19 211 | 'use strict'; let import; //? <-> @1:19 212 | 'use strict'; let in; //? <-> @1:19 213 | 'use strict'; let instanceof; //? <-> @1:19 214 | 'use strict'; let new; //? <-> @1:19 215 | 'use strict'; let null; //? <-> @1:19 216 | 'use strict'; let return; //? <-> @1:19 217 | 'use strict'; let super; //? <-> @1:19 218 | 'use strict'; let switch; //? <-> @1:19 219 | 'use strict'; let this; //? <-> @1:19 220 | 'use strict'; let throw; //? <-> @1:19 221 | 'use strict'; let true; //? <-> @1:19 222 | 'use strict'; let try; //? <-> @1:19 223 | 'use strict'; let typeof; //? <-> @1:19 224 | 'use strict'; let var; //? <-> @1:19 225 | 'use strict'; let void; //? <-> @1:19 226 | 'use strict'; let while; //? <-> @1:19 227 | 'use strict'; let with; //? <-> @1:19 228 | 229 | -------------------------------------------------------------------------------- /test/data/native/misc/keywords/reserved_words.manual.js: -------------------------------------------------------------------------------- 1 | /// IdentifierReference 2 | //- default 3 | break = 0; //? <-> @1:1 -unsyntatic_break 4 | case = 0; //? <-> @1:1 5 | catch = 0; //? <-> @1:1 6 | class = 0; //? <-> @1:7 7 | const = 0; //? <-> @1:7 -missing_variable_name 8 | continue = 0; //? <-> @1:1 -unsyntatic_continue 9 | debugger = 0; //? <-> @1:10 -expect ; 10 | default = 0; //? <-> @1:1 11 | delete = 0; //? <-> @1:8 12 | do = 0; //? <-> @1:4 13 | else = 0; //? <-> @1:1 14 | enum = 0; //? <-> @1:1 15 | export = 0; //? <-#> @1:8 16 | extends = 0; //? <-> @1:1 17 | false = 0; //? <-> @1:1 -invalid_assignment_target 18 | finally = 0; //? <-> @1:1 19 | for = 0; //? <-> @1:5 -expect ( 20 | function = 0; //? <-> @1:10 21 | if = 0; //? <-> @1:4 -expect ( 22 | import = 0; //? <-#> @1:8 23 | in = 0; //? <-> @1:1 24 | instanceof = 0; //? <-> @1:1 25 | new = 0; //? <-> @1:5 26 | null = 0; //? <-> @1:1 -invalid_assignment_target 27 | return = 0; //? <-> @1:1 -unsyntatic_return 28 | super = 0; //? <-> @1:1 -standalone_super 29 | switch = 0; //? <-> @1:8 -expect ( 30 | this = 0; //? <-> @1:1 -invalid_assignment_target 31 | throw = 0; //? <-> @1:7 32 | true = 0; //? <-> @1:1 -invalid_assignment_target 33 | try = 0; //? <-> @1:5 -expect { 34 | typeof = 0; //? <-> @1:8 35 | var = 0; //? <-> @1:5 -missing_variable_name 36 | void = 0; //? <-> @1:6 37 | while = 0; //? <-> @1:7 -expect ( 38 | with = 0; //? <-> @1:6 -expect ( 39 | 40 | /// LabelIdentifier 41 | //- default 42 | break: ; //? <-> @1:1 -unsyntatic_break 43 | case: ; //? <-> @1:1 44 | catch: ; //? <-> @1:1 45 | class: ; //? <-> @1:6 46 | const: ; //? <-> @1:6 -missing_variable_name 47 | continue: ; //? <-> @1:1 -unsyntatic_continue 48 | debugger: ; //? <-> @1:9 -expect ; 49 | default: ; //? <-> @1:1 50 | delete: ; //? <-> @1:7 51 | do: ; //? <-> @1:3 52 | else: ; //? <-> @1:1 53 | enum: ; //? <-> @1:1 54 | export: ; //? <-#> @1:7 55 | extends: ; //? <-> @1:1 56 | false: ; //? <-> @1:6 57 | finally: ; //? <-> @1:1 58 | for: ; //? <-> @1:4 -expect ( 59 | function: ; //? <-> @1:9 60 | if: ; //? <-> @1:3 -expect ( 61 | import: ; //? <-#> @1:7 62 | in: ; //? <-> @1:1 63 | instanceof: ; //? <-> @1:1 64 | new: ; //? <-> @1:4 65 | null: ; //? <-> @1:5 66 | return: ; //? <-> @1:1 -unsyntatic_return 67 | super: ; //? <-> @1:1 -standalone_super 68 | switch: ; //? <-> @1:7 -expect ( 69 | this: ; //? <-> @1:5 70 | throw: ; //? <-> @1:6 71 | true: ; //? <-> @1:5 72 | try: ; //? <-> @1:4 -expect { 73 | typeof: ; //? <-> @1:7 74 | var: ; //? <-> @1:4 -missing_variable_name 75 | void: ; //? <-> @1:5 76 | while: ; //? <-> @1:6 -expect ( 77 | with: ; //? <-> @1:5 -expect ( 78 | -------------------------------------------------------------------------------- /test/data/native/misc/lexical_uniqueness/arrow_expression.js: -------------------------------------------------------------------------------- 1 | //- duplicate_symbol 2 | (a, a) => {} //? <-> @1:5 3 | ([a, a]) => {} //? <-> @1:6 4 | (a, a = 0) => {} //? <-> @1:5 5 | (a, [a]) => {} //? <-> @1:6 6 | (a, {a}) => {} //? <-> @1:6 7 | (a, ...a) => {} //? <-> @1:8 8 | (a = 0, a) => {} //? <-> @1:9 9 | ([a], a) => {} //? <-> @1:7 10 | ({a}, a) => {} //? <-> @1:7 11 | ([a], {a}) => {} //? <-> @1:8 12 | (a, a, b = 0) => {} //? <-> @1:5 13 | (a, a, [b]) => {} //? <-> @1:5 14 | (a, a, {b}) => {} //? <-> @1:5 15 | a => { var a; } //? <+> 16 | a => { let a; } //? <-> @1:12 17 | (a) => { var a; } //? <+> 18 | (a) => { let a; } //? <-> @1:14 19 | ([a]) => { var a; } //? <+> 20 | ([a]) => { let a; } //? <-> @1:16 21 | ({a}) => { var a; } //? <+> 22 | ({a}) => { let a; } //? <-> @1:16 23 | (...a) => { var a; } //? <+> 24 | (...a) => { let a; } //? <-> @1:17 25 | (a = 0) => { var a; } //? <+> 26 | (a = 0) => { let a; } //? <-> @1:18 27 | ({a = 0}) => { var a; } //? <+> 28 | ({a = 0}) => { let a; } //? <-> @1:20 29 | ([{a}]) => { var a; } //? <+> 30 | ([{a}]) => { let a; } //? <-> @1:18 31 | ({a: [b]}) => { var b; } //? <+> 32 | ({a: [b]}) => { let b; } //? <-> @1:21 33 | ([a, {b = 0}]) => { var b; } //? <+> 34 | ([a, {b = 0}]) => { let b; } //? <-> @1:25 35 | 36 | //- duplicate_symbol 37 | async (a, a) => {} //? <-> @1:11 38 | async ([a, a]) => {} //? <-> @1:12 39 | async (a, a = 0) => {} //? <-> @1:11 40 | async (a, [a]) => {} //? <-> @1:12 41 | async (a, {a}) => {} //? <-> @1:12 42 | async (a, ...a) => {} //? <-> @1:14 43 | async (a = 0, a) => {} //? <-> @1:15 44 | async ([a], a) => {} //? <-> @1:13 45 | async ({a}, a) => {} //? <-> @1:13 46 | async ([a], {a}) => {} //? <-> @1:14 47 | async (a, a, b = 0) => {} //? <-> @1:11 48 | async (a, a, [b]) => {} //? <-> @1:11 49 | async (a, a, {b}) => {} //? <-> @1:11 50 | async a => { var a; } //? <+> 51 | async a => { let a; } //? <-> @1:18 52 | async (a) => { var a; } //? <+> 53 | async (a) => { let a; } //? <-> @1:20 54 | async ([a]) => { var a; } //? <+> 55 | async ([a]) => { let a; } //? <-> @1:22 56 | async ({a}) => { var a; } //? <+> 57 | async ({a}) => { let a; } //? <-> @1:22 58 | async (...a) => { var a; } //? <+> 59 | async (...a) => { let a; } //? <-> @1:23 60 | async (a = 0) => { var a; } //? <+> 61 | async (a = 0) => { let a; } //? <-> @1:24 62 | async ({a = 0}) => { var a; } //? <+> 63 | async ({a = 0}) => { let a; } //? <-> @1:26 64 | async ([{a}]) => { var a; } //? <+> 65 | async ([{a}]) => { let a; } //? <-> @1:24 66 | async ({a: [b]}) => { var b; } //? <+> 67 | async ({a: [b]}) => { let b; } //? <-> @1:27 68 | async ([a, {b = 0}]) => { var b; } //? <+> 69 | async ([a, {b = 0}]) => { let b; } //? <-> @1:31 70 | -------------------------------------------------------------------------------- /test/data/native/misc/lexical_uniqueness/declarative_statements.js: -------------------------------------------------------------------------------- 1 | /// declarative for statement 2 | /// [NOTE] let a; cannot be a for body 3 | for(var a;;) var a; //? <+> 4 | for(var a;;) let a; //? <-> 5 | for(let a;;) var a; //? <-> 6 | for(let a;;) let a; //? <-> 7 | for(var a;;) { var a; } //? <+> 8 | for(var a;;) { let a; } //? <+> 9 | for(let a;;) { var a; } //? <-> 10 | for(let a;;) { let a; } //? <+> 11 | /// 12 | for(var a;;); var a; //? <+> 13 | for(var a;;); let a; //? <-> 14 | for(let a;;); var a; //? <+> 15 | for(let a;;); let a; //? <+> 16 | for(var a;;); { var a; } //? <+> 17 | for(var a;;); { let a; } //? <+> 18 | for(let a;;); { var a; } //? <+> 19 | for(let a;;); { let a; } //? <+> 20 | { for(var a;;); } var a; //? <+> 21 | { for(var a;;); } let a; //? <-> 22 | { for(let a;;); } var a; //? <+> 23 | { for(let a;;); } let a; //? <+> 24 | 25 | /// declarative for-in statement 26 | for(var a in {}) var a; //? <+^> 27 | for(var a in {}) let a; //? <-^> 28 | for(let a in {}) var a; //? <-^> 29 | for(let a in {}) let a; //? <-^> 30 | for(var a in {}) { var a; } //? <+^> 31 | for(var a in {}) { let a; } //? <+^> 32 | for(let a in {}) { var a; } //? <-^> 33 | for(let a in {}) { let a; } //? <+^> 34 | /// 35 | for(var a in {}); var a; //? <+^> 36 | for(var a in {}); let a; //? <-^> 37 | for(let a in {}); var a; //? <+^> 38 | for(let a in {}); let a; //? <+^> 39 | for(var a in {}); { var a; } //? <+^> 40 | for(var a in {}); { let a; } //? <+^> 41 | for(let a in {}); { var a; } //? <+^> 42 | for(let a in {}); { let a; } //? <+^> 43 | { for(var a in {}); } var a; //? <+^> 44 | { for(var a in {}); } let a; //? <-^> 45 | { for(let a in {}); } var a; //? <+^> 46 | { for(let a in {}); } let a; //? <+^> 47 | 48 | /// declarative for-in statement 49 | for(var a of []) var a; //? <+^> 50 | for(var a of []) let a; //? <-^> 51 | for(let a of []) var a; //? <-^> 52 | for(let a of []) let a; //? <-^> 53 | for(var a of []) { var a; } //? <+^> 54 | for(var a of []) { let a; } //? <+^> 55 | for(let a of []) { var a; } //? <-^> 56 | for(let a of []) { let a; } //? <+^> 57 | /// 58 | for(var a of []); var a; //? <+^> 59 | for(var a of []); let a; //? <-^> 60 | for(let a of []); var a; //? <+^> 61 | for(let a of []); let a; //? <+^> 62 | for(var a of []); { var a; } //? <+^> 63 | for(var a of []); { let a; } //? <+^> 64 | for(let a of []); { var a; } //? <+^> 65 | for(let a of []); { let a; } //? <+^> 66 | { for(var a of []); } var a; //? <+^> 67 | { for(var a of []); } let a; //? <-^> 68 | { for(let a of []); } var a; //? <+^> 69 | { for(let a of []); } let a; //? <+^> 70 | 71 | /// declarative statements 72 | !async function(){ var a; for await(let a of []){} } //? <+> 73 | !async function(){ let a; for await(var a of []){} } //? <-> 74 | 75 | // declarative catch 76 | try{} catch(a){}; var a; //? <+> 77 | try{} catch(a){}; let a; //? <+> 78 | try{} catch(a){ var a; } //? <+&> 79 | try{} catch(a){ let a; } //? <-> 80 | try{} catch(a){ { let a; } } //? <+> 81 | try{} catch([a]){}; var a; //? <+> 82 | try{} catch([a]){}; let a; //? <+> 83 | try{} catch([a]){ var a; } //? <-> 84 | try{} catch([a]){ let a; } //? <-> 85 | try{} catch([a]){ { let a; } } //? <+> 86 | try{} catch([a, a]){}; //? <-> 87 | try{} catch([a, ...a]){}; //? <-> 88 | 89 | function a(){} let a; //? <-> 90 | class a{} let a; //? <-> 91 | -------------------------------------------------------------------------------- /test/data/native/misc/lexical_uniqueness/formal_parameters.js: -------------------------------------------------------------------------------- 1 | function a(b, b) {} //? <+> 2 | function a(b, b = 0) {} //? <-> 3 | function a(b, [b]) {} //? <-> 4 | function a(b, {b}) {} //? <-> 5 | function a(b, ...b) {} //? <-> 6 | function a(b = 0, b) {} //? <-> 7 | function a([b], b) {} //? <-> 8 | function a({b}, b) {} //? <-> 9 | function a(b, b, c = 0) {} //? <-> 10 | function a(b, b, [c]) {} //? <-> 11 | function a(b, b, {c}) {} //? <-> 12 | function a(b) { var b; } //? <+> 13 | function a(b) { let b; } //? <-> 14 | function a([b]) { var b; } //? <+> 15 | function a([b]) { let b; } //? <-> 16 | function a({b}) { var b; } //? <+> 17 | function a({b}) { let b; } //? <-> 18 | function a(...b) { var b; } //? <+> 19 | function a(...b) { let b; } //? <-> 20 | function a(b = 0) { var b; } //? <+> 21 | function a(b = 0) { let b; } //? <-> 22 | 23 | !function a(b, b = 0) {} //? <-> 24 | !function a(b, [b]) {} //? <-> 25 | !function a(b, {b}) {} //? <-> 26 | !function a(b, ...b) {} //? <-> 27 | !function a(b = 0, b) {} //? <-> 28 | !function a([b], b) {} //? <-> 29 | !function a({b}, b) {} //? <-> 30 | !function a(b, b, c = 0) {} //? <-> 31 | !function a(b, b, [c]) {} //? <-> 32 | !function a(b, b, {c}) {} //? <-> 33 | !function a(b) { let b; } //? <-> 34 | !function a([b]) { let b; } //? <-> 35 | !function a({b}) { let b; } //? <-> 36 | -------------------------------------------------------------------------------- /test/data/native/misc/lexical_uniqueness/function_declaration.js: -------------------------------------------------------------------------------- 1 | /// [NOTE] labeled functions are not allowed in strict mode 2 | /// function at the top level of script 3 | function a(){} var a; //? <+> 4 | function a(){} let a; //? <-> 5 | function a(){} function a(){} //? <+> 6 | function a(){} function* a(){} //? <+> 7 | function a(){} async function a(){} //? <+> 8 | function a(){} b: function a(){} //? <+&> 9 | b: function a(){} var a; //? <+&> 10 | b: function a(){} let a; //? <-&> 11 | b: function a(){} function a(){} //? <+&> 12 | b: function a(){} c: function a(){} //? <+&> 13 | 'use strict'; function a(){} var a; //? <+^> 14 | 'use strict'; function a(){} let a; //? <-^> 15 | 'use strict'; function a(){} function a(){} //? <+> 16 | 'use strict'; function a(){} b: function a(){} //? <-^> 17 | 'use strict'; function a(){} function* a(){} //? <+> 18 | 'use strict'; function a(){} async function a(){} //? <+> 19 | /// function at the top level of module 20 | function a(){} var a; //? <-#> 21 | function a(){} let a; //? <-#> 22 | function a(){} function a(){} //? <-#> 23 | function a(){} b: function a(){} //? <-#> 24 | /// function at the top level of function 25 | !function(){ function a(){} var a; } //? <+> 26 | !function(){ function a(){} let a; } //? <-> 27 | !function(){ function a(){} function a(){} } //? <+> 28 | !function(){ function a(){} function* a(){} } //? <+> 29 | !function(){ function a(){} async function a(){} } //? <+> 30 | !function(){ function a(){} b: function a(){} } //? <+> 31 | !function(){ 'use strict'; function a(){} var a; } //? <+> 32 | !function(){ 'use strict'; function a(){} let a; } //? <-> 33 | !function(){ 'use strict'; function a(){} function a(){} } //? <+> 34 | !function(){ 'use strict'; function a(){} function* a(){} } //? <+> 35 | !function(){ 'use strict'; function a(){} async function a(){} } //? <+> 36 | !function(){ 'use strict'; function a(){} b: function a(){} } //? <-^> 37 | /// annex modifications of functions in block statements 38 | { function a(){} var a; } //? <-&> 39 | { function a(){} let a; } //? <-&> 40 | { function a(){} function a(){} } //? <+&> 41 | { function a(){} function* a(){} } //? <-&> 42 | { function a(){} async function a(){} } //? <-&> 43 | { function a(){} b: function a(){} } //? <+&> 44 | 'use strict'; { var a; function a(){} } //? <-&> 45 | 'use strict'; { let a; function a(){} } //? <-&> 46 | 'use strict'; { function a(){} function a(){} } //? <-&> 47 | 'use strict'; { function a(){} function* a(){} } //? <-&> 48 | 'use strict'; { function a(){} async function a(){} } //? <-&> 49 | 'use strict'; { function a(){} b: function a(){} } //? <-^> 50 | /// annex modifications of functions in switch statements 51 | switch(0){ default: function a(){} var a; } //? <-&> 52 | switch(0){ default: function a(){} let a; } //? <-&> 53 | switch(0){ default: function a(){} function a(){} } //? <+&> 54 | switch(0){ default: function a(){} function* a(){} } //? <-&> 55 | switch(0){ default: function a(){} async function a(){} } //? <-&> 56 | switch(0){ default: function a(){} b: function a(){} }//? <+&> 57 | switch(0){ case 0: function a(){} case 1: function a(){} } //? <+&> 58 | switch(0){ case 0: function a(){} case 1: function* a(){} } //? <-&> 59 | switch(0){ case 0: function a(){} case 1: async function a(){} } //? <-&> 60 | switch(0){ case 0: function a(){} case 1: b: function a(){} } //? <+&> 61 | 'use strict'; switch(0){ default: function a(){} var a; } //? <-> 62 | 'use strict'; switch(0){ default: function a(){} let a; } //? <-> 63 | 'use strict'; switch(0){ default: function a(){} function a(){} } //? <-> 64 | 'use strict'; switch(0){ default: function a(){} function* a(){} } //? <-&> 65 | 'use strict'; switch(0){ default: function a(){} async function a(){} } //? <-&> 66 | 'use strict'; switch(0){ default: function a(){} b: function a(){} }//? <-^> 67 | 'use strict'; switch(0){ case 0: function a(){} case 1: function a(){} } //? <-> 68 | 'use strict'; switch(0){ case 0: function a(){} case 1: function* a(){} } //? <-&> 69 | 'use strict'; switch(0){ case 0: function a(){} case 1: async function a(){} } //? <-&> 70 | 'use strict'; switch(0){ case 0: function a(){} case 1: b: function a(){} } //? <-&^> 71 | -------------------------------------------------------------------------------- /test/data/native/misc/lexical_uniqueness/variable_declarations.js: -------------------------------------------------------------------------------- 1 | 'use strict'; var a; var a; //? <+> 2 | 'use strict'; for(var a, a;;); //? <+> 3 | 4 | var a, a; //? <+> 5 | let a, a; //? <-> 6 | 7 | /// duplicate bindings 8 | var a; var a; //? <+> 9 | var a; let a; //? <-> 10 | let a; var a; //? <-^> 11 | let a; let a; //? <-> 12 | /// hoisting of var bindings 13 | var a; { var a; } //? <+^> 14 | var a; { let a; } //? <+> 15 | let a; { var a; } //? <-> 16 | let a; { let a; } //? <+> 17 | { var a; } var a; //? <+^> 18 | { var a; } let a; //? <-^> 19 | { let a; } var a; //? <+^> 20 | { let a; } let a; //? <+^> 21 | 22 | /// hoisting of deeply nested var bindings 23 | let a; {{ var a; }} //? <-> 24 | {{ var a; }} let a; //? <-^> 25 | /// hoisting at all levels of nesting 26 | { let a; { var a; }} //? <-> 27 | {{ var a; } let a; } //? <-^> 28 | 29 | /// hoisting through statements 30 | let a; if(0) { var a; } //? <-> 31 | let a; if(0); else { var a; } //? <-> 32 | let a; do { var a; } while(0); //? <-> 33 | let a; while(0){ var a; } //? <-> 34 | let a; for(;;){ var a; } //? <-> 35 | let a; switch(0){ case 0: var a; } //? <-> 36 | let a; switch(0){ default: var a; } //? <-> 37 | let a; switch(0){ case 0: { var a; } } //? <-> 38 | let a; switch(0){ default: { var a; } } //? <-> 39 | let a; with({}){ var a; } //? <-> 40 | let a; b: var a; //? <-> 41 | let a; b: { var a; } //? <-> 42 | let a; try{} catch{ var a; } //? <-> 43 | let a; try{} finally{ var a; } //? <-> 44 | /// reversed 45 | if(0) { var a; } let a; //? <-^> 46 | if(0); else { var a; } let a; //? <-^> 47 | do { var a; } while(0); let a; //? <-^> 48 | while(0){ var a; } let a; //? <-^> 49 | for(;;){ var a; } let a; //? <-^> 50 | switch(0){ case 0: var a; } let a; //? <-^> 51 | switch(0){ default: var a; } let a; //? <-^> 52 | switch(0){ case 0: { var a; } } let a; //? <-^> 53 | switch(0){ default: { var a; } } let a; //? <-^> 54 | with({}){ var a; } let a; //? <-^> 55 | b: var a; let a; //? <-^> 56 | b: { var a; } let a; //? <-^> 57 | try{} catch{ var a; } let a; //? <-^> 58 | try{} finally{ var a; } let a; //? <-^> 59 | /// scoped 60 | { let a; if(0) { var a; } } //? <-^> 61 | { let a; if(0); else { var a; } } //? <-^> 62 | { let a; do { var a; } while(0); } //? <-^> 63 | { let a; while(0){ var a; } } //? <-^> 64 | { let a; for(;;){ var a; } } //? <-^> 65 | { let a; switch(0){ case 0: var a; } } //? <-^> 66 | { let a; switch(0){ default: var a; } } //? <-^> 67 | { let a; switch(0){ case 0: { var a; } } } //? <-^> 68 | { let a; switch(0){ default: { var a; } } } //? <-^> 69 | { let a; with({}){ var a; } } //? <-^> 70 | { let a; b: var a; } //? <-^> 71 | { let a; b: { var a; } } //? <-^> 72 | { let a; try{} catch{ var a; } } //? <-^> 73 | { let a; try{} finally{ var a; } } //? <-^> 74 | /// scoped-reversed 75 | { if(0) { var a; } let a; } //? <-^> 76 | { if(0); else { var a; } let a; } //? <-^> 77 | { do { var a; } while(0); let a; } //? <-^> 78 | { while(0){ var a; } let a; } //? <-^> 79 | { for(;;){ var a; } let a; } //? <-^> 80 | { switch(0){ case 0: var a; } let a; } //? <-^> 81 | { switch(0){ default: var a; } let a; } //? <-^> 82 | { switch(0){ case 0: { var a; } } let a; } //? <-^> 83 | { switch(0){ default: { var a; } } let a; } //? <-^> 84 | { with({}){ var a; } let a; } //? <-^> 85 | { b: var a; let a; } //? <-^> 86 | { b: { var a; } let a; } //? <-^> 87 | { try{} catch{ var a; } let a; } //? <-^> 88 | { try{} finally{ var a; } let a; } //? <-^> 89 | /// deeply-nested 90 | let a; { if(0) { var a; } } //? <-^> 91 | let a; { if(0); else { var a; } } //? <-^> 92 | let a; { do { var a; } while(0); } //? <-^> 93 | let a; { while(0){ var a; } } //? <-^> 94 | let a; { for(;;){ var a; } } //? <-^> 95 | let a; { switch(0){ case 0: var a; } } //? <-^> 96 | let a; { switch(0){ default: var a; } } //? <-^> 97 | let a; { switch(0){ case 0: { var a; } } } //? <-^> 98 | let a; { switch(0){ default: { var a; } } } //? <-^> 99 | let a; { with({}){ var a; } } //? <-^> 100 | let a; { b: var a; } //? <-^> 101 | let a; { b: { var a; } } //? <-^> 102 | let a; { try{} catch{ var a; } } //? <-^> 103 | let a; { try{} finally{ var a; } } //? <-^> 104 | /// deeply-nested-reversed 105 | { if(0) { var a; } } let a; //? <-^> 106 | { if(0); else { var a; } } let a; //? <-^> 107 | { do { var a; } while(0); } let a; //? <-^> 108 | { while(0){ var a; } } let a; //? <-^> 109 | { for(;;){ var a; } } let a; //? <-^> 110 | { switch(0){ case 0: var a; } } let a; //? <-^> 111 | { switch(0){ default: var a; } } let a; //? <-^> 112 | { switch(0){ case 0: { var a; } } } let a; //? <-^> 113 | { switch(0){ default: { var a; } } } let a; //? <-^> 114 | { with({}){ var a; } } let a; //? <-^> 115 | { b: var a; } let a; //? <-^> 116 | { b: { var a; } } let a; //? <-^> 117 | { try{} catch{ var a; } } let a; //? <-^> 118 | { try{} finally{ var a; } } let a; //? <-^> 119 | 120 | /// masking let 121 | let a; if(0) { let a; } //? <+^> 122 | let a; if(0); else { let a; } //? <+^> 123 | let a; do { let a; } while(0); //? <+^> 124 | let a; while(0){ let a; } //? <+^> 125 | let a; for(;;){ let a; } //? <+^> 126 | let a; switch(0){ case 0: let a; } //? <+> 127 | let a; switch(0){ default: let a; } //? <+> 128 | let a; switch(0){ case 0: { let a; } } //? <+^> 129 | let a; switch(0){ default: { let a; } } //? <+^> 130 | let a; with({}){ let a; } //? <+^> 131 | let a; b: let a; //? <-> 132 | let a; b: { let a; } //? <+^> 133 | let a; try{} catch{ let a; } //? <+^> 134 | let a; try{} finally{ let a; } //? <+^> 135 | 136 | /// switch cases 137 | switch(0){ case 0: var a; case 1: var a; } //? <+> 138 | switch(0){ case 0: var a; case 1: let a; } //? <-> 139 | switch(0){ case 0: let a; case 1: var a; } //? <-> 140 | switch(0){ case 0: let a; case 1: let a; } //? <-> 141 | switch(0){ case 0: var a; default: var a; } //? <+> 142 | switch(0){ case 0: var a; default: let a; } //? <-> 143 | switch(0){ case 0: let a; default: var a; } //? <-> 144 | switch(0){ case 0: let a; default: let a; } //? <-> 145 | 146 | /// labeled statements 147 | var a; b: var a; //? <+> 148 | var a; b: let a; //? <-> 149 | 150 | 'use strict'; function a(b, b) {} //? <-> 151 | 152 | let a; for(let a;;); //? <+> 153 | for(let a;;); let a; //? <+> 154 | var a; for(let a;;); //? <+> 155 | 156 | // VarDeclaredNames 157 | () => { var a; }; let a; //? <+> 158 | !function a(){}; let a; //? <+> 159 | !class a{}; let a; //? <+> 160 | //{ a: function b(){} } let b; //? <+> 161 | try{} catch(a){ var a; } //? <+> 162 | { let a; } let a; //? <+> 163 | //{ function a(){} } let a; //? <+> 164 | { class a {} } let a; //? <+> 165 | //function a(){} function a(){} //? <+> 166 | //let a; if(0) function a(){} //? <+> 167 | //var a; if(0) function a(){} //? <+> 168 | 169 | //let a; {function a(){}} //? <+> 170 | //{ var a; { function b(){} }} let b; //? <+> 171 | //{ let a; { let b; { function a(){} }}} //? <+> 172 | -------------------------------------------------------------------------------- /test/data/native/misc/strict_mode/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'.length; eval = 0; //? <+> 2 | 'use strict' 3 | `a`; eval = 0; //? <+> 4 | -------------------------------------------------------------------------------- /test/data/native/misc/strict_mode/invalid.js: -------------------------------------------------------------------------------- 1 | /// template 2 | !{ a(){ 'use strict'; } } //? <+> 3 | !{ set b(c){ 'use strict'; }} //? <+> 4 | !function(){ 'use strict'; } //? <+> 5 | !class{ a(){ 'use strict'; } } //? <+> 6 | () => { 'use strict'; }; //? <+> 7 | async () => { 'use strict'; }; //? <+> 8 | function a(){ 'use strict'; } //? <+> 9 | class a{ b(){ 'use strict'; } } //? <+> 10 | 11 | //- invalid_strict_mode 12 | !{ a(b = 0){ 'use strict'; } } //? <-> @1:14 13 | !{ set a(b = 0){ 'use strict'; } } //? <-> @1:18 14 | !function(a = 0){ 'use strict'; } //? <-> @1:19 15 | !class{ a(b = 0){ 'use strict'; } } //? <-> @1:19 16 | (a = 0) => { 'use strict'; }; //? <-> @1:14 17 | async (a = 0) => { 'use strict'; }; //? <-> @1:20 18 | function a(b = 0){ 'use strict'; } //? <-> @1:20 19 | class a{ b(c = 0){ 'use strict'; } } //? <-> @1:20 20 | /// 21 | !{ a([b]){ 'use strict'; } } //? <-> @1:12 22 | !{ set a([b]){ 'use strict'; } } //? <-> @1:16 23 | !function([a]){ 'use strict'; } //? <-> @1:17 24 | !class{ a([b]){ 'use strict'; } } //? <-> @1:17 25 | ([a]) => { 'use strict'; }; //? <-> @1:12 26 | async ([a]) => { 'use strict'; }; //? <-> @1:18 27 | function a([b]){ 'use strict'; } //? <-> @1:18 28 | class a{ b([c]){ 'use strict'; } } //? <-> @1:18 29 | /// 30 | !{ a({b}){ 'use strict'; } } //? <-> @1:12 31 | !{ set a({b}){ 'use strict'; } } //? <-> @1:16 32 | !function({a}){ 'use strict'; } //? <-> @1:17 33 | !class{ a({b}){ 'use strict'; } } //? <-> @1:17 34 | ({a}) => { 'use strict'; }; //? <-> @1:12 35 | async ({a}) => { 'use strict'; }; //? <-> @1:18 36 | function a({b}){ 'use strict'; } //? <-> @1:18 37 | class a{ b({c}){ 'use strict'; } } //? <-> @1:18 38 | /// 39 | !{ a(...b){ 'use strict'; } } //? <-> @1:13 40 | !{ set a(...b){ 'use strict'; } } //? <-> @1:10 -default 41 | !function(...a){ 'use strict'; } //? <-> @1:18 42 | !class{ a(...b){ 'use strict'; } } //? <-> @1:18 43 | (...a) => { 'use strict'; }; //? <-> @1:13 44 | async (...a) => { 'use strict'; }; //? <-> @1:19 45 | function a(...b){ 'use strict'; } //? <-> @1:19 46 | class a{ b(...c){ 'use strict'; } } //? <-> @1:19 47 | /// 48 | function a([eval]) { 'use strict'; } //? <-> @1:22 49 | -------------------------------------------------------------------------------- /test/data/native/misc/strict_mode/keywords/_keywords.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import url from 'url'; 3 | import path from 'path'; 4 | 5 | const file_path = url.fileURLToPath(import.meta.url); 6 | const template_path = file_path.replace(/\.js$/, '.tmpl.js'); 7 | if(template_path == file_path) { 8 | throw 'template and file paths are identical'; 9 | } 10 | const parsed = path.parse(file_path); 11 | const output_path = path.join(parsed.dir, parsed.base.replace(/^_/, '')); 12 | if(output_path == file_path) { 13 | throw 'template and file paths are identical'; 14 | } 15 | const test_dir_re = new RegExp(`${path.sep}test${path.sep}.+`); 16 | const test_dir = file_path.replace(test_dir_re, `${path.sep}test`); 17 | 18 | (async () => { 19 | const Expander = (await import(path.join(test_dir, 'expander.js'))).default; 20 | const config = { 21 | keywords: [ 22 | 'eval', 'arguments', 'yield', 'await', 23 | 'let', 'static', 'implements', 'interface', 24 | 'package', 'private', 'protected', 'public' 25 | ], 26 | errors: { 27 | eval: 'eval_args_in_strict_mode', 28 | arguments: 'eval_args_in_strict_mode', 29 | yield: 'yield_in_strict_mode', 30 | await: 'await_in_module', 31 | __default__: 'invalid_strict_mode_identifier' 32 | }, 33 | error_overrides: new Set(['await']) 34 | } 35 | let template = fs.readFileSync(template_path).toString(); 36 | let expander = new Expander(output_path, config); 37 | expander.group_expand(template); 38 | expander.write(); 39 | })(); 40 | -------------------------------------------------------------------------------- /test/data/native/misc/strict_mode/keywords/_keywords.tmpl.js: -------------------------------------------------------------------------------- 1 | 'use strict'; keyword; //? <-> @1:15 $override 2 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 3 | 'use strict'; [keyword]; //? <-> @1:16 $override 4 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 5 | 'use strict'; [...keyword]; //? <-> @1:19 $override 6 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 7 | 'use strict'; !{keyword}; //? <-> @1:17 $override 8 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 9 | 'use strict'; !{keyword: 0}; //? <+> 10 | 'use strict'; !{[keyword]: 0}; //? <-> @1:18 $override 11 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 12 | 'use strict'; !{keyword = 0}; //? <-> @1:17 $override 13 | /*{ "await": "<-> @1:17 -invalid_cover_grammar" }*/ 14 | 'use strict'; !{ keyword(){} } //? <+> 15 | 'use strict'; !{ [keyword](){} }; //? <-> @1:19 $override 16 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 17 | 'use strict'; !{ a(keyword){} } //? <-> @1:20 18 | 'use strict'; !{ a([keyword]){} } //? <-> @1:21 19 | 'use strict'; !{ a({keyword}){} } //? <-> @1:21 20 | 'use strict'; !{ a([...keyword]){} } //? <-> @1:24 21 | 'use strict'; !{ a({...keyword}){} } //? <-> @1:24 22 | 'use strict'; !{ a(...keyword){} } //? <-> @1:23 23 | 'use strict'; !{ set a(keyword){} } //? <-> @1:24 24 | 'use strict'; !{ set a([keyword]){} } //? <-> @1:25 25 | 'use strict'; !{ set a({keyword}){} } //? <-> @1:25 26 | 'use strict'; !{ set a([...keyword]){} } //? <-> @1:28 27 | 'use strict'; !{ set a({...keyword}){} } //? <-> @1:28 28 | 'use strict'; !{ set a(...keyword){} } //? <-> @1:24 -default $override 29 | /*{ "await": "<-> @1:24 -default" }*/ 30 | 'use strict'; !function keyword(){} //? <-> @1:25 31 | 'use strict'; !function a(b = keyword){} //? <-> @1:31 $override 32 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 33 | 'use strict'; !function a(keyword){} //? <-> @1:27 34 | 'use strict'; !function a([keyword]){} //? <-> @1:28 35 | 'use strict'; !function a({keyword}){} //? <-> @1:28 36 | 'use strict'; !function a([...keyword]){} //? <-> @1:31 37 | 'use strict'; !function a({...keyword}){} //? <-> @1:31 38 | 'use strict'; !function a(...keyword){} //? <-> @1:30 39 | 'use strict'; `${keyword}`; //? <-> @1:18 $override 40 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 41 | 'use strict'; a.keyword; //? <+> 42 | 'use strict'; ``.keyword; //? <+> 43 | 'use strict'; keyword++; //? <-> @1:15 44 | 'use strict'; ++keyword; //? <-> @1:17 45 | 'use strict'; keyword = 0; //? <-> @1:15 46 | 'use strict'; keyword *= 0; //? <-> @1:15 47 | 'use strict'; [keyword] = []; //? <-> @1:16 48 | 'use strict'; ({keyword} = {}); //? <-> @1:17 49 | 'use strict'; ({keyword = 0} = {}); //? <-> @1:17 50 | 'use strict'; [...keyword] = []; //? <-> @1:19 51 | 'use strict'; ({...keyword} = {}); //? <-> @1:20 52 | 'use strict'; keyword => {}; //? <-> @1:15 53 | 'use strict'; (keyword) => {}; //? <-> @1:16 54 | 'use strict'; ([keyword]) => {}; //? <-> @1:17 55 | 'use strict'; ({keyword}) => {}; //? <-> @1:17 56 | 'use strict'; ([...keyword]) => {}; //? <-> @1:20 57 | 'use strict'; ({...keyword}) => {}; //? <-> @1:20 58 | 'use strict'; (...keyword) => {}; //? <-> @1:19 59 | 'use strict'; async (keyword) => {}; //? <-> @1:22 $override 60 | /*{ "await": "<-> @1:22 -yield_await_in_arrow_params" }*/ 61 | 'use strict'; async ([keyword]) => {}; //? <-> @1:23 $override 62 | /*{ "await": "<-> @1:23 -yield_await_in_arrow_params" }*/ 63 | 'use strict'; async ({keyword}) => {}; //? <-> @1:23 $override 64 | /*{ "await": "<-> @1:23 -yield_await_in_arrow_params" }*/ 65 | 'use strict'; async ([...keyword]) => {}; //? <-> @1:26 $override 66 | /*{ "await": "<-> @1:26 -yield_await_in_arrow_params" }*/ 67 | 'use strict'; async ({...keyword}) => {}; //? <-> @1:26 $override 68 | /*{ "await": "<-> @1:26 -yield_await_in_arrow_params" }*/ 69 | 'use strict'; async (...keyword) => {}; //? <-> @1:25 $override 70 | /*{ "await": "<-> @1:25 -yield_await_in_arrow_params" }*/ 71 | 'use strict'; keyword: ; //? <-> @1:15 $override 72 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 73 | 'use strict'; var keyword; //? <-> @1:19 74 | 'use strict'; var [keyword] = []; //? <-> @1:20 75 | 'use strict'; var {keyword} = {}; //? <-> @1:20 76 | 'use strict'; var [...keyword] = []; //? <-> @1:23 77 | 'use strict'; var {...keyword}= {}; //? <-> @1:23 78 | 'use strict'; let keyword; //? <-> @1:19 $override 79 | /*{ "let": "<-> @1:19 -let_in_lexical" }*/ 80 | 'use strict'; let [keyword] = []; //? <-> @1:20 $override 81 | /*{ "let": "<-> @1:20 -let_in_lexical" }*/ 82 | 'use strict'; let {keyword} = {}; //? <-> @1:20 $override 83 | /*{ "let": "<-> @1:20 -let_in_lexical" }*/ 84 | 'use strict'; let [...keyword] = []; //? <-> @1:23 $override 85 | /*{ "let": "<-> @1:23 -let_in_lexical" }*/ 86 | 'use strict'; let {...keyword} = {}; //? <-> @1:23 $override 87 | /*{ "let": "<-> @1:23 -let_in_lexical" }*/ 88 | 'use strict'; const keyword = 0; //? <-> @1:21 $override 89 | /*{ "let": "<-> @1:21 -let_in_lexical" }*/ 90 | 'use strict'; const [keyword] = 0; //? <-> @1:22 $override 91 | /*{ "let": "<-> @1:22 -let_in_lexical" }*/ 92 | 'use strict'; const {keyword} = 0; //? <-> @1:22 $override 93 | /*{ "let": "<-> @1:22 -let_in_lexical" }*/ 94 | 'use strict'; const [...keyword] = 0; //? <-> @1:25 $override 95 | /*{ "let": "<-> @1:25 -let_in_lexical" }*/ 96 | 'use strict'; const {...keyword} = 0; //? <-> @1:25 $override 97 | /*{ "let": "<-> @1:25 -let_in_lexical" }*/ 98 | 'use strict'; function keyword(){} //? <-> @1:24 99 | 'use strict'; function a(keyword){} //? <-> @1:26 100 | 'use strict'; function a(b = keyword){} //? <-> @1:30 $override 101 | /*{ "eval": "<+>", "arguments": "<+>" }*/ 102 | 'use strict'; function a([keyword]){} //? <-> @1:27 103 | 'use strict'; function a({keyword}){} //? <-> @1:27 104 | 'use strict'; function a([...keyword]){} //? <-> @1:30 105 | 'use strict'; function a({...keyword}){} //? <-> @1:30 106 | 'use strict'; function a(...keyword){} //? <-> @1:29 107 | /// 108 | function keyword(){ 'use strict'; } //? <-> @1:10 109 | function a(keyword){ 'use strict'; } //? <-> @1:12 110 | function a(b, keyword){ 'use strict'; } //? <-> @1:15 111 | !function keyword(){ 'use strict'; } //? <-> @1:11 112 | !function a(keyword){ 'use strict'; } //? <-> @1:13 113 | !{ keyword(){ 'use strict'; } } //? <+> 114 | !{ a(keyword){ 'use strict'; } } //? <-> @1:6 115 | !{ set a(keyword){ 'use strict'; } } //? <-> @1:10 116 | keyword => { 'use strict'; }; //? <-> @1:1 117 | (keyword) => { 'use strict'; }; //? <-> @1:2 118 | async (keyword) => { 'use strict'; }; //? <-> @1:8 $override 119 | /*{ "await": "<-> @1:8 -yield_await_in_arrow_params" }*/ 120 | -------------------------------------------------------------------------------- /test/data/native/misc/strict_mode/literals.js: -------------------------------------------------------------------------------- 1 | !class { 001(){} }; //? <-> @1:10 2 | 'use strict'; '\0'; //? <+> 3 | //- annex_numeral 4 | 'use strict'; 001; //? <-> @1:15 5 | 'use strict'; 08; //? <-> @1:15 6 | 'use strict'; 09; //? <-> @1:15 7 | 'use strict'; 018; //? <-> @1:15 8 | 'use strict'; !{ 001(){} }; //? <-> @1:18 9 | 'use strict'; !{ 08(){} }; //? <-> @1:18 10 | 'use strict'; !{ 09(){} }; //? <-> @1:18 11 | !class { 001(){} }; //? <-> @1:10 12 | !class { 08(){} }; //? <-> @1:10 13 | !class { 09(){} }; //? <-> @1:10 14 | /// look back strict mode is not imposed on property names 15 | !{ 001(){ 'use strict'; } }; //? <+> 16 | !{ 08(){ 'use strict'; } }; //? <+> 17 | !{ 09(){ 'use strict'; } }; //? <+> 18 | -------------------------------------------------------------------------------- /test/data/native/statements/directive.js: -------------------------------------------------------------------------------- 1 | 'a'; //? <+> 2 | 'a'; 'b'; //? <+> 3 | 'a'; ; 'b'; //? <+> 4 | ''; 'a'; 1; 'b'; //? <+> 5 | 6 | function a() { 'a'; } //? <+> 7 | function a() { 'a' } //? <+> 8 | function a() { 'a' 9 | } //? <+> 10 | function a() { 'a'; 'b'; } //? <+> 11 | function a() { 'a'; 'b' } //? <+> 12 | function a() { 'a' 13 | 'b'; } //? <+> 14 | function a() { 'a' 15 | 'b' } //? <+> 16 | function a() { 'a' 17 | 'b' 18 | } //? <+> 19 | function a() { 'a'; 'b'; 1; } //? <+> 20 | function a() { 'a'; 1; 'b'; } //? <+> 21 | function a() { 1; 'a'; 'b'; } //? <+> 22 | function a() { 'a' 23 | + 'b'; 'c'; } //? <+> 24 | 25 | function a() { class b {} 'a' } //? <+> 26 | -------------------------------------------------------------------------------- /test/data/native/statements/for.js: -------------------------------------------------------------------------------- 1 | for(;;); //? <+> 2 | for(;;){} //? <+> 3 | for(1;;); //? <+> 4 | for(;2;); //? <+> 5 | for(;;3); //? <+> 6 | for(1;2;); //? <+> 7 | for(;2;3); //? <+> 8 | for(1;;3); //? <+> 9 | for(1;2;3); //? <+> 10 | 11 | for(a;;); //? <+> 12 | for(var a;;); //? <+> 13 | for(let a;;); //? <+> 14 | for(const a;;); //? <-> @1:12 -missing_const_initializer 15 | for(a = 0;;); //? <+> 16 | for(var a = 0;;); //? <+> 17 | for(let a = 0;;); //? <+> 18 | for(const a = 0;;); //? <+> 19 | 20 | for(var [a] = [];;); //? <+> 21 | for(let [a] = [];;); //? <+> 22 | for(const [a] = [];;); //? <+> 23 | for(l\u0065t[a];;); //? <+> 24 | 25 | for(; a in {};); //? <+> 26 | for(;; a in {}); //? <+> 27 | for(var a = (b in {});;); //? <+> 28 | for(var a = [b in {}];;); //? <+> 29 | for(var [a] = [b in {}];;); //? <+> 30 | for(var [a = b in {}] = [1];;); //? <+> 31 | 32 | for(b in {}); //? <+> 33 | for(var b in {}); //? <+> 34 | for(let b in {}); //? <+> 35 | for(const b in {}); //? <+> 36 | 37 | for(var [a] in {}); //? <+> 38 | for(let [a] in {}); //? <+> 39 | for(const [a] in {}); //? <+> 40 | 41 | for(c of []); //? <+> 42 | for(var c of []); //? <+> 43 | for(let c of []); //? <+> 44 | for(const c of []); //? <+> 45 | 46 | for(var [a] of []); //? <+> 47 | for(let [a] of []); //? <+> 48 | for(const [a] of []); //? <+> 49 | 50 | !async function(){ for await(a of []); } //? <+> 51 | !async function(){ for await(var a of []); } //? <+> 52 | !async function(){ for await(let a of []); } //? <+> 53 | !async function(){ for await(const a of []); } //? <+> 54 | !async function(){ for await(let [a, b = [c = 3], d] of {}); } //? <+> 55 | !async function(){ for await(let {a, b: [c = 3], d} of {}); } //? <+> 56 | 57 | /// let as keyword or identifier? 58 | for(let.a;;); //? <+> 59 | for(let/a;;); //? <+> 60 | for(let in;;); //? <-> @1:11 61 | for(let of;;); //? <+> 62 | for(let[a];;); //? <-> @1:11 63 | /// 64 | for(let in {}); //? <+> 65 | for(let.a in {}); //? <+> 66 | for(let() in {}); //? <-> @1:5 -invalid_for_assignment 67 | for(let().a in {}); //? <+> 68 | for(let[0] in {}); //? <-> @1:9 69 | for(let[a] in {}); //? <+> 70 | //- for_of_begins_with_let 71 | for(let of []); //? <-> @1:12 -expect ; 72 | for(let.a of []); //? <-> @1:5 73 | for(let() of []); //? <-> @1:5 74 | for(let().a of []); //? <-> @1:5 75 | for(let[0] of []); //? <-> @1:9 -default 76 | for(let[a] of []); //? <+> 77 | 78 | /// invalid initialization 79 | //- initializer_in_for 80 | for(var a = 1 in []); //? <+&> 81 | 'use strict'; for(var a = 1 in {}); //? <-> @1:27 82 | for(let a = 1 in {}); //? <-> @1:13 83 | for(const a = 1 in {}); //? <-> @1:15 84 | for(var [a, b] = [1, 2] in []); //? <-> @1:25 -expect ; 85 | for(let [a, b] = [1, 2] in []); //? <-> @1:25 -expect ; 86 | for(var a, b in {}); //? <-> @1:14 -expect ; 87 | for(let a, b in {}); //? <-> @1:14 -expect ; 88 | for(const a = 1, b = 2 in {}); //? <-> @1:24 -expect ; 89 | for(a + b in {}); //? <-> @1:11 -expect ; 90 | for(a + b of []); //? <-> @1:11 -expect ; 91 | for(let [a.b] in {}); //? <-> @1:11 -default 92 | for(a = 1 in {}); //? <-> @1:11 -expect ; 93 | 94 | for(a, b = 2, [c] = [3], {d} = {d: 4};;); //? <+> 95 | for([a, b = [c = 3], d];;); //? <+> 96 | 97 | for(let [a, b = [c = 3], d] in {}); //? <+> 98 | for(let [a, b = [c = 3], d] of []); //? <+> 99 | for(let {a, b: [c = 3], d} in {}); //? <+> 100 | for(let {a, b: [c = 3], d} of {}); //? <+> 101 | 102 | /// exclude "in" keyword in initialize expression 103 | //- default 104 | for(a in {};;); //? <-> @1:12 105 | for(a = x in {};;); //? <-&> @1:11 -expect ; 106 | for(a=>a in b;;); //? <-> @1:10 -expect ; 107 | for(var a = x in {};;); //? <-&> @1:20 -default 108 | for(let a = x in {};;); //? <-> @1:13 -initializer_in_for 109 | for(const a = x in {};;); //? <-> @1:15 -initializer_in_for 110 | for(var [a];;); //? <-> @1:12 -missing_binding_initializer 111 | for(let [a];;); //? <-> @1:12 -missing_binding_initializer 112 | for(const [a];;); //? <-> @1:14 -missing_binding_initializer 113 | for(var [a] = x in {};;); //? <-> @1:17 -expect ; 114 | for(let [a] = x in {};;); //? <-> @1:17 -expect ; 115 | for(const [a] = x in {};;); //? <-> @1:19 -expect ; 116 | 117 | /// incomplete for statements 118 | //- default 119 | for(;) //? <-> @1:6 120 | for(;0) //? <-> @1:7 121 | for(;;) //? <-> @1:9 122 | for(a in) //? <-> @1:9 123 | for(a of) //? <-> @1:9 124 | for(a in {}) //? <-> @1:14 125 | for(a of []) //? <-> @1:14 126 | //- unexpected_for_await 127 | for await(;;); //? <-> @1:5 128 | for await(a in {}); //? <-> @1:5 129 | for await(a of []); //? <-> @1:5 130 | /// 131 | !async function(){ for await(;;); }; //? <-> @1:30 -default 132 | !async function(){ for await(a in {}); }; //? <-> @1:32 -expecting_of 133 | 134 | //- let_in_lexical 135 | for(let let;;); //? <-> @1:9 136 | for(let let = 0;;); //? <-> @1:9 137 | for(let let in {}); //? <-> @1:9 138 | for(let let of []); //? <-> @1:9 139 | for(let [let] in {}); //? <-> @1:10 140 | for(let {let} of []); //? <-> @1:10 141 | for(let [...let] in {}); //? <-> @1:13 142 | for(let {...let} of []); //? <-> @1:13 143 | /// 144 | for(const let;;); //? <-> @1:11 145 | for(const let = 0;;); //? <-> @1:11 146 | for(const let in {}); //? <-> @1:11 147 | for(const let of []); //? <-> @1:11 148 | for(const [let] in {}); //? <-> @1:12 149 | for(const {let} of []); //? <-> @1:12 150 | for(const [...let] in {}); //? <-> @1:15 151 | for(const {...let} of []); //? <-> @1:15 152 | -------------------------------------------------------------------------------- /test/data/native/statements/if.js: -------------------------------------------------------------------------------- 1 | if(0) if(0); else; //? <+> 2 | if(true) function a(){} //? <+> 3 | if(false); else function a(){} //? <+> 4 | if(true) function a(){ function* b(){} } //? <+> 5 | 6 | //- default 7 | 'use strict'; if(true) function a(){} //? <-> @1:24 8 | 'use strict'; if(true); else function a(){} //? <-> @1:30 9 | -------------------------------------------------------------------------------- /test/data/native/statements/jump.js: -------------------------------------------------------------------------------- 1 | break; //? <-> @1:1 -unsyntatic_break 2 | continue; //? <-> @1:1 -unsyntatic_continue 3 | return; //? <-> @1:1 -unsyntatic_return 4 | 5 | /// individual for, switch, function 6 | for(;;) break; //? <+> 7 | for(;;) continue; //? <+> 8 | for(;;) return; //? <-> @1:9 -unsyntatic_return 9 | for(;;) { break; } //? <+> 10 | for(;;) { continue; } //? <+> 11 | for(;;) { return; } //? <-> @1:11 -unsyntatic_return 12 | switch(a) { case 0: break; } //? <+> 13 | switch(a) { case 0: continue; } //? <-> @1:21 -unsyntatic_continue 14 | switch(a) { case 0: return; } //? <-> @1:21 -unsyntatic_return 15 | switch(a) { default: break; } //? <+> 16 | switch(a) { case 0: { break; } } //? <+> 17 | switch(a) { default: { break; } } //? <+> 18 | switch(a) { case 0: function a() { break; } } //? <-> @1:36 -unsyntatic_break 19 | function a() { break; } //? <-> @1:16 -unsyntatic_break 20 | function a() { continue; } //? <-> @1:16 -unsyntatic_continue 21 | function a() { return; } //? <+> 22 | 23 | /// for-switch 24 | for(;;) switch(a) { case 0: continue; } //? <+> 25 | for(;;) switch(a) { default: continue; } //? <+> 26 | for(;;) switch(a) { case 0: { continue; } } //? <+> 27 | for(;;) switch(a) { default: { continue; } } //? <+> 28 | for(;;) { switch(a) { case 0: continue; } } //? <+> 29 | for(;;) { switch(a) { default: continue; } } //? <+> 30 | for(;;) { switch(a) { case 0: { continue; } } } //? <+> 31 | for(;;) { switch(a) { default: { continue; } } } //? <+> 32 | for(;;) { function a() { break; } } //? <-> @1:26 -unsyntatic_break 33 | for(;;) { function a() { continue; } } //? <-> @1:26 -unsyntatic_continue 34 | for(;;) { function a() {} return; } //? <-> @1:27 -unsyntatic_return 35 | 36 | /// function-for, function-switch 37 | function a() { for(;;) return; } //? <+> 38 | function a() { for(;;) { return; } } //? <+> 39 | function a() { switch(a) { case 0: return; } } //? <+> 40 | function a() { switch(a) { default: return; } } //? <+> 41 | function a() { switch(a) { case 0: { return; } } } //? <+> 42 | function a() { switch(a) { default: { return; } } } //? <+> 43 | 44 | /// function-for-switch 45 | function a() { for(;;) switch(a) { case 0: return; } } //? <+> 46 | function a() { for(;;) switch(a) { default: return; } } //? <+> 47 | function a() { for(;;) switch(a) { case 0: { return; } } } //? <+> 48 | function a() { for(;;) switch(a) { default: { return; } } } //? <+> 49 | function a() { for(;;) { switch(a) { case 0: return; } } } //? <+> 50 | function a() { for(;;) { switch(a) { default: return; } } } //? <+> 51 | function a() { for(;;) { switch(a) { case 0: { return; } } } } //? <+> 52 | function a() { for(;;) { switch(a) { default: { return; } } } } //? <+> 53 | -------------------------------------------------------------------------------- /test/data/native/statements/labeled.js: -------------------------------------------------------------------------------- 1 | a: break a; //? <+> 2 | a: if(0) break a; //? <+> 3 | a: if(0); else break a; //? <+> 4 | a: for(;;) break a; //? <+> 5 | a: for(;;) continue a; //? <+> 6 | //- undefined_label 7 | a: function b(){ for(;;) break a; } //? <-> @1:32 8 | a: function b(){ for(;;) continue a; } //? <-> @1:35 9 | a: !function b(){ for(;;) break a; } //? <-> @1:33 10 | a: !function b(){ for(;;) continue a; } //? <-> @1:36 11 | 12 | a: { break a; } //? <+> 13 | a: { if(0) break a; } //? <+> 14 | a: { for(;;) break a; } //? <+> 15 | /// acorn fails a: { for(;;) continue a; } //? <+> 16 | 17 | a: { { break a; } } //? <+> 18 | a: { { if(0) break a; } } //? <+> 19 | a: { { for(;;) break a; } } //? <+> 20 | /// acorn fails a: { { for(;;) continue a; } } //? <+> 21 | 22 | a: continue a; //? <-> @1:4 -unsyntatic_continue 23 | a: break b; //? <-> @1:10 -undefined_label 24 | 25 | a: b: break a; //? <+> 26 | a: b: if(0) break a; //? <+> 27 | a: b: if(0); else break a; //? <+> 28 | a: b: for(;;) break a; //? <+> 29 | a: b: for(;;) continue a; //? <+> 30 | 31 | //- duplicate_label 32 | a: a:; //? <-> @1:4 33 | a: { a:; } //? <-> @1:6 34 | a: b: a:; //? <-> @1:7 35 | a: { b: { a:; } } //? <-> @1:11 36 | a: function b(){ a:; } //? <+> 37 | a: !function b(){ a:; } //? <+> 38 | a: !{b(){ a:; }} //? <+> 39 | a:; a:; //? <+> 40 | a: { b:; b:; } //? <+> 41 | //- undefined_label 42 | a: { b:; { break b; } break a; } //? <-> @1:18 43 | a: { b: { break b; } break a; } //? <+> 44 | a: { !function(){ b:; }; break a; } //? <+> 45 | a: { b:; { !function(){ c:; } } { break b; } break a; } //? <-> @1:41 46 | a: { b: { !function(){ c:; }; break b; } break a; } //? <+> 47 | 48 | //- default 49 | a: function b(){} //? <+&> 50 | a: function* b(){} //? <-&> @1:12 51 | a: async function b(){} //? <-> @1:4 52 | a: async function* b(){} //? <-> @1:4 53 | a: b: function c(){} //? <+&> 54 | if(0) a: function b(){} //? <-> @1:10 55 | if(0) a: b: function c(){} //? <-> @1:13 56 | if(0); else a: function b(){} //? <-> @1:16 57 | if(0); else a: b: function c(){} //? <-> @1:19 58 | if(0) { a: function b(){} } //? <+> 59 | if(0); else { a: function b(){} } //? <+> 60 | with(0) a: function b(){} //? <-> @1:12 61 | with(0) a: b: function c(){} //? <-> @1:15 62 | with(0) { a: function b(){} } //? <+> 63 | do a: function b(){} while(0); //? <-> @1:7 64 | do a: b: function c(){} while(0); //? <-> @1:10 65 | do { a: function b(){} } while(0); //? <+> 66 | while(0) a: function b(){} //? <-> @1:13 67 | while(0) a: b: function b(){} //? <-> @1:16 68 | while(0) { a: function b(){} } //? <+> 69 | for(;;) a: function b(){} //? <-> @1:12 70 | for(;;) a: b: function b(){} //? <-> @1:15 71 | for(;;) { a: function b(){} } //? <+> 72 | for(a in {}) b: function c(){} //? <-> @1:17 73 | for(a of []) b: function c(){} //? <-> @1:17 74 | 75 | 'use strict'; a: function b(){} //? <-> @1:18 76 | a: function b(){} //? <-#> @1:4 77 | 78 | !async function() { for await(a of []) b: function c(){} } //? <-> @1:43 79 | -------------------------------------------------------------------------------- /test/data/native/statements/switch.js: -------------------------------------------------------------------------------- 1 | switch(a) {} //? <+> 2 | switch(a) { case 0: } //? <+> 3 | switch(a) { default: } //? <+> 4 | switch(a) { case 0: default: } //? <+> 5 | switch(a) { default: case 0: } //? <+> 6 | switch(a) 7 | { 8 | case 0: {} 9 | case 1: a; 10 | case 2: b; break; 11 | default: break; 12 | } //? <+> 13 | switch(a) { default: default: } //? <-> @1:22 -duplicate_default_clause 14 | -------------------------------------------------------------------------------- /test/data/native/statements/try.js: -------------------------------------------------------------------------------- 1 | try {} catch({x}) {} //? <+> 2 | try {} //? <-> @1:8 -default 3 | -------------------------------------------------------------------------------- /test/data/native/statements/with.js: -------------------------------------------------------------------------------- 1 | 'use strict'; with(1); //? <-> @1:15 -with_in_strict_mode 2 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/.gitattributes: -------------------------------------------------------------------------------- 1 | * -text 2 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/comment.js: -------------------------------------------------------------------------------- 1 | // //? <+> 2 | // abc //? <+> 3 | // abc 4 | //? <+> 5 | /**/ //? <+> 6 | /***/ //? <+> 7 | /* 8 | */ //? <+> 9 | /* */ //? <+> 10 | /* 11 | */ //? <+> 12 | /*
*/ //? <+> 13 | /*
*/ //? <+> 14 | /** 15 | **/ //? <+> 16 | //? <+> 18 | --> //? <+> 19 | /**/--> //? <+> 20 | /**/ --> //? <+> 21 | // 22 | 23 | --> //? <+> 24 | a --> //? <-> 25 | /**/ 26 | --> //? <+> 27 | /* 28 | */--> //? <+> 29 | /* 30 | */ --> //? <+> 31 | /* 32 | */ /**/ --> //? <+> 33 | /**/ 34 | /**/ --> //? <+> 35 | // 36 | 37 | /**/ --> //? <+> 38 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/context.js: -------------------------------------------------------------------------------- 1 | ++/a/.b; //? <+> 2 | 3 | !{} / 1; //? <+> 4 | !function(){} / 1; //? <+> 5 | !class{} / 1; //? <+> 6 | typeof async function a(){} / b; //? <+a> 7 | typeof async function a(){} /./; //? <-> @1:30 8 | function a(){} /./; //? <+> 9 | class a {} /./; //? <+> 10 | () => {} / 1; //? <-> @1:10 -unterminated_regexp 11 | () => {} 12 | /./; //? <+> 13 | 14 | a.in / 1; //? <+> 15 | 16 | await / 1; //? <+> 17 | yield / 1; //? <+> 18 | let / 1; //? <+> 19 | of / 1; //? <+> 20 | 21 | !function*(){ yield /./; } //? <+> 22 | !async function(){ await /./; } //? <+> 23 | ///!async function(){ await /a*/; } //? <+> 24 | for(of of []); //? <+> 25 | for(of of /./); //? <+> 26 | 27 | if(0) /./; //? <+> 28 | for(;;) /./; //? <+> 29 | while(0) /./; //? <+> 30 | 31 | /// test parenthesis stack exhaustion 32 | if(0) /./; (0) /./; //? <-> @1:17 33 | for(;;) /./; (0) /./; //? <-> @1:19 34 | while(0) /./; (0) /./; //? <-> @1:20 35 | 36 | if((0)) /./; //? <+> 37 | for((0);;) /./; //? <+> 38 | while((0)) /./; //? <+> 39 | 40 | /// test parenthesis stack push and pop 41 | if(!function(){ if(0) /./; }) /./; //? <+> 42 | for(!function(){ if(0) /./; };;) /./; //? <+> 43 | while(!function(){ if(0) /./; }) /./; //? <+> 44 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/identifier.js: -------------------------------------------------------------------------------- 1 | /// code points are choosen to cover all possible coding scenarios in UTF8 2 | a, À, ἀ, 𝛃; //? <+> 3 | aa, aÀ, aἀ, a𝛃; //? <+> 4 | Àa, ÀÀ, Àἀ, À𝛃; //? <+> 5 | ἀa, ἀÀ, ἀἀ, ἀ𝛃; //? <+> 6 | 𝛃a, 𝛃À, 𝛃ἀ, 𝛃𝛃; //? <+> 7 | a‌, À‌, ἀ‌, 𝛃‌; // invisible ZWJ as IdentifierPart //? <+> 8 | a‍, À‍, ἀ‍, 𝛃‍; // invisible ZWNJ as IdentifierPart //? <+> 9 | aÀἀ𝛃‌‍aÀἀ𝛃‌‍; //? <+> 10 | 11 | 𞸊, 𞸋, 𞸊𞸋; // surrogates (only valid as characters, not escape sequences) //? <+> 12 | 13 | //- surrogate_in_identifier 14 | \ud835; //? <-> @1:1 15 | \udec3; //? <-> @1:1 16 | \ud835\udec3; //? <-> @1:1 17 | \u0061\ud835\udec3; //? <-> @1:7 18 | \ud835\udec3\u00c0; //? <-> @1:1 19 | 20 | /// unicode escaped versions of above tests 21 | \u0061, \u00c0, \u1f00, \u{1d6c3}; //? <+> 22 | \u0061\u0061, \u0061\u00c0, \u0061\u1f00, \u0061\u{1d6c3}; //? <+> 23 | \u00c0\u0061, \u00c0\u00c0, \u00c0\u1f00, \u00c0\u{1d6c3}; //? <+> 24 | \u1f00\u0061, \u1f00\u00c0, \u1f00\u1f00, \u1f00\u{1d6c3}; //? <+> 25 | \u{1d6c3}\u0061, \u{1d6c3}\u00c0, \u{1d6c3}\u1f00, \u{1d6c3}\u{1d6c3}; //? <+> 26 | \u0061\u200c, \u00c0\u200c, \u1f00\u200c, \u{1d6c3}\u200c; //? <+> 27 | \u0061\u200d, \u00c0\u200d, \u1f00\u200d, \u{1d6c3}\u200d; //? <+> 28 | \u0061\u00c0\u1f00\u{1d6c3}\u200c\u200d\u0061\u00c0\u1f00\u{1d6c3}\u200c\u200d; //? <+> 29 | 30 |  a
  À
  ἀ
  𝛃
 //? <+> 31 |  a
 À
 ἀ
 𝛃
 //? <+> 32 | 33 | 
 //? <+> 34 |   //? <+> 35 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/location.js: -------------------------------------------------------------------------------- 1 | ///( /* */ 1, 2 /* */ ); //? <+a> 2 | // € 3 | ; //? <+> 4 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/newline.js: -------------------------------------------------------------------------------- 1 | //# {"preserve_newlines": "true"} 2 | 3 | // \n //? <+> 4 | // \r //? <+> 5 | 
 // line separator //? <+> 6 | 
 // paragraph separator //? <+> 7 | 8 | 9 | // \n\n //? <+> 10 | 11 | // \n\r //? <+> 12 | 13 | 
 // \n //? <+> 14 | 15 | 
 // \n //? <+> 16 | // \r\r //? <+> 17 | 18 | // \r\n //? <+> 19 | 
 // \r //? <+> 20 | 
 // \r //? <+> 21 | 
 // \r //? <+> 22 | 
 23 | // \n //? <+> 24 | 

 // //? <+> 25 | 

 // //? <+> 26 | 
 // \r //? <+> 27 | 
 28 | // \n //? <+> 29 | 

 // //? <+> 30 | 

 // //? <+> 31 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/regexp.js: -------------------------------------------------------------------------------- 1 | /a/gimsuy; //? <+> 2 | /a/gg; //? <-> 3 | -------------------------------------------------------------------------------- /test/data/native/tokenizer/whitespace.js: -------------------------------------------------------------------------------- 1 | /*space*/ //? <+> 2 | /*tab*/ //? <+> 3 | /**/ //? <+> 4 | /**/ //? <+> 5 | /**/ //? <+> 6 | /**/ //? <+> 7 |  /*-0x1680*/ //? <+> 8 |  /*-0x202F*/ //? <+> 9 |  /*-0x205F*/ //? <+> 10 |  /*-0x3000*/ //? <+> 11 |            /*-0x2000-0x200A*/ //? <+> 12 |  /*mixed*/ //? <+> 13 |   /*mixed*/ //? <+> 14 | -------------------------------------------------------------------------------- /test/data/test262/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /test/debug/main.js: -------------------------------------------------------------------------------- 1 | /* globals process global */ 2 | 3 | const electron = require('electron'); 4 | const {app, ipcMain, BrowserWindow} = electron; 5 | 6 | //app.commandLine.appendSwitch('enable-features', 'experimental-wasm-simd'); 7 | app.commandLine.appendSwitch('experimental-wasm-simd'); 8 | 9 | // Keep a global reference of the window object, if you don't, the window will 10 | // be closed automatically when the JavaScript object is garbage collected. 11 | let win; 12 | 13 | function createWindow () { 14 | win = {}; 15 | 16 | // Create the browser window. 17 | //const {width, height} = electron.screen.getPrimaryDisplay().workAreaSize; 18 | //win = new BrowserWindow({width: width, height: height}); 19 | ///* 20 | win = new BrowserWindow({ 21 | webPreferences: { 22 | nodeIntegration: true, 23 | //sandbox: false, 24 | //allowRunningInsecureContent: true, 25 | //webSecurity: false, 26 | //contextIsolation: false 27 | } 28 | }); 29 | //*/ 30 | //win = new BrowserWindow(); 31 | win.maximize(); 32 | 33 | // and load the index.html of the app. 34 | win.loadURL(`file://${__dirname}/parser.html`); 35 | //win.loadURL(`file://${__dirname}/../blis-0.6.1/test.html`); 36 | 37 | // Open the DevTools. 38 | win.webContents.openDevTools(); 39 | 40 | // Emitted when the window is closed. 41 | win.on('closed', () => { 42 | // Dereference the window object, usually you would store windows 43 | // in an array if your app supports multi windows, this is the time 44 | // when you should delete the corresponding element. 45 | win = null; 46 | }); 47 | } 48 | 49 | // This method will be called when Electron has finished 50 | // initialization and is ready to create browser windows. 51 | // Some APIs can only be used after this event occurs. 52 | app.on('ready', createWindow); 53 | 54 | // Quit when all windows are closed. 55 | app.on('window-all-closed', () => { 56 | // On macOS it is common for applications and their menu bar 57 | // to stay active until the user quits explicitly with Cmd + Q 58 | if(process.platform !== 'darwin') { 59 | app.quit(); 60 | } 61 | }); 62 | 63 | app.on('activate', () => { 64 | // On macOS it's common to re-create a window in the app when the 65 | // dock icon is clicked and there are no other windows open. 66 | if (win === null) { 67 | createWindow(); 68 | } 69 | }); 70 | 71 | // In this file you can include the rest of your app's specific main process 72 | // code. You can also put them in separate files and require them here. 73 | -------------------------------------------------------------------------------- /test/debug/parser.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 19 | 20 | -------------------------------------------------------------------------------- /test/expander.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export default class Expander { 5 | constructor(output_path, config) { 6 | this.test = ''; 7 | this.config = config; 8 | this.output_path = output_path; 9 | } 10 | expand(template, error, overrides, config) { 11 | template = template.trim(); 12 | overrides = overrides || {}; 13 | config = config || this.config; 14 | let expanded = (error ? `//- ${error}\r\n` : '///\r\n'); 15 | for(const keyword of config.keywords) { 16 | let _test = template.replace(/keyword/g, keyword); 17 | const override = overrides[keyword]; 18 | if(override) _test = _test.replace(/\/\/\? .+$/, override); 19 | expanded += _test + '\r\n'; 20 | } 21 | expanded += '\r\n'; 22 | this.test += expanded; 23 | } 24 | group_expand(template, errors, config) { 25 | template = template.trim(); 26 | config = config || this.config; 27 | errors = errors || this.config.errors; 28 | for(const keyword of config.keywords) { 29 | const error = errors[keyword] || errors.__default__ || 'default'; 30 | this.test += `//- ${error}\r\n`; 31 | let replaced = template.replace(/keyword/g, keyword); 32 | let override_error = config.error_overrides.has(keyword); 33 | if(override_error) { 34 | // convert non-overrided tests to positive tests 35 | replaced = replaced.replace(/\/\/\? <+->[^\r\n$]*(?=[\r\n]|$)/g, '//? <+>'); 36 | } 37 | replaced = replaced.replace( 38 | /(<[+-]>.*) \$override[\r\n]+\/\*([^*]+)\*\//g, 39 | (pattern, match1, match2) => { 40 | const overrides = JSON.parse(match2); 41 | const override = overrides[keyword]; 42 | const skip = overrides['skip-error-override']; 43 | return override || (override_error && !skip ? '<+>' : match1); 44 | } 45 | ) 46 | this.test += replaced + '\r\n\r\n'; 47 | } 48 | } 49 | write() { 50 | fs.writeFileSync(this.output_path, this.test); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /test/object_diff.js: -------------------------------------------------------------------------------- 1 | /* globals module window */ 2 | export function object_diff(actual, expected) { 3 | var default_diff = {left: actual, right: expected}; 4 | if(typeof actual != typeof expected) return default_diff; 5 | switch(typeof actual) { 6 | case 'undefined': return null; 7 | case 'object': break; 8 | case 'symbol': case 'function': return default_diff; // unsupported 9 | default: return actual === expected ? null : default_diff; 10 | } 11 | if(actual === null || expected === null) { 12 | return (actual !== expected ? default_diff : null); 13 | } 14 | var proto_of = Object.getPrototypeOf; 15 | if(proto_of(actual) !== proto_of(expected)) return default_diff; 16 | if(typeof ArrayBuffer != 'undefined' && proto_of(actual) == ArrayBuffer.prototype){ 17 | actual = new Uint8Array(actual); 18 | expected = new Uint8Array(expected); 19 | } 20 | switch(proto_of(actual)) { 21 | case Number.prototype: 22 | return actual === expected ? null : default_diff; 23 | case Date.prototype: 24 | return actual.valueOf() == expected.valueOf() ? null : default_diff; 25 | case RegExp.prototype: 26 | return actual.source === expected.source && 27 | actual.flags === expected.flags ? null: default_diff; 28 | case Object.prototype: { 29 | var left_keys = Object.keys(actual).sort().reverse(); 30 | var right_keys = Object.keys(expected).sort().reverse(); 31 | var left = {}, right = {}, has_diff = false; 32 | for(var li = 0, ri = 0; li < left_keys.length || ri < right_keys.length;) { 33 | var lkey = (li < left_keys.length ? left_keys[li] : ''); 34 | var rkey = (ri < right_keys.length ? right_keys[ri] : ''); 35 | if(lkey == rkey) { 36 | ++li, ++ri; 37 | var d = object_diff(actual[lkey], expected[rkey]); 38 | if(d === null) continue; 39 | left[lkey] = d.left, right[rkey] = d.right; 40 | has_diff = true; 41 | } else if(lkey > rkey) { 42 | ++li, left[lkey] = actual[lkey]; 43 | has_diff = true; 44 | } else { 45 | ++ri, right[rkey] = expected[rkey]; 46 | has_diff = true; 47 | } 48 | } 49 | // reverse the property assignment (increasing sort order) 50 | var diff = [['left', left], ['right', right]].reduce(function(diff, arr){ 51 | diff[arr[0]] = Object.keys(arr[1]).sort().reduce(function(side, key){ 52 | side[key] = arr[1][key]; 53 | return side; 54 | }, {}); 55 | return diff; 56 | }, {}); 57 | return !has_diff ? null : diff; 58 | } 59 | default: 60 | if(typeof ArrayBuffer == 'undefined' || !ArrayBuffer.isView(actual)){ 61 | return default_diff; 62 | } 63 | // fallthrough 64 | case Array.prototype: { 65 | if(actual.length != expected.length) return default_diff; 66 | var left = [], right = []; 67 | actual.forEach(function(value, index){ 68 | var d = object_diff(actual[index], expected[index]); 69 | if(d === null) return; 70 | //console.log(require('util').inspect(d.left, {depth: 3})); 71 | //console.log(require('util').inspect(d.right, {depth: 3})); 72 | left.push(d.left), right.push(d.right); 73 | }); 74 | return left.length == 0 ? null : {left: left, right: right}; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "devDependencies": { 4 | "acorn": "^8.0.1", 5 | "asar": "^3.0.3", 6 | "benchmark": "^2.1.4", 7 | "meriyah": "^2.1.1", 8 | "minimist": "^1.2.5", 9 | "tenko": "^1.1.1", 10 | "test262-parser-tests": "0.0.5", 11 | "web-tree-sitter": "^0.17.1" 12 | }, 13 | "scripts": { 14 | "postinstall": "node ../scripts/postinstall.js" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | process.on('unhandledRejection', (reason, p) => { 2 | console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); 3 | }); 4 | 5 | import {Parser} from '../src/interface.js'; 6 | import disk from 'asar/lib/disk.js'; 7 | import * as acorn from 'acorn'; 8 | import Tenko from 'tenko'; 9 | import {object_diff} from './object_diff.js'; 10 | import fs from 'fs'; 11 | import readline from 'readline'; 12 | import parse_args from 'minimist'; 13 | 14 | const arg = parse_args(process.argv.slice(2)); 15 | let test_count = 0; 16 | 17 | const color = { 18 | bold_red: x => `\x1b[0;38;2;255;0;0m${x}\x1b[0m`, 19 | bold_green: x => `\x1b[0;38;2;0;255;0m${x}\x1b[0m`, 20 | bold_magenta: x => `\x1b[0;38;2;255;0;255m${x}\x1b[0m`, 21 | bright_red: x => `\x1b[38;2;255;128;128m${x}\x1b[0m`, 22 | bright_green: x => `\x1b[38;2;128;255;128m${x}\x1b[0m`, 23 | bright_blue: x => `\x1b[38;2;128;128;255m${x}\x1b[0m`, 24 | bright_cyan: x => `\x1b[38;2;128;255;255m${x}\x1b[0m`, 25 | blue: x => `\x1b[38;2;0;0;255m${x}\x1b[0m`, 26 | cyan: x => `\x1b[38;2;0;255;255m${x}\x1b[0m`, 27 | yellow: x => `\x1b[38;2;255;255;0m${x}\x1b[0m`, 28 | magenta: x => `\x1b[35m${x}\x1b[0m`, 29 | gray: x => `\x1b[38;2;128;128;128m${x}\x1b[0m`, 30 | }; 31 | 32 | function test_file(utf8_view, script, options) 33 | { 34 | ++test_count; 35 | const {is_module, is_negative} = options; 36 | const parser = new Parser(); 37 | const params = 0; 38 | parser.load_utf8_view(utf8_view); 39 | let program; 40 | try { 41 | const parse_result = parser.parse_code(is_module, params); 42 | program = parse_result.program; 43 | program = JSON.parse(JSON.stringify(program)); 44 | } catch(e) { 45 | //if(!is_negative) console.log('error id:', e.id); 46 | if(options.error_line) { 47 | const position = e.position; 48 | if(options.error_line != position.line || 49 | options.error_column-1 != position.column 50 | ){ 51 | print_error('mismatching error location', script, options); 52 | console.log(options, position); 53 | } else if(options.error) { 54 | //console.log('error', options.error); 55 | if(options.error == 'expect') { 56 | const token_string = Parser.token_string(e.expected_token_id); 57 | if(token_string != options.expected_token) { 58 | print_error('mismatching expected token', script, options); 59 | console.log(options, e.expected_token_id, token_string); 60 | } 61 | } else { 62 | const error = Parser.error[options.error]; 63 | if(!error) { 64 | print_error(`unknown error ${options.error}`, script, options); 65 | } else if(error.id === undefined || e.id === undefined || error.id != e.id) { 66 | print_error('mismatching error type', script, options); 67 | console.log(options, error.id?.toString(16), e.id?.toString(16)); 68 | } 69 | } 70 | } 71 | } 72 | //console.log(token.location); 73 | } 74 | let reference_result; 75 | const source_type = (is_module ? 'module' : 'script'); 76 | try { 77 | const options = {ecmaVersion: 2020, sourceType: source_type, locations: true, sourceFile: ''}; 78 | reference_result = acorn.parse(script, options); 79 | //reference_result = Tenko(script, {goalMode: source_type, loc: true, sourceField: ''}).ast; 80 | reference_result = JSON.parse(JSON.stringify(reference_result)); 81 | } catch(e) { 82 | //console.log(e); 83 | } 84 | let result; 85 | if(is_negative) { 86 | result = (program ? undefined : null); 87 | //result = (!program && !reference_result ? null : undefined); 88 | if(!program && reference_result) { 89 | const type = (is_negative ? 'negative' : 'positive'); 90 | console.log(color.gray(`[${source_type}][${type}] ${script}`)); 91 | } 92 | } else { 93 | if(!reference_result && options.warn_acorn) { 94 | result = null; 95 | const type = (is_negative ? 'negative' : 'positive'); 96 | console.log(color.gray(`[${source_type}][${type}] ${script}`)); 97 | } else { 98 | result = (program && reference_result ? object_diff(program, reference_result) : undefined); 99 | } 100 | } 101 | /* 102 | if(result !== null) { 103 | console.log( 104 | JSON.stringify(program, null, ' '), 105 | JSON.stringify(reference_result, null, ' ') 106 | ); 107 | } 108 | //*/ 109 | parser.free(); 110 | return result; 111 | } 112 | 113 | function test_test262_suite() 114 | { 115 | for(const suite of ['fail', 'early', 'pass', 'pass-explicit']) { 116 | //for(const suite of ['fail', 'pass', 'pass-explicit']) { 117 | const is_negative = (suite == 'fail' || suite == 'early'); 118 | console.group(color.bold_magenta(`test262/${suite}`)); 119 | const suite_path = `data/test262/${suite}.asar`; 120 | const asarfs = disk.readFilesystemSync(suite_path); 121 | for(const path of asarfs.listFiles()) 122 | { 123 | const adjusted_path = path.substring(1); 124 | const is_module = /\.module\.js$|\.mjs$/.test(adjusted_path); 125 | const info = asarfs.getFile(adjusted_path); 126 | const utf8_view = disk.readFileSync(asarfs, adjusted_path, info); 127 | const script = utf8_view.toString(); 128 | const options = {is_module: is_module, is_negative: is_negative}; 129 | const diff = test_file(utf8_view, script, options); 130 | if(diff !== null) { 131 | console.log(color.bold_red(`test262/${suite}/${adjusted_path}`)); 132 | console.log(script); 133 | } 134 | } 135 | console.groupEnd(); 136 | } 137 | } 138 | 139 | function print_error(message, script, options) { 140 | if(!options.has_failed) { 141 | console.log(color.bold_red(`${options.file_path}`)); 142 | } 143 | const fail_color = color[(options.is_negative ? 'bright_red' : 'bright_green')]; 144 | console.log((options.is_module ? color.bright_blue('[module]') : color.yellow('[script]')), fail_color(script)); 145 | options.has_failed = true; 146 | if(message) console.log(message); 147 | } 148 | 149 | function test_segmented_file(file_path, is_module, is_negative) 150 | { 151 | let begin = 0, index = 0; 152 | const settings = {}; 153 | const global_options = {error: undefined}; 154 | const options = {is_module: is_module, is_negative: is_negative, has_failed: false, file_path: file_path}; 155 | const utf8_view = fs.readFileSync(file_path); 156 | const length = utf8_view.byteLength; 157 | const script = utf8_view.toString(); 158 | function print_location_error() { 159 | const line = utf8_view.subarray(begin, index).toString(); 160 | print_error('invalid error location', line, options); 161 | } 162 | function test_script(segment_view) { 163 | const script = segment_view.toString(); 164 | //console.log(script, script.length); console.log('---'); 165 | const diff = test_file(segment_view, script, options); 166 | if(diff !== null) print_error(undefined, script, options); 167 | } 168 | const cr = '\r'.charCodeAt(0); 169 | const lf = '\n'.charCodeAt(0); 170 | const slash = '/'.charCodeAt(0); 171 | const lesser = '<'.charCodeAt(0); 172 | const greater = '>'.charCodeAt(0); 173 | const question = '?'.charCodeAt(0); 174 | const space = ' '.charCodeAt(0); 175 | const at = '@'.charCodeAt(0); 176 | const zero = '0'.charCodeAt(0); 177 | const nine = '9'.charCodeAt(0); 178 | const colon = ':'.charCodeAt(0); 179 | const minus = '-'.charCodeAt(0); 180 | const eat_white = () => { 181 | while(++index < length && utf8_view[index] == space); 182 | } 183 | const until_white = () => { 184 | let begin = index; 185 | while(++index < length) { 186 | const c = utf8_view[index]; 187 | if(c == space || c == cr || c == lf) break; 188 | } 189 | return utf8_view.subarray(begin, index).toString(); 190 | }; 191 | const until_newline = () => { 192 | while(++index < length) { 193 | const c = utf8_view[index]; 194 | if(c == cr || c == lf) break; 195 | } 196 | }; 197 | const eat_newline_only = () => { 198 | const c = utf8_view[index]; 199 | if(c == lf) return ++index; 200 | else if(c == cr && ++index < length && utf8_view[index] == lf) ++index; 201 | }; 202 | const eat_newline = () => { 203 | if(settings.preserve_newlines) { 204 | return eat_newline_only(); 205 | } 206 | while(index < length) { 207 | const c = utf8_view[index]; 208 | if(c != cr && c != lf) break; 209 | ++index; 210 | } 211 | }; 212 | const read_error = (is_global) => { 213 | const error_begin = index; 214 | const error = until_white(); 215 | if(!error) { 216 | print_error(`invalid error tag: ${utf8_view.subarray(end, index).toString()}`, script, options); 217 | return 0; 218 | } 219 | switch(error) { 220 | case 'default': { 221 | delete options.error; 222 | if(is_global) { 223 | delete global_options.error; 224 | } 225 | break; 226 | } 227 | case 'expect': { 228 | --index; eat_white(); 229 | options.error = error; 230 | options.expected_token = until_white(); 231 | if(options.expected_token == 'none') { 232 | options.error = undefined; 233 | options.expected_token = undefined; 234 | } 235 | if(is_global) { 236 | global_options.error = options.error; 237 | global_options.expected_token = options.expected_token; 238 | } 239 | break; 240 | } 241 | default: { 242 | options.error = error; 243 | if(is_global) global_options.error = error; 244 | } 245 | } 246 | --index; until_newline(); 247 | return 1; 248 | }; 249 | while(index < length) { 250 | let end = index; 251 | if(utf8_view[index] != slash) { ++index; continue; } 252 | if(++index == length || utf8_view[index] != slash) continue; 253 | if(++index == length) continue; 254 | if(utf8_view[index] == slash) { 255 | // ignore comments 256 | const at_begin = (begin == end); 257 | until_newline(); eat_newline(); 258 | if(at_begin) begin = index; 259 | continue; 260 | } else if(utf8_view[index] == minus) { 261 | const at_begin = (begin == end); 262 | eat_white(); 263 | if(!read_error(true)) return; 264 | eat_newline(); 265 | if(at_begin) begin = index; 266 | continue; 267 | } else if(utf8_view[index] == '#'.charCodeAt(0)) { 268 | eat_white(); const settings_begin = index; until_newline(); 269 | const _settings = JSON.parse(utf8_view.subarray(settings_begin, index).toString()); 270 | Object.assign(settings, _settings); 271 | eat_newline(); 272 | begin = index; 273 | continue; 274 | } else if(utf8_view[index] == question) { 275 | while(++index < length && utf8_view[index] == space); 276 | options.is_negative = false, options.is_module = false; 277 | options.can_exclude = false, options.is_pedantic = false; 278 | options.use_annex = false, options.expected_token = undefined; 279 | options.warn_acorn = false; 280 | options.error = global_options.error; 281 | options.expected_token = global_options.expected_token; 282 | if(index != length && utf8_view[index] == lesser) { 283 | while(++index != length) { 284 | if(utf8_view[index] == greater) break; 285 | switch(utf8_view[index]) { 286 | case '+'.charCodeAt(0): options.is_negative = false; break; 287 | case '-'.charCodeAt(0): options.is_negative = true; break; 288 | case '#'.charCodeAt(0): options.is_module = true; break; 289 | case '^'.charCodeAt(0): options.can_exclude = true; break; 290 | case '?'.charCodeAt(0): options.is_pedantic = true; break; 291 | case '&'.charCodeAt(0): options.use_annex = true; break; 292 | case 'a'.charCodeAt(0): options.warn_acorn = true; break; 293 | default: break; 294 | } 295 | } 296 | if(index == length) { 297 | print_error(`invalid test tag: ${utf8_view.subarray(end, index).toString()}`, script, options); 298 | return; 299 | } 300 | ++index; 301 | } 302 | } else continue; 303 | const parse_integer = () => { 304 | let str = ''; 305 | while(++index < length) { 306 | let c = utf8_view[index]; 307 | if(c < zero || c > nine) break; 308 | str += String.fromCharCode(c); 309 | } 310 | return (str == '' ? undefined : parseInt(str)); 311 | } 312 | // read error location 313 | while(index < length && utf8_view[index] == space) ++index; 314 | let line, column; 315 | delete options.error_line; 316 | delete options.error_column; 317 | if(utf8_view[index] == at) { 318 | line = parse_integer(); 319 | if(line === undefined || index == length || utf8_view[index] != colon) { 320 | print_location_error(); return; 321 | } 322 | column = parse_integer(); 323 | if(column === undefined) { print_location_error(); return; } 324 | options.error_line = line, options.error_column = column; 325 | while(index < length && utf8_view[index] == space) ++index; 326 | } 327 | if(utf8_view[index] == minus) { 328 | ++index; 329 | if(!read_error()) return; 330 | } 331 | eat_newline(); 332 | if(begin < end || (begin == end && settings.allow_empty)) { 333 | test_script(utf8_view.subarray(begin, end)); 334 | } 335 | begin = index; 336 | } 337 | if(begin < length) { 338 | test_script(utf8_view.subarray(begin, length)); 339 | } 340 | } 341 | 342 | function test_falcon_suite_dir(suite_path, is_negative, segmented) 343 | { 344 | console.group(color.bold_magenta(`falcon/${suite_path}`)); 345 | for(const file of fs.readdirSync(suite_path)) 346 | { 347 | const file_path = `${suite_path}/${file}`; 348 | if(fs.statSync(file_path).isDirectory()) { 349 | test_falcon_suite_dir(file_path, is_negative, segmented); 350 | continue; 351 | } 352 | if(file.startsWith('_')) continue; 353 | if(arg.native && /libraries/.test(file_path)) continue; 354 | //if(/libraries/.test(file_path)) continue; 355 | if(/tsserver/.test(file_path)) continue; 356 | if(!/\.js$/.test(file_path)) continue; 357 | //console.log(file_path); 358 | const is_module = /\.module\.js$|\.mjs$/.test(file_path); 359 | if(is_negative || segmented) { 360 | test_segmented_file(file_path, is_module, is_negative); 361 | } else { 362 | process.stdout.write(file_path); 363 | const utf8_view = fs.readFileSync(file_path); 364 | const script = utf8_view.toString(); 365 | const options = {is_module: is_module, is_negative: is_negative}; 366 | const diff = test_file(utf8_view, script, options); 367 | readline.clearLine(process.stdout); 368 | readline.cursorTo(process.stdout, 0); 369 | if(diff !== null) { 370 | console.log(color.bold_red(`test262/${file_path}`)); 371 | //console.log(JSON.stringify(diff, null, ' ')); 372 | } 373 | } 374 | } 375 | console.groupEnd(); 376 | } 377 | 378 | function test_falcon_suite() 379 | { 380 | //for(const suite of ['pass', 'fail', 'native']) { 381 | for(const suite of ['pass', 'native']) { 382 | //for(const suite of ['pass', 'fail']) { 383 | //for(const suite of ['fail']) { 384 | test_falcon_suite_dir(`data/${suite}`, suite == 'fail', suite != 'pass'); 385 | } 386 | } 387 | 388 | (async () => { 389 | await Parser.load_wasm('../dist/parser.wasm'); 390 | if(arg.f) { 391 | const is_module = !!arg.m; 392 | const is_negative = !!arg.n; 393 | const is_segmented = !!arg.n || !!arg.s; 394 | if(is_segmented) { 395 | test_segmented_file(arg.f, is_module, is_negative); 396 | } else { 397 | const utf8_view = fs.readFileSync(arg.f); 398 | const script = utf8_view.toString(); 399 | const options = {is_module: is_module, is_negative: is_negative}; 400 | const diff = test_file(utf8_view, script, options); 401 | if(diff !== null) { 402 | console.log(color.bold_red(`${arg.f}`)); 403 | } 404 | } 405 | } else if(arg.s) { 406 | test_falcon_suite_dir(arg.s, !!arg.n); 407 | } else { 408 | if(!arg.native) test_test262_suite(); 409 | test_falcon_suite(); 410 | console.log('test count:', test_count); 411 | } 412 | })(); 413 | --------------------------------------------------------------------------------