Add javascript

This commit is contained in:
xenia 2023-12-21 14:00:00 +01:00
parent 3088bcfa22
commit b43f5ecea1
20 changed files with 18753 additions and 0 deletions

View File

@ -8,3 +8,4 @@ Languages:
* python: https://github.com/tree-sitter/tree-sitter-python (MIT)
* rust: https://github.com/tree-sitter/tree-sitter-rust (MIT)
* html: https://github.com/tree-sitter/tree-sitter-html (MIT)
* javascript: https://github.com/tree-sitter/tree-sitter-javascript (MIT)

View File

@ -45,6 +45,7 @@
packages.python = compile-tree-sitter { src = ./python; name = "python"; };
packages.rust = compile-tree-sitter { src = ./rust; name = "rust"; };
packages.html = compile-tree-sitter { src = ./html; name = "html"; };
packages.javascript = compile-tree-sitter { src = ./javascript; name = "javascript"; };
}
);
}

21
javascript/LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Max Brunsfeld
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.

9190
javascript/examples/jquery.js vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1242
javascript/grammar.js Normal file

File diff suppressed because it is too large Load Diff

188
javascript/src/scanner.c Normal file
View File

@ -0,0 +1,188 @@
#include <tree_sitter/parser.h>
#include <wctype.h>
enum TokenType {
AUTOMATIC_SEMICOLON,
TEMPLATE_CHARS,
TERNARY_QMARK,
};
void *tree_sitter_javascript_external_scanner_create() { return NULL; }
void tree_sitter_javascript_external_scanner_destroy(void *p) {}
void tree_sitter_javascript_external_scanner_reset(void *p) {}
unsigned tree_sitter_javascript_external_scanner_serialize(void *p, char *buffer) { return 0; }
void tree_sitter_javascript_external_scanner_deserialize(void *p, const char *b, unsigned n) {}
static void advance(TSLexer *lexer) { lexer->advance(lexer, false); }
static void skip(TSLexer *lexer) { lexer->advance(lexer, true); }
static bool scan_template_chars(TSLexer *lexer) {
lexer->result_symbol = TEMPLATE_CHARS;
for (bool has_content = false;; has_content = true) {
lexer->mark_end(lexer);
switch (lexer->lookahead) {
case '`':
return has_content;
case '\0':
return false;
case '$':
advance(lexer);
if (lexer->lookahead == '{') return has_content;
break;
case '\\':
return has_content;
default:
advance(lexer);
}
}
}
static bool scan_whitespace_and_comments(TSLexer *lexer) {
for (;;) {
while (iswspace(lexer->lookahead)) {
skip(lexer);
}
if (lexer->lookahead == '/') {
skip(lexer);
if (lexer->lookahead == '/') {
skip(lexer);
while (lexer->lookahead != 0 && lexer->lookahead != '\n' && lexer->lookahead != 0x2028 &&
lexer->lookahead != 0x2029) {
skip(lexer);
}
} else if (lexer->lookahead == '*') {
skip(lexer);
while (lexer->lookahead != 0) {
if (lexer->lookahead == '*') {
skip(lexer);
if (lexer->lookahead == '/') {
skip(lexer);
break;
}
} else {
skip(lexer);
}
}
} else {
return false;
}
} else {
return true;
}
}
}
static bool scan_automatic_semicolon(TSLexer *lexer) {
lexer->result_symbol = AUTOMATIC_SEMICOLON;
lexer->mark_end(lexer);
for (;;) {
if (lexer->lookahead == 0) return true;
if (lexer->lookahead == '}') return true;
if (lexer->is_at_included_range_start(lexer)) return true;
if (lexer->lookahead == '\n' || lexer->lookahead == 0x2028 || lexer->lookahead == 0x2029) break;
if (!iswspace(lexer->lookahead)) return false;
skip(lexer);
}
skip(lexer);
if (!scan_whitespace_and_comments(lexer)) return false;
switch (lexer->lookahead) {
case ',':
case '.':
case ':':
case ';':
case '*':
case '%':
case '>':
case '<':
case '=':
case '[':
case '(':
case '?':
case '^':
case '|':
case '&':
case '/':
return false;
// Insert a semicolon before `--` and `++`, but not before binary `+` or `-`.
case '+':
skip(lexer);
return lexer->lookahead == '+';
case '-':
skip(lexer);
return lexer->lookahead == '-';
// Don't insert a semicolon before `!=`, but do insert one before a unary `!`.
case '!':
skip(lexer);
return lexer->lookahead != '=';
// Don't insert a semicolon before `in` or `instanceof`, but do insert one
// before an identifier.
case 'i':
skip(lexer);
if (lexer->lookahead != 'n') return true;
skip(lexer);
if (!iswalpha(lexer->lookahead)) return false;
for (unsigned i = 0; i < 8; i++) {
if (lexer->lookahead != "stanceof"[i]) return true;
skip(lexer);
}
if (!iswalpha(lexer->lookahead)) return false;
break;
}
return true;
}
static bool scan_ternary_qmark(TSLexer *lexer) {
for(;;) {
if (!iswspace(lexer->lookahead)) break;
skip(lexer);
}
if (lexer->lookahead == '?') {
advance(lexer);
if (lexer->lookahead == '?') return false;
lexer->mark_end(lexer);
lexer->result_symbol = TERNARY_QMARK;
if (lexer->lookahead == '.') {
advance(lexer);
if (iswdigit(lexer->lookahead)) return true;
return false;
}
return true;
}
return false;
}
bool tree_sitter_javascript_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
if (valid_symbols[TEMPLATE_CHARS]) {
if (valid_symbols[AUTOMATIC_SEMICOLON]) return false;
return scan_template_chars(lexer);
} else if (valid_symbols[AUTOMATIC_SEMICOLON]) {
bool ret = scan_automatic_semicolon(lexer);
if (!ret && valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?')
return scan_ternary_qmark(lexer);
return ret;
}
if (valid_symbols[TERNARY_QMARK]) {
return scan_ternary_qmark(lexer);
}
return false;
}

View File

@ -0,0 +1,111 @@
============================================
Object destructuring assignments
============================================
({a, b: c.d, ...e[f]} = object);
let {a, b, ...c} = object
const {a, b: {c, d}} = object
---
(program
(expression_statement (parenthesized_expression (assignment_expression
(object_pattern
(shorthand_property_identifier_pattern)
(pair_pattern
(property_identifier)
(member_expression (identifier) (property_identifier)))
(rest_pattern (subscript_expression (identifier) (identifier))))
(identifier))))
(lexical_declaration (variable_declarator
(object_pattern
(shorthand_property_identifier_pattern)
(shorthand_property_identifier_pattern)
(rest_pattern (identifier)))
(identifier)))
(lexical_declaration (variable_declarator
(object_pattern
(shorthand_property_identifier_pattern)
(pair_pattern
(property_identifier)
(object_pattern
(shorthand_property_identifier_pattern)
(shorthand_property_identifier_pattern))))
(identifier))))
============================================
Object destructuring parameters
============================================
function a ({b, c}, {d}) {}
---
(program
(function_declaration (identifier)
(formal_parameters
(object_pattern (shorthand_property_identifier_pattern) (shorthand_property_identifier_pattern))
(object_pattern (shorthand_property_identifier_pattern)))
(statement_block)))
============================================
Array destructuring assignments
============================================
[a, b.c, ...c[d]] = array;
[a, b, ...c] = array;
[,, c,, d,] = array;
---
(program
(expression_statement (assignment_expression
(array_pattern
(identifier)
(member_expression (identifier) (property_identifier))
(rest_pattern (subscript_expression (identifier) (identifier))))
(identifier)))
(expression_statement (assignment_expression
(array_pattern
(identifier)
(identifier)
(rest_pattern (identifier)))
(identifier)))
(expression_statement (assignment_expression
(array_pattern
(identifier)
(identifier))
(identifier))))
================================================
Object destructuring patterns w/ default values
================================================
let {a: b = c} = object;
for await (var {a: {b} = object} of asyncIter) {}
function a({b = true}, [c, d = false]) {}
function b({c} = {}) {}
---
(program
(lexical_declaration (variable_declarator
(object_pattern (pair_pattern
(property_identifier)
(assignment_pattern (identifier) (identifier))))
(identifier)))
(for_in_statement
(object_pattern (pair_pattern
(property_identifier)
(assignment_pattern (object_pattern (shorthand_property_identifier_pattern)) (identifier))))
(identifier)
(statement_block))
(function_declaration (identifier)
(formal_parameters
(object_pattern (object_assignment_pattern (shorthand_property_identifier_pattern) (true)))
(array_pattern (identifier) (assignment_pattern (identifier) (false))))
(statement_block))
(function_declaration (identifier)
(formal_parameters
(assignment_pattern (object_pattern (shorthand_property_identifier_pattern)) (object)))
(statement_block)))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,136 @@
============================================
Simple
============================================
const Named = <template>
{{ (doubled foo) }}
</template>
----
(program
(lexical_declaration
(variable_declarator
(identifier)
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag)))))
============================================
Empty
============================================
<template></template>
----
(program
(expression_statement
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
============================================
Two Components
============================================
const WithSemi = <template>
{{ (doubled foo) }}
</template>;
<template>
<WithSemi />
</template>;
----
(program
(lexical_declaration
(variable_declarator
(identifier)
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
(expression_statement
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
============================================
Multiple Assignment
============================================
const Empty = <template></template>
const WithSemi = <template>
<Empty />
{{ (doubled foo) }}
</template>;
<template>
<WithSemi />
</template>;
----
(program
(lexical_declaration
(variable_declarator
(identifier)
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
(lexical_declaration
(variable_declarator
(identifier)
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
(expression_statement
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag))))
============================================
Class Component
============================================
class InClass {
<template>
{{this.whatever}}
</template>
}
----
(program
(class_declaration
(identifier)
(class_body
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag)))))
============================================
JS Regex Evasion
============================================
<template>
{{#if true}}
{{/if}}
</template>
----
(program
(expression_statement
(glimmer_template
(glimmer_opening_tag)
(glimmer_closing_tag)
)))

View File

@ -0,0 +1,43 @@
============================================
JSDoc
============================================
/*
* @return {void}
*/
function foo() {}
----
(program
(comment)
(function_declaration
(identifier)
(formal_parameters)
(statement_block)))
============================================
JSX
============================================
const foo = 2;
<div>{{foo}}</div>
----
(program
(lexical_declaration
(variable_declarator
(identifier)
(number)))
(expression_statement
(jsx_element
(jsx_opening_element
(identifier))
(jsx_expression
(object
(shorthand_property_identifier)))
(jsx_closing_element
(identifier)))))

View File

@ -0,0 +1,153 @@
============================================
Numbers
============================================
04000
400
100n
0xffffffffn
0b00111n
0o1234n
0xa_b_c
0o1_1
0b1_000_000
1_2_3
12_3.4_5e6_7
0b1_000_000n
01
00000123
---
(program
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number))
(expression_statement (number)))
============================================
Unicode identifiers
============================================
const últimaVez = 1
{ 県: '大阪府', '': '' }
---
(program
(lexical_declaration (variable_declarator (identifier) (number)))
(expression_statement
(object
(pair (property_identifier) (string (string_fragment)))
(pair (string) (string)))))
==========================================
Strings containing comment-like content
==========================================
"//ok\n//what"
---
(program
(expression_statement
(string (string_fragment) (escape_sequence) (string_fragment))))
==========================================
Quote escaping
==========================================
"";
'';
"\"";
"a\"b";
'\'';
'a\'b';
"it's a tiny tiny world";
'"hello"';
---
(program
(expression_statement (string))
(expression_statement (string))
(expression_statement (string (escape_sequence)))
(expression_statement
(string (string_fragment) (escape_sequence) (string_fragment)))
(expression_statement (string (escape_sequence)))
(expression_statement
(string (string_fragment) (escape_sequence) (string_fragment)))
(expression_statement (string (string_fragment)))
(expression_statement (string (string_fragment))))
==========================================
Line continuations
==========================================
"hello\
world";
'hello\
world';
---
(program
(expression_statement
(string (string_fragment) (escape_sequence) (string_fragment)))
(expression_statement
(string (string_fragment) (escape_sequence) (string_fragment))))
============================================================
Non-standard unescaped newlines legal in TSX attributes
============================================================
"hello
world";
'hello
world';
---
(program
(expression_statement (string (string_fragment)))
(expression_statement (string (string_fragment))))
=========================================================
JSX strings with unescaped newlines for TSX attributes
=========================================================
<Element Attribute="hello
world"></Element>;
<Element Attribute='hello
world'></Element>;
---
(program
(expression_statement
(jsx_element
(jsx_opening_element
(identifier)
(jsx_attribute (property_identifier) (string (string_fragment))))
(jsx_closing_element
(identifier))))
(expression_statement
(jsx_element
(jsx_opening_element
(identifier)
(jsx_attribute (property_identifier) (string (string_fragment))))
(jsx_closing_element
(identifier)))))

View File

@ -0,0 +1,289 @@
============================================
Automatic semicolon insertion
============================================
if (a) {
var b = c
d()
e()
return f
}
---
(program
(if_statement
(parenthesized_expression (identifier))
(statement_block
(variable_declaration (variable_declarator (identifier) (identifier)))
(expression_statement (call_expression (identifier) (arguments)))
(expression_statement (call_expression (identifier) (arguments)))
(return_statement (identifier)))))
============================================
Semicolon insertion before update expressions
============================================
if (a)
d()
++b
if (a)
d()
--b
---
(program
(if_statement
(parenthesized_expression (identifier))
(expression_statement
(call_expression (identifier) (arguments))))
(expression_statement (update_expression (identifier)))
(if_statement
(parenthesized_expression (identifier))
(expression_statement
(call_expression (identifier) (arguments))))
(expression_statement (update_expression (identifier))))
==========================================
property access across lines
==========================================
object
.someProperty
.otherProperty
---
(program (expression_statement
(member_expression
(member_expression (identifier) (property_identifier))
(property_identifier))))
===========================================
indented code after blocks
===========================================
function x() {}
return z;
---
(program
(function_declaration
(identifier)
(formal_parameters)
(statement_block))
(return_statement (identifier)))
================================================
operator expressions split across lines
================================================
a
? b
: c
a
|| b
a
^ b
a
!== b
a
!b; // standalone statement
---
(program
(expression_statement (ternary_expression (identifier) (identifier) (identifier)))
(expression_statement (binary_expression (identifier) (identifier)))
(expression_statement (binary_expression (identifier) (identifier)))
(expression_statement (binary_expression (identifier) (identifier)))
(expression_statement (identifier))
(expression_statement (unary_expression (identifier)))
(comment))
================================================
Alphabetical infix operators split across lines
================================================
a
i;
a
in b;
a
ins;
a
inst;
a
instanceof b;
a
instanceofX;
---
(program
(expression_statement (identifier))
(expression_statement (identifier))
(expression_statement (binary_expression (identifier) (identifier)))
(expression_statement (identifier))
(expression_statement (identifier))
(expression_statement (identifier))
(expression_statement (identifier))
(expression_statement (binary_expression (identifier) (identifier)))
(expression_statement (identifier))
(expression_statement (identifier)))
===========================================
Single-line if/else statements
===========================================
if (a) {b} else {c}
---
(program
(if_statement (parenthesized_expression (identifier))
(statement_block (expression_statement (identifier)))
(else_clause
(statement_block (expression_statement (identifier))))))
===========================================
single-line blocks without semicolons
===========================================
function a() {b}
function c() {return d}
---
(program
(function_declaration (identifier) (formal_parameters) (statement_block
(expression_statement (identifier))))
(function_declaration (identifier) (formal_parameters) (statement_block
(return_statement (identifier)))))
==============================================
Multi-line chained expressions in var declarations
==============================================
var a = new A()
.b({c: 'd'})
.e()
---
(program
(variable_declaration (variable_declarator
(identifier)
(call_expression
(member_expression
(call_expression
(member_expression
(new_expression (identifier) (arguments))
(property_identifier))
(arguments
(object
(pair (property_identifier) (string (string_fragment))))))
(property_identifier))
(arguments)))))
==============================================
if/for/while/do statements without semicolons
==============================================
if (a) { if (b) return c }
if (d) { for (;;) break }
if (e) { for (f in g) break }
if (h) { for (i of j) continue }
if (k) { while (l) break }
if (m) { do { n; } while (o) }
if (p) { var q }
---
(program
(if_statement (parenthesized_expression (identifier)) (statement_block
(if_statement
(parenthesized_expression (identifier))
(return_statement (identifier)))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(for_statement
(empty_statement)
(empty_statement)
(break_statement))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(for_in_statement (identifier) (identifier)
(break_statement))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(for_in_statement (identifier) (identifier)
(continue_statement))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(while_statement
(parenthesized_expression (identifier))
(break_statement))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(do_statement
(statement_block (expression_statement (identifier)))
(parenthesized_expression (identifier)))))
(if_statement (parenthesized_expression (identifier)) (statement_block
(variable_declaration (variable_declarator (identifier))))))
=====================================================
Single-line declarations without semicolons
=====================================================
function a () { function b () {} function *c () {} class D {} return }
---
(program
(function_declaration (identifier) (formal_parameters) (statement_block
(function_declaration (identifier) (formal_parameters) (statement_block))
(generator_function_declaration (identifier) (formal_parameters) (statement_block))
(class_declaration (identifier) (class_body))
(return_statement))))
=====================================================
Comments after statements without semicolons
=====================================================
let a // comment at end of declaration
// comment outside of declaration
let b /* comment between declarators */, c
/** comment with *stars* **/ /* comment with /slashes/ */
/* third comment in a row */
let d
---
(program
(lexical_declaration
(variable_declarator (identifier))
(comment))
(comment)
(lexical_declaration
(variable_declarator (identifier))
(comment)
(variable_declarator (identifier)))
(comment)
(comment)
(comment)
(lexical_declaration (variable_declarator (identifier))))

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
var a = 'a';
// ^ variable
var b = function() {};
// ^ function
var c = () => {};
// ^ function
var d = async () => {};
// ^ function
module.e = 'e';
// ^ property
module.f = function() {};
// ^ function.method
module.g = async function() {};
// ^ function.method
module.h = () => {};
// ^ function.method
function i() {
// ^ function
}
class Person {
static foo = bar;
// ^ property
getName() {
// ^ function.method
}
}
foo(function callback() {
// ^ keyword
// ^ function
})
c();
// <- function
module.e();
// ^ function.method

View File

@ -0,0 +1,5 @@
eval(js `var foo`)
// <- function
// ^ function
// ^ keyword
// ^ variable

View File

@ -0,0 +1,12 @@
do {} while (a);
// <- keyword
// ^ keyword
try {} catch (e) {} finally {}
// <- keyword
// ^ keyword
// ^ keyword
throw e
// <- keyword
// ^ variable

View File

@ -0,0 +1,48 @@
class A {}
// ^ constructor
const ABC = 1
// ^ constant
const AB_C1 = 2
// ^ constant
const {AB_C2_D3} = x
// ^ constant
module.exports = function(one, two) {
// <- variable.builtin
// ^ variable.parameter
if (something()) {
let module = null, one = 1;
// ^ variable
// ^ variable
console.log(module, one, two);
// ^ variable.builtin
// ^ variable
// ^ variable
// ^ variable.parameter
}
console.log(module, one, two);
// ^ variable.builtin
// ^ variable.builtin
// ^ variable.parameter
// ^ variable.parameter
};
console.log(module, one, two);
// ^ variable.builtin
// ^ variable.builtin
// ^ variable
// ^ variable
function one({two: three}, [four]) {
// ^ property
// ^ variable.parameter
// ^ variable.parameter
console.log(two, three, four)
// ^ variable
// ^ variable.parameter
// ^ variable.parameter
}

View File

@ -0,0 +1,14 @@
class Person {
// ^ definition.class
static foo = bar;
getName() {
// ^ definition.method
}
}
var person = new Person();
// ^ reference.class
person.getName()
// ^ reference.call

View File

@ -0,0 +1,22 @@
function foo() {
// ^ definition.function
}
foo()
// <- reference.call
{ source: $ => repeat($._expression) }
// ^ definition.function
// ^ reference.call
let plus1 = x => x + 1
// ^ definition.function
let plus2 = function(x) { return x + 2 }
// ^ definition.function
function *gen() { }
// ^ definition.function
async function* foo() { yield 1; }
// ^ definition.function