Merge commit '6fc75e0478e89a6adef4903069b0035247378665'

pull/315/head
Wilfred Hughes 2022-07-10 22:38:31 +07:00
commit 7cfca8a39f
15 changed files with 130023 additions and 82107 deletions

@ -0,0 +1,20 @@
Copyright (c) 2020-2022 UserNobody14 and others
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.

@ -0,0 +1,461 @@
let tree;
(async () => {
const CAPTURE_REGEX = /@\s*([\w\._-]+)/g;
const COLORS_BY_INDEX = [
'blue',
'chocolate',
'darkblue',
'darkcyan',
'darkgreen',
'darkred',
'darkslategray',
'dimgray',
'green',
'indigo',
'navy',
'red',
'sienna',
];
const scriptURL = document.currentScript.getAttribute('src');
const codeInput = document.getElementById('code-input');
const languageSelect = document.getElementById('language-select');
const loggingCheckbox = document.getElementById('logging-checkbox');
const outputContainer = document.getElementById('output-container');
const outputContainerScroll = document.getElementById('output-container-scroll');
const playgroundContainer = document.getElementById('playground-container');
const queryCheckbox = document.getElementById('query-checkbox');
const queryContainer = document.getElementById('query-container');
const queryInput = document.getElementById('query-input');
const updateTimeSpan = document.getElementById('update-time');
const languagesByName = {};
loadState();
await TreeSitter.init();
const parser = new TreeSitter();
const codeEditor = CodeMirror.fromTextArea(codeInput, {
lineNumbers: true,
showCursorWhenSelecting: true
});
const queryEditor = CodeMirror.fromTextArea(queryInput, {
lineNumbers: true,
showCursorWhenSelecting: true
});
const cluster = new Clusterize({
rows: [],
noDataText: null,
contentElem: outputContainer,
scrollElem: outputContainerScroll
});
const renderTreeOnCodeChange = debounce(renderTree, 50);
const saveStateOnChange = debounce(saveState, 2000);
const runTreeQueryOnChange = debounce(runTreeQuery, 50);
let languageName = languageSelect.value;
let treeRows = null;
let treeRowHighlightedIndex = -1;
let parseCount = 0;
let isRendering = 0;
let query;
codeEditor.on('changes', handleCodeChange);
codeEditor.on('viewportChange', runTreeQueryOnChange);
codeEditor.on('cursorActivity', debounce(handleCursorMovement, 150));
queryEditor.on('changes', debounce(handleQueryChange, 150));
loggingCheckbox.addEventListener('change', handleLoggingChange);
queryCheckbox.addEventListener('change', handleQueryEnableChange);
languageSelect.addEventListener('change', handleLanguageChange);
outputContainer.addEventListener('click', handleTreeClick);
handleQueryEnableChange();
await handleLanguageChange()
playgroundContainer.style.visibility = 'visible';
async function handleLanguageChange() {
const newLanguageName = languageSelect.value;
if (!languagesByName[newLanguageName]) {
const url = `${LANGUAGE_BASE_URL}/tree-sitter-${newLanguageName}.wasm`
languageSelect.disabled = true;
try {
languagesByName[newLanguageName] = await TreeSitter.Language.load(url);
} catch (e) {
console.error(e);
languageSelect.value = languageName;
return
} finally {
languageSelect.disabled = false;
}
}
tree = null;
languageName = newLanguageName;
parser.setLanguage(languagesByName[newLanguageName]);
handleCodeChange();
handleQueryChange();
}
async function handleCodeChange(editor, changes) {
const newText = codeEditor.getValue() + '\n';
const edits = tree && changes && changes.map(treeEditForEditorChange);
const start = performance.now();
if (edits) {
for (const edit of edits) {
tree.edit(edit);
}
}
const newTree = parser.parse(newText, tree);
const duration = (performance.now() - start).toFixed(1);
updateTimeSpan.innerText = `${duration} ms`;
if (tree) tree.delete();
tree = newTree;
parseCount++;
renderTreeOnCodeChange();
runTreeQueryOnChange();
saveStateOnChange();
}
async function renderTree() {
isRendering++;
const cursor = tree.walk();
let currentRenderCount = parseCount;
let row = '';
let rows = [];
let finishedRow = false;
let visitedChildren = false;
let indentLevel = 0;
for (let i = 0;; i++) {
if (i > 0 && i % 10000 === 0) {
await new Promise(r => setTimeout(r, 0));
if (parseCount !== currentRenderCount) {
cursor.delete();
isRendering--;
return;
}
}
let displayName;
if (cursor.nodeIsMissing) {
displayName = `MISSING ${cursor.nodeType}`
} else if (cursor.nodeIsNamed) {
displayName = cursor.nodeType;
}
if (visitedChildren) {
if (displayName) {
finishedRow = true;
}
if (cursor.gotoNextSibling()) {
visitedChildren = false;
} else if (cursor.gotoParent()) {
visitedChildren = true;
indentLevel--;
} else {
break;
}
} else {
if (displayName) {
if (finishedRow) {
row += '</div>';
rows.push(row);
finishedRow = false;
}
const start = cursor.startPosition;
const end = cursor.endPosition;
const id = cursor.nodeId;
let fieldName = cursor.currentFieldName();
if (fieldName) {
fieldName += ': ';
} else {
fieldName = '';
}
row = `<div>${' '.repeat(indentLevel)}${fieldName}<a class='plain' href="#" data-id=${id} data-range="${start.row},${start.column},${end.row},${end.column}">${displayName}</a> [${start.row}, ${start.column}] - [${end.row}, ${end.column}])`;
finishedRow = true;
}
if (cursor.gotoFirstChild()) {
visitedChildren = false;
indentLevel++;
} else {
visitedChildren = true;
}
}
}
if (finishedRow) {
row += '</div>';
rows.push(row);
}
cursor.delete();
cluster.update(rows);
treeRows = rows;
isRendering--;
handleCursorMovement();
}
function runTreeQuery(_, startRow, endRow) {
if (endRow == null) {
const viewport = codeEditor.getViewport();
startRow = viewport.from;
endRow = viewport.to;
}
codeEditor.operation(() => {
const marks = codeEditor.getAllMarks();
marks.forEach(m => m.clear());
if (tree && query) {
const captures = query.captures(
tree.rootNode,
{row: startRow, column: 0},
{row: endRow, column: 0},
);
let lastNodeId;
for (const {name, node} of captures) {
if (node.id === lastNodeId) continue;
lastNodeId = node.id;
const {startPosition, endPosition} = node;
codeEditor.markText(
{line: startPosition.row, ch: startPosition.column},
{line: endPosition.row, ch: endPosition.column},
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(name)}`
}
);
}
}
});
}
function handleQueryChange() {
if (query) {
query.delete();
query.deleted = true;
query = null;
}
queryEditor.operation(() => {
queryEditor.getAllMarks().forEach(m => m.clear());
if (!queryCheckbox.checked) return;
const queryText = queryEditor.getValue();
try {
query = parser.getLanguage().query(queryText);
let match;
let row = 0;
queryEditor.eachLine((line) => {
while (match = CAPTURE_REGEX.exec(line.text)) {
queryEditor.markText(
{line: row, ch: match.index},
{line: row, ch: match.index + match[0].length},
{
inclusiveLeft: true,
inclusiveRight: true,
css: `color: ${colorForCaptureName(match[1])}`
}
);
}
row++;
});
} catch (error) {
const startPosition = queryEditor.posFromIndex(error.index);
const endPosition = {
line: startPosition.line,
ch: startPosition.ch + (error.length || Infinity)
};
if (error.index === queryText.length) {
if (startPosition.ch > 0) {
startPosition.ch--;
} else if (startPosition.row > 0) {
startPosition.row--;
startPosition.column = Infinity;
}
}
queryEditor.markText(
startPosition,
endPosition,
{
className: 'query-error',
inclusiveLeft: true,
inclusiveRight: true,
attributes: {title: error.message}
}
);
}
});
runTreeQuery();
saveQueryState();
}
function handleCursorMovement() {
if (isRendering) return;
const selection = codeEditor.getDoc().listSelections()[0];
let start = {row: selection.anchor.line, column: selection.anchor.ch};
let end = {row: selection.head.line, column: selection.head.ch};
if (
start.row > end.row ||
(
start.row === end.row &&
start.column > end.column
)
) {
let swap = end;
end = start;
start = swap;
}
const node = tree.rootNode.namedDescendantForPosition(start, end);
if (treeRows) {
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row) treeRows[treeRowHighlightedIndex] = row.replace('highlighted', 'plain');
}
treeRowHighlightedIndex = treeRows.findIndex(row => row.includes(`data-id=${node.id}`));
if (treeRowHighlightedIndex !== -1) {
const row = treeRows[treeRowHighlightedIndex];
if (row) treeRows[treeRowHighlightedIndex] = row.replace('plain', 'highlighted');
}
cluster.update(treeRows);
const lineHeight = cluster.options.item_height;
const scrollTop = outputContainerScroll.scrollTop;
const containerHeight = outputContainerScroll.clientHeight;
const offset = treeRowHighlightedIndex * lineHeight;
if (scrollTop > offset - 20) {
$(outputContainerScroll).animate({scrollTop: offset - 20}, 150);
} else if (scrollTop < offset + lineHeight + 40 - containerHeight) {
$(outputContainerScroll).animate({scrollTop: offset - containerHeight + 40}, 150);
}
}
}
function handleTreeClick(event) {
if (event.target.tagName === 'A') {
event.preventDefault();
const [startRow, startColumn, endRow, endColumn] = event
.target
.dataset
.range
.split(',')
.map(n => parseInt(n));
codeEditor.focus();
codeEditor.setSelection(
{line: startRow, ch: startColumn},
{line: endRow, ch: endColumn}
);
}
}
function handleLoggingChange() {
if (loggingCheckbox.checked) {
parser.setLogger((message, lexing) => {
if (lexing) {
console.log(" ", message)
} else {
console.log(message)
}
});
} else {
parser.setLogger(null);
}
}
function handleQueryEnableChange() {
if (queryCheckbox.checked) {
queryContainer.style.visibility = '';
queryContainer.style.position = '';
} else {
queryContainer.style.visibility = 'hidden';
queryContainer.style.position = 'absolute';
}
handleQueryChange();
}
function treeEditForEditorChange(change) {
const oldLineCount = change.removed.length;
const newLineCount = change.text.length;
const lastLineLength = change.text[newLineCount - 1].length;
const startPosition = {row: change.from.line, column: change.from.ch};
const oldEndPosition = {row: change.to.line, column: change.to.ch};
const newEndPosition = {
row: startPosition.row + newLineCount - 1,
column: newLineCount === 1
? startPosition.column + lastLineLength
: lastLineLength
};
const startIndex = codeEditor.indexFromPos(change.from);
let newEndIndex = startIndex + newLineCount - 1;
let oldEndIndex = startIndex + oldLineCount - 1;
for (let i = 0; i < newLineCount; i++) newEndIndex += change.text[i].length;
for (let i = 0; i < oldLineCount; i++) oldEndIndex += change.removed[i].length;
return {
startIndex, oldEndIndex, newEndIndex,
startPosition, oldEndPosition, newEndPosition
};
}
function colorForCaptureName(capture) {
const id = query.captureNames.indexOf(capture);
return COLORS_BY_INDEX[id % COLORS_BY_INDEX.length];
}
function loadState() {
const language = localStorage.getItem("language");
const sourceCode = localStorage.getItem("sourceCode");
const query = localStorage.getItem("query");
const queryEnabled = localStorage.getItem("queryEnabled");
if (language != null && sourceCode != null && query != null) {
queryInput.value = query;
codeInput.value = sourceCode;
languageSelect.value = language;
queryCheckbox.checked = (queryEnabled === 'true');
}
}
function saveState() {
localStorage.setItem("language", languageSelect.value);
localStorage.setItem("sourceCode", codeEditor.getValue());
saveQueryState();
}
function saveQueryState() {
localStorage.setItem("queryEnabled", queryCheckbox.checked);
localStorage.setItem("query", queryEditor.getValue());
}
function debounce(func, wait, immediate) {
var timeout;
return function() {
var context = this, args = arguments;
var later = function() {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
})();

File diff suppressed because one or more lines are too long

@ -63,13 +63,14 @@ module.exports = grammar({
$._template_chars_single,
$._template_chars_double_single,
$._template_chars_single_single,
$._template_chars_raw_slash
$._template_chars_raw_slash,
$._block_comment,
$._documentation_block_comment,
],
extras: $ => [
$.comment,
$.documentation_comment,
// $.multiline_comment,
/\s/
],
@ -117,6 +118,11 @@ module.exports = grammar({
// [$._real_expression, $._below_relational_expression],
[$._postfix_expression],
[$._top_level_definition, $.lambda_expression],
[$._top_level_definition, $._var_or_type, $.function_signature],
[$._var_or_type, $.function_signature],
[$._var_or_type, $._function_formal_parameter],
[$._var_or_type],
[$._top_level_definition, $._var_or_type],
[$._top_level_definition, $._final_const_var_or_type],
[$._top_level_definition, $.const_object_expression, $._final_const_var_or_type],
[$._final_const_var_or_type, $.const_object_expression],
@ -155,6 +161,7 @@ module.exports = grammar({
[$._type_not_void_not_function, $._function_type_tail],
[$._type_not_void],
[$._type_not_void_not_function],
[$.super_formal_parameter, $.unconditional_assignable_selector],
[$.function_signature]
],
@ -237,7 +244,7 @@ module.exports = grammar({
),
seq(
optional($._late_builtin),
choice($._type, $.inferred_type),
choice($._type, seq($.inferred_type, optional($._type))),
$.initialized_identifier_list,
$._semicolon
)
@ -642,16 +649,22 @@ module.exports = grammar({
//todo: use the op names in place of these.
_assignment_operator: $ => choice(
'=',
seq(
choice(
$._multiplicative_operator,
$._shift_operator,
$._bitwise_operator,
$._additive_operator,
'??'
),
'='
)
// additive operator
'+=',
'-=',
// multiplicative operator
'*=',
'/=',
'%=',
'~/=',
// shift operator
'<<=',
'>>=',
'>>>=',
'&=',
'^=',
'|=',
'??=',
),
// binary_expression: $ => choice(
@ -1089,7 +1102,7 @@ module.exports = grammar({
cascade_section: $ => prec.left(
DART_PREC.Cascade,
seq(
'..',
choice('..', '?..'),
$.cascade_selector,
repeat($.argument_part),
repeat(
@ -1171,7 +1184,8 @@ module.exports = grammar({
// Statements
_statement: $ => choice(
$.block,
$.local_variable_declaration,
prec.dynamic(1, $.local_function_declaration),
prec.dynamic(2, $.local_variable_declaration),
$.for_statement,
$.while_statement,
$.do_statement,
@ -1188,7 +1202,11 @@ module.exports = grammar({
$.yield_each_statement,
$.expression_statement,
$.assert_statement,
$.labeled_statement,
// $.labeled_statement,
),
local_function_declaration: $ => seq(
optional($._metadata),
$.lambda_expression
),
@ -1207,11 +1225,15 @@ module.exports = grammar({
assert_statement: $ => seq($.assertion, ';'),
assertion: $ => seq($._assert_builtin, '(', $._expression, optional(seq(
',',
$._expression,
optional(',')
)), ')'),
assertion: $ => seq($._assert_builtin, '(', $._expression,
optional(
seq(
',',
$._expression
)
),
optional(','),
')'),
switch_statement: $ => seq(
'switch',
@ -1225,10 +1247,20 @@ module.exports = grammar({
'}'
),
switch_label: $ => choice(
switch_case: $ => choice(
seq(repeat($.label), $.case_builtin, $._expression, ':', repeat1($._statement)),
),
default_case: $ => choice(
seq(repeat($.label), 'default', ':', repeat1($._statement)),
),
switch_label: $ => seq(
repeat($.label),
choice(
seq($.case_builtin, $._expression, ':'),
seq('default', ':')
),
)),
do_statement: $ => seq(
'do',
@ -1593,6 +1625,12 @@ module.exports = grammar({
alias(
$.identifier,
$.type_identifier),
// This is a comment
// comment with a link made in https://github.com/flutter/flutter/pull/48547
// Changes made in https://github.com/flutter/flutter/pull/48547
/* This is also a comment */
/* this comment /* // /** ends here: */
optional($._nullable_type),
optional($.type_bound)
),
@ -1751,11 +1789,74 @@ module.exports = grammar({
$._static,
$.function_signature,
),
// | static const 〈type〉? 〈staticFinalDeclarationList〉
// | static final 〈type〉? 〈staticFinalDeclarationList〉
// | static late final 〈type〉? 〈initializedIdentifierList〉
// | static late? 〈varOrType〉 〈initializedIdentifierList
seq(
$._static,
$._final_or_const,
optional($._type),
$.static_final_declaration_list
choice(
seq(
$._final_or_const,
optional($._type),
$.static_final_declaration_list
),
seq(
$._late_builtin,
choice(
seq(
$.final_builtin,
optional($._type),
$.initialized_identifier_list
),
seq(
choice(
$._type,
$.inferred_type,
),
$.initialized_identifier_list
)
)
),
seq(
choice(
$._type,
$.inferred_type,
),
$.initialized_identifier_list
)
)
),
// | covariant late final 〈type〉? 〈identifierList〉
// | covariant late? 〈varOrType〉 〈initializedIdentifierList〉
seq(
$._covariant,
choice(
seq(
$._late_builtin,
choice(
seq(
$.final_builtin,
optional($._type),
$.identifier_list
),
seq(
choice(
$._type,
$.inferred_type,
),
$.initialized_identifier_list
)
)
),
seq(
choice(
$._type,
$.inferred_type,
),
$.initialized_identifier_list
)
)
),
seq(
optional($._late_builtin), $.final_builtin,
@ -1763,12 +1864,8 @@ module.exports = grammar({
$.initialized_identifier_list
),
seq(
optional($._static_or_covariant),
optional($._late_builtin),
choice(
$._type,
$.inferred_type
),
$._var_or_type,
$.initialized_identifier_list
)
// TODO: add in the 'late' keyword from the informal draft spec:
@ -1778,6 +1875,10 @@ module.exports = grammar({
// |late?final〈type〉?〈initializedIdentifierList〉
// |late?〈varOrType〉 〈initializedIdentifierList〉
),
identifier_list: $ => commaSep1(
$.identifier
),
initialized_identifier_list: $ => commaSep1(
$.initialized_identifier
),
@ -1844,10 +1945,6 @@ module.exports = grammar({
//$.arguements
$.arguments
),
seq('super',
//$.arguements
$.arguments
),
$.field_initializer,
$.assertion
),
@ -1984,10 +2081,7 @@ module.exports = grammar({
$._type
)),
seq(optional($._late_builtin),
choice(
$.inferred_type,
$._type
))
$._var_or_type)
),
_type: $ => choice(
@ -2053,9 +2147,12 @@ module.exports = grammar({
')'
),
normal_parameter_type: $ => choice(
$.typed_identifier,
$._type
normal_parameter_type: $ => seq(
optional($._metadata),
choice(
$.typed_identifier,
$._type
)
),
optional_parameter_types: $ => choice(
@ -2070,10 +2167,16 @@ module.exports = grammar({
),
named_parameter_types: $ => seq(
'{',
commaSep1TrailingComma($.typed_identifier),
commaSep1TrailingComma($._named_parameter_type),
'}'
),
_named_parameter_type: $ => seq(
optional($._metadata),
optional($._required),
$.typed_identifier
),
_type_not_void: $ => choice(
seq(
$.function_type,
@ -2126,7 +2229,6 @@ module.exports = grammar({
),
typed_identifier: $ => seq(
optional($._metadata),
$._type,
$.identifier
),
@ -2144,6 +2246,14 @@ module.exports = grammar({
void_type: $ => token('void'),
_var_or_type: $ => choice(
$._type,
seq(
$.inferred_type,
optional($._type)
)
),
inferred_type: $ => prec(
DART_PREC.BUILTIN,
'var',
@ -2300,7 +2410,7 @@ module.exports = grammar({
_default_named_parameter: $ => choice(
seq(
optional(
'required'
$._required
),
$.formal_parameter,
optional(
@ -2312,7 +2422,7 @@ module.exports = grammar({
),
seq(
optional(
'required'
$._required
),
$.formal_parameter,
optional(
@ -2331,8 +2441,8 @@ module.exports = grammar({
choice(
$._function_formal_parameter,
$._simple_formal_parameter,
$.constructor_param
// $.field_formal_parameter
$.constructor_param,
$.super_formal_parameter
)
),
@ -2357,6 +2467,16 @@ module.exports = grammar({
$.identifier
)
),
// see https://github.com/dart-lang/language/blob/31f3d2bd6fd83b2e5f5019adb276c23fd2900941/working/1855%20-%20super%20parameters/proposal.md
super_formal_parameter: $ => seq(
optional($._final_const_var_or_type),
$.super,
'.',
$.identifier,
optional($._formal_parameter_part)
),
//constructor param = field formal parameter
constructor_param: $ => seq(
optional($._final_const_var_or_type),
@ -2501,6 +2621,10 @@ module.exports = grammar({
DART_PREC.BUILTIN,
'part',
),
_required: $ => prec(
DART_PREC.BUILTIN,
'required',
),
_set: $ => prec(
DART_PREC.BUILTIN,
'set',
@ -2564,83 +2688,35 @@ module.exports = grammar({
label: $ => seq($.identifier, ':'),
_semicolon: $ => seq(';', optional($._automatic_semicolon)),
_semicolon: $ => seq(';'),
identifier: $ => /[a-zA-Z_$][\w$]*/,
identifier_dollar_escaped: $ => /([a-zA-Z_]|(\\\$))([\w]|(\\\$))*/,
//TODO: add support for triple-slash comments as a special category.
// Trying to add support for nested multiline comments.
// http://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment/36328890#36328890
comment: $ => token(choice(
seq('//', /[^/].*/),
// _line_comment: $ => token(seq(
// '//', /[^\/].*/
// )),
// _documentation_line_comment: $ => token(seq('///', /.*/)),
comment: $ => choice(
$._block_comment,
seq('//', /([^/\n].*)?/),
seq(
'/*',
/[^*]*\*+([^/*][^*]*\*+)*/,
'/'
)
)),
),
//added nesting comments.
documentation_comment: $ => token(
documentation_comment: $ =>
choice(
$._documentation_block_comment,
seq('///', /.*/),
// seq(
// '/**',
// repeat(
// choice(
// /[^*]*\*+([^/*][^*]*\*+)*/,
// // $.comment
// // ,
// /.*/,
// $._multiline_comment,
// $.documentation_comment
// )
// ),
// '*/'
// )
)
),
// multiline_comment: $ => seq(
// $._multiline_comment_begin,
// $._multiline_comment_core,
// // repeat(
// // choice(
// // $._multiline_comment_core,
// // $.multiline_comment
// // )
// // ),
// $._multiline_comment_end
// ),
// _multiline_comment_end: $ => token('*/'),
// _multiline_comment_begin: $ => token('/*'),
//
// _nested_multiline_comment: $ => seq(
// $._multiline_comment_begin,
// repeat(
// choice(
// /([^\/*]*|\/[^*]|\*[^\/])+/,
// $._nested_multiline_comment
// // seq(
// // $._multiline_comment_begin,
// // $._multiline_comment_core,
// // )
// )
// ),
// $._multiline_comment_end
// ),
//
// _multiline_comment_core: $ => seq(
// repeat1(
// choice(
// /([^\/*]*|\/[^*]|\*[^\/])+/,
// $._nested_multiline_comment
// // seq(
// // $._multiline_comment_begin,
// // $._multiline_comment_core,
// // )
// )
// ),
// // $._multiline_comment_end
// ),
,
}
});

@ -11,12 +11,12 @@
"author": "Benjamin Sobel",
"license": "ISC",
"dependencies": {
"nan": "^2.14.2"
"nan": "^2.15.0"
},
"devDependencies": {
"node-gyp": "^7.1.2",
"npm-watch": "^0.7.0",
"tree-sitter-cli": "^0.19.2"
"tree-sitter-cli": "^0.19.5"
},
"watch": {
"test": {
@ -51,7 +51,8 @@
"scope": "source.dart",
"file-types": [
"dart"
]
],
"injection-regex": "dart"
}
]
}

@ -119,10 +119,6 @@
(unconditional_assignable_selector
(identifier) @property)
;; https://github.com/UserNobody14/tree-sitter-dart/issues/24
;; (assignable_selector
;; (identifier) @property)
; assignments
(assignment_expression
left: (assignable_expression) @variable)

File diff suppressed because it is too large Load Diff

@ -100,11 +100,7 @@
"named": true
},
{
"type": "labeled_statement",
"named": true
},
{
"type": "lambda_expression",
"type": "local_function_declaration",
"named": true
},
{
@ -749,27 +745,35 @@
]
},
"operator": {
"multiple": true,
"multiple": false,
"required": true,
"types": [
{
"type": "%",
"type": "%=",
"named": false
},
{
"type": "&=",
"named": false
},
{
"type": "&",
"type": "*=",
"named": false
},
{
"type": "*",
"type": "+=",
"named": false
},
{
"type": "/",
"type": "-=",
"named": false
},
{
"type": "<<",
"type": "/=",
"named": false
},
{
"type": "<<=",
"named": false
},
{
@ -777,27 +781,27 @@
"named": false
},
{
"type": ">>",
"type": ">>=",
"named": false
},
{
"type": ">>>",
"type": ">>>=",
"named": false
},
{
"type": "??",
"type": "??=",
"named": false
},
{
"type": "^",
"type": "^=",
"named": false
},
{
"type": "|",
"type": "|=",
"named": false
},
{
"type": "~/",
"type": "~/=",
"named": false
}
]
@ -945,27 +949,35 @@
]
},
"operator": {
"multiple": true,
"multiple": false,
"required": true,
"types": [
{
"type": "%",
"type": "%=",
"named": false
},
{
"type": "&",
"type": "&=",
"named": false
},
{
"type": "*",
"type": "*=",
"named": false
},
{
"type": "/",
"type": "+=",
"named": false
},
{
"type": "<<",
"type": "-=",
"named": false
},
{
"type": "/=",
"named": false
},
{
"type": "<<=",
"named": false
},
{
@ -973,27 +985,27 @@
"named": false
},
{
"type": ">>",
"type": ">>=",
"named": false
},
{
"type": ">>>",
"type": ">>>=",
"named": false
},
{
"type": "??",
"type": "??=",
"named": false
},
{
"type": "^",
"type": "^=",
"named": false
},
{
"type": "|",
"type": "|=",
"named": false
},
{
"type": "~/",
"type": "~/=",
"named": false
}
]
@ -2093,6 +2105,11 @@
]
}
},
{
"type": "comment",
"named": true,
"fields": {}
},
{
"type": "conditional_assignable_selector",
"named": true,
@ -2763,6 +2780,10 @@
"type": "getter_signature",
"named": true
},
{
"type": "identifier_list",
"named": true
},
{
"type": "inferred_type",
"named": true
@ -2859,6 +2880,11 @@
}
}
},
{
"type": "documentation_comment",
"named": true,
"fields": {}
},
{
"type": "dotted_identifier_list",
"named": true,
@ -4980,6 +5006,10 @@
"type": "marker_annotation",
"named": true
},
{
"type": "super_formal_parameter",
"named": true
},
{
"type": "type_arguments",
"named": true
@ -5430,6 +5460,21 @@
"named": true,
"fields": {}
},
{
"type": "identifier_list",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "identifier",
"named": true
}
]
}
},
{
"type": "if_element",
"named": true,
@ -6486,25 +6531,6 @@
]
}
},
{
"type": "labeled_statement",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "_statement",
"named": true
},
{
"type": "identifier",
"named": true
}
]
}
},
{
"type": "lambda_expression",
"named": true,
@ -6751,6 +6777,29 @@
]
}
},
{
"type": "local_function_declaration",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "annotation",
"named": true
},
{
"type": "lambda_expression",
"named": true
},
{
"type": "marker_annotation",
"named": true
}
]
}
},
{
"type": "local_variable_declaration",
"named": true,
@ -7473,6 +7522,14 @@
"multiple": true,
"required": true,
"types": [
{
"type": "annotation",
"named": true
},
{
"type": "marker_annotation",
"named": true
},
{
"type": "typed_identifier",
"named": true
@ -7524,10 +7581,18 @@
"multiple": true,
"required": false,
"types": [
{
"type": "annotation",
"named": true
},
{
"type": "function_type",
"named": true
},
{
"type": "marker_annotation",
"named": true
},
{
"type": "type_arguments",
"named": true
@ -9382,6 +9447,61 @@
"named": true,
"fields": {}
},
{
"type": "super_formal_parameter",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "const_builtin",
"named": true
},
{
"type": "final_builtin",
"named": true
},
{
"type": "formal_parameter_list",
"named": true
},
{
"type": "function_type",
"named": true
},
{
"type": "identifier",
"named": true
},
{
"type": "inferred_type",
"named": true
},
{
"type": "super",
"named": true
},
{
"type": "type_arguments",
"named": true
},
{
"type": "type_identifier",
"named": true
},
{
"type": "type_parameters",
"named": true
},
{
"type": "void_type",
"named": true
}
]
}
},
{
"type": "superclass",
"named": true,
@ -9492,6 +9612,10 @@
"type": "if_null_expression",
"named": true
},
{
"type": "label",
"named": true
},
{
"type": "logical_and_expression",
"named": true
@ -10508,10 +10632,6 @@
"multiple": true,
"required": true,
"types": [
{
"type": "annotation",
"named": true
},
{
"type": "function_type",
"named": true
@ -10520,10 +10640,6 @@
"type": "identifier",
"named": true
},
{
"type": "marker_annotation",
"named": true
},
{
"type": "type_arguments",
"named": true
@ -11143,6 +11259,10 @@
"type": "%",
"named": false
},
{
"type": "%=",
"named": false
},
{
"type": "&",
"named": false
@ -11151,6 +11271,10 @@
"type": "&&",
"named": false
},
{
"type": "&=",
"named": false
},
{
"type": "'",
"named": false
@ -11171,10 +11295,22 @@
"type": "*",
"named": false
},
{
"type": "*=",
"named": false
},
{
"type": "+=",
"named": false
},
{
"type": ",",
"named": false
},
{
"type": "-=",
"named": false
},
{
"type": ".",
"named": false
@ -11191,6 +11327,22 @@
"type": "/",
"named": false
},
{
"type": "/*",
"named": false
},
{
"type": "//",
"named": false
},
{
"type": "///",
"named": false
},
{
"type": "/=",
"named": false
},
{
"type": ":",
"named": false
@ -11207,6 +11359,10 @@
"type": "<<",
"named": false
},
{
"type": "<<=",
"named": false
},
{
"type": "<=",
"named": false
@ -11235,10 +11391,18 @@
"type": ">>",
"named": false
},
{
"type": ">>=",
"named": false
},
{
"type": ">>>",
"named": false
},
{
"type": ">>>=",
"named": false
},
{
"type": "?",
"named": false
@ -11247,10 +11411,18 @@
"type": "?.",
"named": false
},
{
"type": "?..",
"named": false
},
{
"type": "??",
"named": false
},
{
"type": "??=",
"named": false
},
{
"type": "@",
"named": false
@ -11279,6 +11451,10 @@
"type": "^",
"named": false
},
{
"type": "^=",
"named": false
},
{
"type": "abstract",
"named": false
@ -11315,10 +11491,6 @@
"type": "class",
"named": false
},
{
"type": "comment",
"named": true
},
{
"type": "const_builtin",
"named": true
@ -11351,10 +11523,6 @@
"type": "do",
"named": false
},
{
"type": "documentation_comment",
"named": true
},
{
"type": "dynamic",
"named": false
@ -11603,6 +11771,10 @@
"type": "|",
"named": false
},
{
"type": "|=",
"named": false
},
{
"type": "||",
"named": false
@ -11618,5 +11790,9 @@
{
"type": "~/",
"named": false
},
{
"type": "~/=",
"named": false
}
]

File diff suppressed because it is too large Load Diff

@ -7,7 +7,9 @@ enum TokenType {
TEMPLATE_CHARS_DOUBLE,
TEMPLATE_CHARS_SINGLE_SINGLE,
TEMPLATE_CHARS_DOUBLE_SINGLE,
TEMPLATE_CHARS_RAW_SLASH
TEMPLATE_CHARS_RAW_SLASH,
BLOCK_COMMENT,
DOCUMENTATION_BLOCK_COMMENT,
};
void *tree_sitter_dart_external_scanner_create() { return NULL; }
@ -17,32 +19,33 @@ unsigned tree_sitter_dart_external_scanner_serialize(void *p, char *buffer) { re
void tree_sitter_dart_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_whitespace_and_comments(TSLexer *lexer) {
for (;;) {
while (iswspace(lexer->lookahead)) {
advance(lexer);
skip(lexer);
}
if (lexer->lookahead == '/') {
advance(lexer);
skip(lexer);
if (lexer->lookahead == '/') {
advance(lexer);
skip(lexer);
while (lexer->lookahead != 0 && lexer->lookahead != '\n') {
advance(lexer);
skip(lexer);
}
} else if (lexer->lookahead == '*') {
advance(lexer);
skip(lexer);
while (lexer->lookahead != 0) {
if (lexer->lookahead == '*') {
advance(lexer);
skip(lexer);
if (lexer->lookahead == '/') {
advance(lexer);
skip(lexer);
break;
}
} else {
advance(lexer);
skip(lexer);
}
}
} else {
@ -54,119 +57,144 @@ static bool scan_whitespace_and_comments(TSLexer *lexer) {
}
}
bool tree_sitter_dart_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
if (valid_symbols[TEMPLATE_CHARS_DOUBLE] ||
valid_symbols[TEMPLATE_CHARS_SINGLE] ||
valid_symbols[TEMPLATE_CHARS_DOUBLE_SINGLE] ||
valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]) {
if (valid_symbols[AUTOMATIC_SEMICOLON]) return false;
if(valid_symbols[TEMPLATE_CHARS_DOUBLE]) {
lexer->result_symbol = TEMPLATE_CHARS_DOUBLE;
} else if (valid_symbols[TEMPLATE_CHARS_SINGLE]) {
lexer->result_symbol = TEMPLATE_CHARS_SINGLE;
} else if (valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]) {
lexer->result_symbol = TEMPLATE_CHARS_SINGLE_SINGLE;
} else {
lexer->result_symbol = TEMPLATE_CHARS_DOUBLE_SINGLE;
}
for (bool has_content = false;; has_content = true) {
lexer->mark_end(lexer);
switch (lexer->lookahead) {
case '\'':
case '"':
return has_content;
case '\n':
if (valid_symbols[TEMPLATE_CHARS_DOUBLE_SINGLE] || valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]) return false;
advance(lexer);
break;
case '\0':
return false;
case '$':
// advance(lexer);
// if (lexer->lookahead == '{') return has_content;
// break;
return has_content;
case '\\':
if (valid_symbols[TEMPLATE_CHARS_RAW_SLASH]) {
lexer->result_symbol = TEMPLATE_CHARS_RAW_SLASH;
advance(lexer);
} else {
return has_content;
}
break;
default:
advance(lexer);
}
}
} else {
lexer->result_symbol = AUTOMATIC_SEMICOLON;
lexer->mark_end(lexer);
static bool scan_multiline_comments(TSLexer *lexer) {
bool documentation_comment = false;
advance(lexer);
if (lexer->lookahead != '*') return false;
advance(lexer);
if (lexer->lookahead == '*') documentation_comment = true;
bool after_star = false;
unsigned nesting_depth = 1;
for (;;) {
if (lexer->lookahead == 0) return true;
if (lexer->lookahead == '}') return true;
if (lexer->is_at_included_range_start(lexer)) return true;
if (!iswspace(lexer->lookahead)) return false;
if (lexer->lookahead == '\n') break;
advance(lexer);
switch (lexer->lookahead) {
case '\0':
return false;
case '*':
advance(lexer);
after_star = true;
break;
case '/':
if (after_star) {
advance(lexer);
after_star = false;
nesting_depth--;
if (nesting_depth == 0) {
if (!documentation_comment) {
lexer->result_symbol = BLOCK_COMMENT;
} else {
lexer->result_symbol = DOCUMENTATION_BLOCK_COMMENT;
}
return true;
}
} else {
advance(lexer);
after_star = false;
if (lexer->lookahead == '*') {
nesting_depth++;
advance(lexer);
}
}
break;
default:
advance(lexer);
after_star = false;
break;
}
}
return false;
}
advance(lexer);
if (!scan_whitespace_and_comments(lexer)) return false;
static bool scan_automatic_semicolon(TSLexer *lexer) {
switch (lexer->lookahead) {
case ',':
case '.':
case ':':
case ';':
case '*':
case '%':
case '>':
case '<':
case '=':
case '[':
case '(':
case '?':
case '^':
case '|':
case '&':
case '/':
return false;
lexer->result_symbol = AUTOMATIC_SEMICOLON;
lexer->mark_end(lexer);
// Insert a semicolon before `--` and `++`, but not before binary `+` or `-`.
case '+':
advance(lexer);
return lexer->lookahead == '+';
case '-':
advance(lexer);
return lexer->lookahead == '-';
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') break;
if (!iswspace(lexer->lookahead)) return false;
skip(lexer);
}
// Don't insert a semicolon before `!=`, but do insert one before a unary `!`.
case '!':
advance(lexer);
return lexer->lookahead != '=';
skip(lexer);
// Don't insert a semicolon before `in` or `instanceof`, but do insert one
// before an identifier.
case 'i':
advance(lexer);
// if (!scan_whitespace_and_comments(lexer)) return false;
if (lexer->lookahead != 'n') return true;
advance(lexer);
return true;
if (!iswalpha(lexer->lookahead)) return false;
}
for (unsigned i = 0; i < 8; i++) {
if (lexer->lookahead != "stanceof"[i]) return true;
advance(lexer);
static bool scan_templates(TSLexer *lexer, const bool *valid_symbols) {
// if (valid_symbols[AUTOMATIC_SEMICOLON]) return false;
if(valid_symbols[TEMPLATE_CHARS_DOUBLE]) {
lexer->result_symbol = TEMPLATE_CHARS_DOUBLE;
} else if (valid_symbols[TEMPLATE_CHARS_SINGLE]) {
lexer->result_symbol = TEMPLATE_CHARS_SINGLE;
} else if (valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]) {
lexer->result_symbol = TEMPLATE_CHARS_SINGLE_SINGLE;
} else {
lexer->result_symbol = TEMPLATE_CHARS_DOUBLE_SINGLE;
}
for (bool has_content = false;; has_content = true) {
lexer->mark_end(lexer);
switch (lexer->lookahead) {
case '\'':
case '"':
return has_content;
case '\n':
if (valid_symbols[TEMPLATE_CHARS_DOUBLE_SINGLE] || valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]) return false;
advance(lexer);
break;
case '\0':
return false;
case '$':
// advance(lexer);
// if (lexer->lookahead == '{') return has_content;
// break;
return has_content;
case '\\':
if (valid_symbols[TEMPLATE_CHARS_RAW_SLASH]) {
lexer->result_symbol = TEMPLATE_CHARS_RAW_SLASH;
advance(lexer);
} else {
return has_content;
}
if (!iswalpha(lexer->lookahead)) return false;
break;
default:
advance(lexer);
}
}
return true;
}
bool tree_sitter_dart_external_scanner_scan(void *payload, TSLexer *lexer,
const bool *valid_symbols) {
// bool ret = false;
// if (lexer->lookahead == '/') {
// return scan_multiline_comments(lexer);
// }
if (
valid_symbols[TEMPLATE_CHARS_DOUBLE] ||
valid_symbols[TEMPLATE_CHARS_SINGLE] ||
valid_symbols[TEMPLATE_CHARS_DOUBLE_SINGLE] ||
valid_symbols[TEMPLATE_CHARS_SINGLE_SINGLE]
) {
return scan_templates(lexer, valid_symbols);
}
if (valid_symbols[AUTOMATIC_SEMICOLON]) {
bool ret = scan_automatic_semicolon(lexer);
return ret;
}
while (iswspace(lexer->lookahead)) lexer->advance(lexer, true);
return true;
if (lexer->lookahead == '/') {
return scan_multiline_comments(lexer);
}
return false;
}

@ -0,0 +1,704 @@
================================
big test
================================
abstract class IOSApp extends ApplicationPackage {
IOSApp({required String projectBundleId}) : super(id: projectBundleId);
@override
String get displayName => id;
String get simulatorBundlePath;
String get deviceBundlePath;
/// Directory used by ios-deploy to store incremental installation metadata for
/// faster second installs.
Directory? get appDeltaDirectory;
}
class BuildableIOSApp extends IOSApp {
BuildableIOSApp(this.project, String projectBundleId, String? hostAppBundleName)
: _hostAppBundleName = hostAppBundleName,
super(projectBundleId: projectBundleId);
static Future<BuildableIOSApp?> fromProject(IosProject project, BuildInfo? buildInfo) async {
final String? hostAppBundleName = await project.hostAppBundleName(buildInfo);
final String? projectBundleId = await project.productBundleIdentifier(buildInfo);
if (projectBundleId != null) {
return BuildableIOSApp(project, projectBundleId, hostAppBundleName);
}
return null;
}
final IosProject project;
final String? _hostAppBundleName;
@override
String? get name => _hostAppBundleName;
@override
String get simulatorBundlePath => _buildAppPath('iphonesimulator');
@override
String get deviceBundlePath => _buildAppPath('iphoneos');
@override
Directory get appDeltaDirectory => globals.fs.directory(globals.fs.path.join(getIosBuildDirectory(), 'app-delta'));
// Xcode uses this path for the final archive bundle location,
// not a top-level output directory.
// Specifying `build/ios/archive/Runner` will result in `build/ios/archive/Runner.xcarchive`.
String get archiveBundlePath => globals.fs.path.join(getIosBuildDirectory(), 'archive',
_hostAppBundleName == null ? 'Runner' : globals.fs.path.withoutExtension(_hostAppBundleName!));
// The output xcarchive bundle path `build/ios/archive/Runner.xcarchive`.
String get archiveBundleOutputPath =>
globals.fs.path.setExtension(archiveBundlePath, '.xcarchive');
String get ipaOutputPath =>
globals.fs.path.join(getIosBuildDirectory(), 'ipa');
String _buildAppPath(String type) {
return globals.fs.path.join(getIosBuildDirectory(), type, _hostAppBundleName);
}
}
---
(program (class_definition (identifier) (superclass (type_identifier))
(class_body (declaration (constructor_signature (identifier)
(formal_parameter_list (optional_formal_parameters
(formal_parameter (type_identifier) (identifier))))) (initializers
(initializer_list_entry (arguments (named_argument (label (identifier))
(identifier)))))) (marker_annotation (identifier))
(method_signature (getter_signature
(type_identifier) (identifier))) (function_body (identifier)) (declaration
(getter_signature (type_identifier) (identifier))) (declaration
(getter_signature (type_identifier) (identifier))) (documentation_comment)
(documentation_comment) (declaration (getter_signature (type_identifier) (identifier)))))
(class_definition (identifier) (superclass (type_identifier))
(class_body (declaration (constructor_signature (identifier)
(formal_parameter_list (formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (type_identifier) (identifier))
(formal_parameter (type_identifier) (identifier))))
(initializers (initializer_list_entry (field_initializer (identifier) (identifier)))
(initializer_list_entry (arguments (named_argument (label (identifier)) (identifier))))))
(method_signature (function_signature (type_identifier) (type_arguments
(type_identifier)) (identifier) (formal_parameter_list
(formal_parameter (type_identifier) (identifier))
(formal_parameter (type_identifier) (identifier)))))
(function_body
(block
(local_variable_declaration
(initialized_variable_definition (final_builtin) (type_identifier)
(identifier)
(unary_expression (await_expression (identifier)
(selector (unconditional_assignable_selector
(identifier))) (selector (argument_part (arguments (argument (identifier)))))))))
(local_variable_declaration (initialized_variable_definition (final_builtin)
(type_identifier) (identifier) (unary_expression (await_expression (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)))))))))
(if_statement (parenthesized_expression (equality_expression (identifier)
(equality_operator) (null_literal))) (block (return_statement (identifier)
(selector (argument_part (arguments (argument (identifier)) (argument (identifier))
(argument (identifier))))))))
(return_statement (null_literal))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(marker_annotation (identifier))
(method_signature (getter_signature (type_identifier)
(identifier))) (function_body (identifier)) (marker_annotation (identifier)) (method_signature
(getter_signature (type_identifier) (identifier))) (function_body (identifier)
(selector (argument_part (arguments (argument (string_literal))))))
(marker_annotation (identifier))
(method_signature (getter_signature (type_identifier) (identifier)))
(function_body (identifier)
(selector (argument_part (arguments (argument (string_literal))))))
(marker_annotation (identifier))
(method_signature (getter_signature (type_identifier) (identifier)))
(function_body (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments)))) (argument (string_literal))))))))))
(comment) (comment) (comment)
(method_signature (getter_signature (type_identifier) (identifier)))
(function_body (identifier) (selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments)))) (argument (string_literal))
(argument
(conditional_expression (equality_expression (identifier)
(equality_operator) (null_literal)) (string_literal) (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector)))))))))))
(comment)
(method_signature (getter_signature (type_identifier) (identifier)))
(function_body (identifier) (selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)) (argument (string_literal))))))
(method_signature (getter_signature (type_identifier) (identifier)))
(function_body (identifier) (selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments)))) (argument (string_literal))))))
(method_signature
(function_signature (type_identifier) (identifier)
(formal_parameter_list (formal_parameter (type_identifier) (identifier)))))
(function_body (block (return_statement (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments)))) (argument (identifier)) (argument (identifier)))))))))))
=====================================
more tests
======================================
typedef RpcPeerConnectionFunction = Future<vms.VmService> Function(
Uri uri, {
required Duration timeout,
});
---
(program
(type_alias
(type_identifier)
(function_type (type_identifier)
(type_arguments (type_identifier) (type_identifier))
(parameter_type_list
(normal_parameter_type
(typed_identifier
(type_identifier) (identifier)
)
)
(optional_parameter_types
(named_parameter_types
(typed_identifier (type_identifier) (identifier))))))))
=======================================
more tests2
=======================================
static bool? _boolAttribute(
String resourceId,
String name,
Map<String, Object?> attributes,
String attributeName,
) {
final Object? value = attributes[attributeName];
if (value == null) {
return null;
}
if (value != 'true' && value != 'false') {
throw L10nException(
'The "$attributeName" value of the "$name" placeholder in message $resourceId '
'must be a boolean value.',
);
}
return value == 'true';
}
---
(program (function_signature (type_identifier) (ERROR
(identifier)) (identifier)
(formal_parameter_list
(formal_parameter
(type_identifier) (identifier)) (formal_parameter (type_identifier) (identifier))
(formal_parameter
(type_identifier) (type_arguments (type_identifier) (type_identifier))
(identifier))
(formal_parameter (type_identifier) (identifier)))
)
(function_body (block (local_variable_declaration
(initialized_variable_definition (final_builtin) (type_identifier) (identifier)
(identifier) (selector (unconditional_assignable_selector (identifier)))))
(if_statement (parenthesized_expression (equality_expression (identifier) (equality_operator)
(null_literal))) (block (return_statement (null_literal))))
(if_statement (parenthesized_expression (logical_and_expression
(equality_expression (identifier) (equality_operator) (string_literal))
(equality_expression (identifier) (equality_operator) (string_literal))))
(block (expression_statement (throw_expression (identifier)
(selector (argument_part (arguments (argument (string_literal
(template_substitution (identifier_dollar_escaped))
(template_substitution (identifier_dollar_escaped))
(template_substitution (identifier_dollar_escaped)))))))))))
(return_statement (equality_expression (identifier) (equality_operator) (string_literal))))))
===========================================
more tests 2
===========================================
/// A doctor validator for both Intellij and Android Studio.
abstract class IntelliJValidator extends DoctorValidator {
IntelliJValidator(super.title, this.installPath, {
required FileSystem fileSystem,
required UserMessages userMessages,
}) : _fileSystem = fileSystem,
_userMessages = userMessages;
final String installPath;
final FileSystem _fileSystem;
final UserMessages _userMessages;
String get version;
String? get pluginsPath;
static const Map<String, String> _idToTitle = <String, String>{
_ultimateEditionId: _ultimateEditionTitle,
_communityEditionId: _communityEditionTitle,
};
}
---
(program
(documentation_comment)
(class_definition (identifier) (superclass (type_identifier))
(class_body (declaration (constructor_signature (identifier)
(formal_parameter_list
(formal_parameter (super_formal_parameter (super) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(optional_formal_parameters (formal_parameter (type_identifier) (identifier))
(formal_parameter (type_identifier) (identifier)))))
(initializers (initializer_list_entry (field_initializer (identifier) (identifier)))
(initializer_list_entry (field_initializer (identifier) (identifier)))))
(declaration (final_builtin) (type_identifier) (initialized_identifier_list
(initialized_identifier (identifier)))) (declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (getter_signature (type_identifier) (identifier)))
(declaration (getter_signature (type_identifier) (identifier)))
(declaration (const_builtin) (type_identifier) (type_arguments (type_identifier)
(type_identifier)) (static_final_declaration_list (static_final_declaration (identifier)
(set_or_map_literal (type_arguments (type_identifier) (type_identifier))
(pair (identifier) (identifier)) (pair (identifier) (identifier)))))))))
==============================================
more tests 3
==============================================
class _RecompileRequest extends _CompilationRequest {
_RecompileRequest(
super.completer,
this.mainUri,
this.invalidatedFiles,
this.outputPath,
this.packageConfig,
this.suppressErrors,
{this.additionalSource}
);
Uri mainUri;
List<Uri>? invalidatedFiles;
String outputPath;
PackageConfig packageConfig;
bool suppressErrors;
final String? additionalSource;
@override
Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
compiler._recompile(this);
}
---
(program
(class_definition (identifier)
(superclass (type_identifier))
(class_body (declaration
(constructor_signature (identifier)
(formal_parameter_list
(formal_parameter (super_formal_parameter (super) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (constructor_param (this) (identifier)))
(optional_formal_parameters
(formal_parameter (constructor_param (this) (identifier)))))))
(declaration (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (type_identifier) (type_arguments (type_identifier))
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (type_identifier) (initialized_identifier_list
(initialized_identifier (identifier)))) (declaration (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(declaration (type_identifier) (initialized_identifier_list
(initialized_identifier (identifier))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(marker_annotation (identifier)) (method_signature
(function_signature (type_identifier) (type_arguments (type_identifier))
(identifier) (formal_parameter_list (formal_parameter (type_identifier)
(identifier))))) (function_body (identifier) (selector
(unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (this)))))))))
===============================
more tests 4
===============================
bool debugAssertIsValid() {
assert(
textColor != null
&& style != null
&& margin != null
&& _position != null
&& _position.isFinite
&& _opacity != null
&& _opacity >= 0.0
&& _opacity <= 1.0,
);
return true;
}
---
(program
(function_signature (type_identifier) (identifier) (formal_parameter_list))
(function_body (block (assert_statement
(assertion
(logical_and_expression
(equality_expression (identifier) (equality_operator) (null_literal))
(logical_and_expression
(equality_expression (identifier) (equality_operator) (null_literal))
(logical_and_expression (equality_expression (identifier) (equality_operator) (null_literal))
(logical_and_expression (equality_expression (identifier) (equality_operator) (null_literal))
(logical_and_expression (identifier) (selector (unconditional_assignable_selector (identifier)))
(logical_and_expression (equality_expression (identifier) (equality_operator) (null_literal))
(logical_and_expression
(relational_expression (identifier) (relational_operator)
(decimal_floating_point_literal))
(relational_expression (identifier) (relational_operator) (decimal_floating_point_literal)
)
)
)
)
)
)
)
)
)
) (return_statement (true)))))
===================================
more tests 5
===================================
var TextTheme textTheme = TextTheme(error: '');
---
(program (inferred_type) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier) (identifier)
(selector (argument_part (arguments (named_argument (label (identifier)) (string_literal))))))))
===================================
more tests 6
===================================
void _layout(ConstraintType constraints) {
@pragma('vm:notify-debugger-on-exception')
void layoutCallback() {
Widget built;
try {
built = (widget as ConstrainedLayoutBuilder<ConstraintType>).builder(this, constraints);
debugWidgetBuilderValue(widget, built);
} catch (e, stack) {
built = ErrorWidget.builder(
_debugReportException(
informationCollector: () => <DiagnosticsNode>[
if (kDebugMode)
DiagnosticsDebugCreator(DebugCreator(this)),
],
),
);
}
}
owner!.buildScope(this, layoutCallback);
}
---
(program (function_signature (void_type) (identifier)
(formal_parameter_list (formal_parameter (type_identifier) (identifier))))
(function_body
(block
(local_function_declaration (annotation (identifier)
(arguments (argument (string_literal))))
(lambda_expression
(function_signature (void_type) (identifier) (formal_parameter_list))
(function_body (block (local_variable_declaration
(initialized_variable_definition (type_identifier) (identifier)))
(try_statement
(block
(expression_statement
(assignment_expression (assignable_expression (identifier))
(type_cast_expression (identifier)
(type_cast (as_operator) (type_identifier) (type_arguments (type_identifier))))
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (this)) (argument (identifier)))))))
(expression_statement
(identifier) (selector
(argument_part (arguments (argument (identifier)) (argument (identifier)))))))
(catch_clause (identifier) (identifier))
(block
(expression_statement (assignment_expression (assignable_expression (identifier)) (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments (named_argument (label (identifier))
(function_expression (formal_parameter_list) (function_expression_body
(list_literal (type_arguments (type_identifier))
(if_element (parenthesized_expression (identifier)) (identifier)
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part (arguments (argument (this)))))))))))))))))))))))))))))
(expression_statement (identifier) (selector)
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (this)) (argument (identifier)))))))))
===================================
more tests 7
===================================
void _layout(ConstraintType constraints) {
@pragma('vm:notify-debugger-on-exception')
void layoutCallback() {
Widget built;
}
}
---
(program (function_signature (void_type) (identifier)
(formal_parameter_list (formal_parameter (type_identifier) (identifier))))
(function_body (block (local_function_declaration (annotation (identifier)
(arguments (argument (string_literal))))
(lambda_expression
(function_signature (void_type) (identifier) (formal_parameter_list))
(function_body
(block (local_variable_declaration
(initialized_variable_definition (type_identifier) (identifier))))))))))
===================================
more tests 8
===================================
void _layout(ConstraintType constraints) {
@pragma('vm:notify-debugger-on-exception')
void layoutCallback() {
Widget built;
}
owner!.buildScope(this, layoutCallback);
}
---
(program (function_signature (void_type) (identifier)
(formal_parameter_list (formal_parameter (type_identifier) (identifier))))
(function_body (block (local_function_declaration (annotation (identifier)
(arguments (argument (string_literal))))
(lambda_expression (function_signature (void_type) (identifier) (formal_parameter_list))
(function_body
(block
(local_variable_declaration
(initialized_variable_definition (type_identifier) (identifier)))))))
(expression_statement (identifier) (selector) (selector
(unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (this)) (argument (identifier)))))))))
====================================
cascade selector
====================================
layer
?..link = link
..showWhenUnlinked = showWhenUnlinked
..linkedOffset = effectiveLinkedOffset
..unlinkedOffset = offset;
---
(program
(expression_statement
(identifier)
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
)
)
====================================
cascade selector 2
====================================
layer
..link = link
..showWhenUnlinked = showWhenUnlinked
..linkedOffset = effectiveLinkedOffset
..unlinkedOffset = offset;
---
(program
(expression_statement
(identifier)
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
(cascade_section (cascade_selector (identifier)) (identifier))
)
)
====================================
comment selector 1
====================================
// O
// / \ O=root
// L L L=node with label
// / \ C=node with checked
// C C* *=node removed next pass
//
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Stack(),
));
---
(program
(comment)
(comment)
(comment)
(comment)
(comment)
(comment)
(expression_statement
(unary_expression
(await_expression (identifier)
(selector (unconditional_assignable_selector (identifier)))
(selector (argument_part (arguments (argument (identifier)
(selector (argument_part
(arguments
(named_argument (label (identifier)) (identifier)
(selector (unconditional_assignable_selector (identifier))))
(named_argument (label (identifier)) (identifier) (selector (argument_part (arguments))))
)))))))))))
====================================
comment overselected 2
====================================
// }
//
class Placeholder {
Placeholder(this.resourceId, this.name, Map<String, Object?> attributes)
: assert(resourceId != null),
assert(name != null),
example = _stringAttribute(resourceId, name, attributes, 'example'),
type = _stringAttribute(resourceId, name, attributes, 'type') ?? 'Object';
final String resourceId;
}
---
(program (comment) (comment) (class_definition (identifier)
(class_body (declaration (constructor_signature (identifier) (formal_parameter_list
(formal_parameter (constructor_param (this) (identifier))) (formal_parameter (constructor_param (this) (identifier)))
(formal_parameter (type_identifier) (type_arguments (type_identifier) (type_identifier)) (identifier)))) (initializers
(initializer_list_entry (assertion (equality_expression (identifier) (equality_operator) (null_literal))))
(initializer_list_entry (assertion (equality_expression (identifier) (equality_operator) (null_literal))))
(initializer_list_entry (field_initializer (identifier) (identifier) (selector (argument_part (arguments (argument (identifier))
(argument (identifier)) (argument (identifier)) (argument (string_literal)))))))
(initializer_list_entry (field_initializer (identifier)
(if_null_expression (identifier) (selector
(argument_part
(arguments
(argument (identifier))
(argument (identifier))
(argument (identifier))
(argument (string_literal)))))
(string_literal))))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier)))))))
================================================
static late final 1
================================================
class TestRoot extends StatefulWidget {
const TestRoot({ super.key });
static late final TestRootState state;
@override
State<TestRoot> createState() => TestRootState();
}
---
(program
(class_definition (identifier) (superclass (type_identifier))
(class_body
(declaration
(constant_constructor_signature (const_builtin) (qualified (identifier))
(formal_parameter_list (optional_formal_parameters
(formal_parameter (super_formal_parameter (super) (identifier)))))))
(declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier))))
(marker_annotation (identifier))
(method_signature
(function_signature (type_identifier)
(type_arguments (type_identifier)) (identifier) (formal_parameter_list)))
(function_body (identifier) (selector (argument_part (arguments)))))))
================================================
static late final 2
================================================
class TestRoot extends StatefulWidget {
static late final TestRootState state;
}
---
(program (class_definition (identifier) (superclass (type_identifier))
(class_body (declaration (final_builtin) (type_identifier)
(initialized_identifier_list (initialized_identifier (identifier)))))))

@ -3,12 +3,14 @@ comment
====
// This is a comment
// comment with a link made in https://github.com/flutter/flutter/pull/48547
// Changes made in https://github.com/flutter/flutter/pull/48547
/* This is also a comment */
/* this comment /* // /** ends here: */
---
(program (comment) (comment) (comment))
(program (comment) (comment) (comment) (comment) (comment))
======================
comments and literals
@ -46,6 +48,7 @@ documentation comment 1
---
(program (documentation_comment))
======================
documentation comment 2
@ -60,8 +63,10 @@ documentation comment 2
---
(program (documentation_comment))
======================
documentation comment 3
fake documentation comment
======================
/*
@ -72,3 +77,47 @@ documentation comment 3
*/
---
(program (comment))
======================
documentation comment 3
======================
/**
* Is this comment is a documentation comment.
*
* That is, that the comment i
*/
---
(program (documentation_comment))
======================
regular comment 2
======================
/*
Nested comment /* ... */ bbbbbbbbbbbb
*/
---
(program (comment))
======================
regular comment 3
======================
/*/* ... */*/
---
(program (comment))

@ -435,7 +435,7 @@ typedef DismissMethod = Future<void> Function(WidgetTester tester, Finder finder
(type_identifier)
(function_type (type_identifier) (type_arguments (void_type))
(parameter_type_list (normal_parameter_type (typed_identifier (type_identifier) (identifier))) (normal_parameter_type (typed_identifier (type_identifier) (identifier)))
(optional_parameter_types (named_parameter_types (typed_identifier (marker_annotation (identifier)) (type_identifier) (identifier))))))))
(optional_parameter_types (named_parameter_types (marker_annotation (identifier)) (typed_identifier (type_identifier) (identifier))))))))
=================
script tag
@ -541,7 +541,8 @@ if (blah) {
---
(program
(local_variable_declaration (initialized_variable_definition (final_builtin) (type_identifier) (type_identifier) (identifier) (identifier) (selector
(final_builtin) (type_identifier) (type_identifier)
(static_final_declaration_list (static_final_declaration (identifier) (identifier) (selector
(unconditional_assignable_selector (identifier))) (selector (argument_part (arguments)))))
(local_variable_declaration (initialized_variable_definition (final_builtin) (type_identifier) (type_identifier) (identifier)))
(if_statement (parenthesized_expression (identifier))

@ -0,0 +1,172 @@
<head>
<meta charset="utf-8">
<title>tree-sitter THE_LANGUAGE_NAME</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.css">
<link rel="icon" type="image/png" href="http://tree-sitter.github.io/tree-sitter/assets/images/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="http://tree-sitter.github.io/tree-sitter/assets/images/favicon-16x16.png" sizes="16x16" />
</head>
<body>
<div id="playground-container" style="visibility: hidden;">
<header>
<div class=header-item>
<bold>THE_LANGUAGE_NAME</bold>
</div>
<div class=header-item>
<label for="logging-checkbox">log</label>
<input id="logging-checkbox" type="checkbox"></input>
</div>
<div class=header-item>
<label for="query-checkbox">query</label>
<input id="query-checkbox" type="checkbox"></input>
</div>
<div class=header-item>
<label for="update-time">parse time: </label>
<span id="update-time"></span>
</div>
<select id="language-select" style="display: none;">
<option value="parser">Parser</option>
</select>
</header>
<main>
<div id="input-pane">
<div id="code-container">
<textarea id="code-input"></textarea>
</div>
<div id="query-container" style="visibility: hidden; position: absolute;">
<textarea id="query-input"></textarea>
</div>
</div>
<div id="output-container-scroll">
<pre id="output-container" class="highlight"></pre>
</div>
</main>
</div>
<script
src="https://code.jquery.com/jquery-3.3.1.min.js"
crossorigin="anonymous">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.45.0/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clusterize.js/0.18.0/clusterize.min.js"></script>
<script>LANGUAGE_BASE_URL = "./";</script>
<script src=assets/tree-sitter.js></script>
<script src=assets/playground.js></script>
<style>
body {
margin: 0;
padding: 0;
}
#playground-container {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
header {
box-sizing: border-box;
display: flex;
padding: 20px;
height: 60px;
border-bottom: 1px solid #aaa;
}
main {
flex: 1;
position: relative;
}
#input-pane {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 50%;
display: flex;
flex-direction: column;
}
#code-container, #query-container {
flex: 1;
position: relative;
overflow: hidden;
border-right: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
#output-container-scroll {
position: absolute;
top: 0;
left: 50%;
bottom: 0;
right: 0;
}
.header-item {
margin-right: 30px;
}
#playground-container .CodeMirror {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
}
#output-container-scroll {
flex: 1;
padding: 0;
overflow: auto;
}
#output-container {
padding: 0 10px;
margin: 0;
}
#logging-checkbox {
vertical-align: middle;
}
.CodeMirror div.CodeMirror-cursor {
border-left: 3px solid red;
}
a {
text-decoration: none;
color: #040404;
padding: 2px;
}
a:hover {
text-decoration: underline;
}
a.highlighted {
background-color: #d9d9d9;
color: red;
border-radius: 3px;
text-decoration: underline;
}
.query-error {
text-decoration: underline red dashed;
-webkit-text-decoration: underline red dashed;
}
</style>
</body>

Binary file not shown.