diff --git a/data/fixtures/recorded/languages/php/changeRound.yml b/data/fixtures/recorded/languages/php/changeRound.yml deleted file mode 100644 index 5d095516dd..0000000000 --- a/data/fixtures/recorded/languages/php/changeRound.yml +++ /dev/null @@ -1,29 +0,0 @@ -languageId: php -command: - version: 6 - spokenForm: change round - action: - name: clearAndSetSelection - target: - type: primitive - modifiers: - - type: containingScope - scopeType: {type: surroundingPair, delimiter: parentheses} - usePrePhraseSnapshot: true -initialState: - documentContents: |- - ---< +1| "aaa"; + +[#1 Insertion delimiter] = " " + + +[#2 Content] = +[#2 Removal] = +[#2 Domain] = 2:5-2:8 + >---< +2| 'aaa'; + +[#2 Insertion delimiter] = " " + + +[#3 Content] = +[#3 Removal] = +[#3 Domain] = 3:5-3:8 + >---< +3| `aaa`; + +[#3 Insertion delimiter] = " " + + +[#4 Content] = +[#4 Removal] = +[#4 Domain] = 4:5-4:17 + >------------< +4| "aaa $bbb ccc" + +[#4 Insertion delimiter] = " " + + +[#5 Content] = +[#5 Removal] = +[#5 Domain] = 5:5-5:17 + >------------< +5| `aaa $bbb ccc`; + +[#5 Insertion delimiter] = " " diff --git a/data/fixtures/scopes/typescript.core/type.cast2.scope b/data/fixtures/scopes/typescript.core/type.cast2.scope new file mode 100644 index 0000000000..6efd72521d --- /dev/null +++ b/data/fixtures/scopes/typescript.core/type.cast2.scope @@ -0,0 +1,20 @@ +aaa as const +--- + +[Content] = 0:7-0:12 + >-----< +0| aaa as const + +[Removal] = 0:3-0:12 + >---------< +0| aaa as const + +[Leading delimiter] = 0:3-0:7 + >----< +0| aaa as const + +[Domain] = 0:0-0:12 + >------------< +0| aaa as const + +[Insertion delimiter] = " " diff --git a/packages/common/src/scopeSupportFacets/php.ts b/packages/common/src/scopeSupportFacets/php.ts index addc48678b..125e505cd4 100644 --- a/packages/common/src/scopeSupportFacets/php.ts +++ b/packages/common/src/scopeSupportFacets/php.ts @@ -11,4 +11,5 @@ const { supported, unsupported, notApplicable } = ScopeSupportFacetLevel; export const phpScopeSupport: LanguageScopeSupportFacetMap = { "comment.line": supported, "comment.block": supported, + "textFragment.string.singleLine": supported, }; diff --git a/packages/cursorless-engine/src/actions/ShowParseTree.ts b/packages/cursorless-engine/src/actions/ShowParseTree.ts index f535f05121..afe6f91bf8 100644 --- a/packages/cursorless-engine/src/actions/ShowParseTree.ts +++ b/packages/cursorless-engine/src/actions/ShowParseTree.ts @@ -116,6 +116,6 @@ function parseCursor( } function getFieldName(cursor: TreeCursor): string { - const field = cursor.currentFieldName(); + const field = cursor.currentFieldName; return field != null ? `${field}: ` : ""; } diff --git a/packages/cursorless-engine/src/core/Debug.ts b/packages/cursorless-engine/src/core/Debug.ts index 8d9ff5c597..255b05cf8d 100644 --- a/packages/cursorless-engine/src/core/Debug.ts +++ b/packages/cursorless-engine/src/core/Debug.ts @@ -101,7 +101,7 @@ export class Debug { cursor: TreeCursor, index: number, ) { - const field = cursor.currentFieldName(); + const field = cursor.currentFieldName; const fieldText = field != null ? `${field}: ` : ""; const indent = " ".repeat(index); const nodeIsLast = index === nodes.length - 1; @@ -133,7 +133,7 @@ export class Debug { private cursorGoToChildWithId(cursor: TreeCursor, id: number): boolean { cursor.gotoFirstChild(); - while (cursor.currentNode().id !== id) { + while (cursor.currentNode.id !== id) { if (!cursor.gotoNextSibling()) { return false; } diff --git a/packages/cursorless-engine/src/languages/LanguageDefinition.ts b/packages/cursorless-engine/src/languages/LanguageDefinition.ts index 1d6c3b7a0f..286358d9b8 100644 --- a/packages/cursorless-engine/src/languages/LanguageDefinition.ts +++ b/packages/cursorless-engine/src/languages/LanguageDefinition.ts @@ -52,6 +52,10 @@ export class LanguageDefinition { return undefined; } + if (!(await treeSitter.loadLanguage(languageId))) { + return undefined; + } + const rawQuery = treeSitter .getLanguage(languageId)! .query(rawLanguageQueryString); diff --git a/packages/cursorless-engine/src/languages/TreeSitterQuery/TreeSitterQuery.ts b/packages/cursorless-engine/src/languages/TreeSitterQuery/TreeSitterQuery.ts index 3ecd56b1a5..13ea57fe3e 100644 --- a/packages/cursorless-engine/src/languages/TreeSitterQuery/TreeSitterQuery.ts +++ b/packages/cursorless-engine/src/languages/TreeSitterQuery/TreeSitterQuery.ts @@ -67,11 +67,10 @@ export class TreeSitterQuery { end?: Position, ): QueryMatch[] { return this.query - .matches( - this.treeSitter.getTree(document).rootNode, - start == null ? undefined : positionToPoint(start), - end == null ? undefined : positionToPoint(end), - ) + .matches(this.treeSitter.getTree(document).rootNode, { + startPosition: start == null ? undefined : positionToPoint(start), + endPosition: end == null ? undefined : positionToPoint(end), + }) .map( ({ pattern, captures }): MutableQueryMatch => ({ patternIdx: pattern, diff --git a/packages/cursorless-engine/src/languages/latex.ts b/packages/cursorless-engine/src/languages/latex.ts index 472f43c84b..c88674c7d8 100644 --- a/packages/cursorless-engine/src/languages/latex.ts +++ b/packages/cursorless-engine/src/languages/latex.ts @@ -108,7 +108,7 @@ function extendToNamedSiblingIfExists( let endIndex = node.endIndex; const sibling = node.nextNamedSibling; - if (sibling != null && sibling.isNamed()) { + if (sibling != null && sibling.isNamed) { endIndex = sibling.endIndex; } diff --git a/packages/cursorless-engine/src/languages/ruby.ts b/packages/cursorless-engine/src/languages/ruby.ts index ff1cc3362e..e7a4278bde 100644 --- a/packages/cursorless-engine/src/languages/ruby.ts +++ b/packages/cursorless-engine/src/languages/ruby.ts @@ -92,15 +92,21 @@ const EXPRESSION_TYPES = [ ]; const EXPRESSION_STATEMENT_PARENT_TYPES = [ + "begin_block", "begin", + "block_body", "block", - "do", + "body_statement", "do_block", + "do", "else", + "end_block", "ensure", "heredoc_beginning", + "interpolation", "lambda", "method", + "parenthesized_statements", "program", "singleton_class", "singleton_method", diff --git a/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts b/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts index bdea535cb6..c9ca6f8a24 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/delimiterMaps.ts @@ -44,6 +44,14 @@ const delimiterToTextOverrides: Record> = { ['"', "]]"], ], }, + + python: { + // FIXME: We technically can't distinguish between single and double quotes + // now, but we'll revisit all this; see + // https://github.com/cursorless-dev/cursorless/issues/1812#issuecomment-1691493746 + singleQuotes: ["string_start", "string_end"], + doubleQuotes: ["string_start", "string_end"], + }, }; export const leftToRightMap: Record = Object.fromEntries( diff --git a/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts b/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts index 8ea522c6d7..90d2511711 100644 --- a/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts +++ b/packages/cursorless-engine/src/processTargets/modifiers/surroundingPair/findSurroundingPairParseTreeBased.ts @@ -183,7 +183,7 @@ function findSurroundingPairContainedInNode( */ const possibleDelimiterNodes = node .descendantsOfType(individualDelimiters.map(({ text }) => text)) - .filter((node) => !(node.text === "" && node.hasError())); + .filter((node) => !(node.text === "" && node.hasError)); /** * A list of all delimiter occurrences, generated from the delimiter nodes. diff --git a/packages/cursorless-engine/src/util/treeSitterUtils.ts b/packages/cursorless-engine/src/util/treeSitterUtils.ts index 33f27248af..6b54bebb17 100644 --- a/packages/cursorless-engine/src/util/treeSitterUtils.ts +++ b/packages/cursorless-engine/src/util/treeSitterUtils.ts @@ -27,8 +27,8 @@ export function getChildNodesForFieldName( let hasNext = true; while (hasNext) { - if (treeCursor.currentFieldName() === fieldName) { - ret.push(treeCursor.currentNode()); + if (treeCursor.currentFieldName === fieldName) { + ret.push(treeCursor.currentNode); } hasNext = treeCursor.gotoNextSibling(); diff --git a/queries/cpp.scm b/queries/cpp.scm index 47945137c0..de5f22ba65 100644 --- a/queries/cpp.scm +++ b/queries/cpp.scm @@ -35,20 +35,19 @@ (function_definition declarator: (_ declarator: (_ - namespace: (_) @className + scope: (_) @className ) ) ) @_.domain (lambda_expression) @anonymousFunction -(attribute) @attribute +(attribute_declaration) @attribute ;; > curl https://raw.githubusercontent.com/tree-sitter/tree-sitter-cpp/master/src/node-types.json | jq '[.[] | select(.type == "_type_specifier") | .subtypes[].type]' [ (auto) (decltype) (dependent_type) - (scoped_type_identifier) (template_type) ] @type diff --git a/queries/javascript.function.scm b/queries/javascript.function.scm index bb8ac92f88..b16a01ca7e 100644 --- a/queries/javascript.function.scm +++ b/queries/javascript.function.scm @@ -1,7 +1,7 @@ ;; Anonymous functions [ ;;!! function() {} - (function + (function_expression !name ) @@ -19,7 +19,7 @@ (export_statement [ ;;!! export default function() {} - (function + (function_expression !name ) @@ -53,7 +53,7 @@ (variable_declarator name: (_) @functionName value: [ - (function + (function_expression !name ) (generator_function @@ -73,7 +73,7 @@ (variable_declarator name: (_) @functionName value: [ - (function + (function_expression !name ) (generator_function @@ -107,7 +107,7 @@ (variable_declarator name: (_) @functionName value: [ - (function + (function_expression !name ) (generator_function @@ -126,7 +126,7 @@ ;; see javascript.scm. [ ;;!! (function foo() {}) - (function + (function_expression name: (_) @functionName ) @@ -147,7 +147,7 @@ (assignment_expression left: (_) @functionName right: [ - (function + (function_expression !name ) (generator_function diff --git a/queries/javascript.jsx.scm b/queries/javascript.jsx.scm index 9424c13e6a..adcf86a59e 100644 --- a/queries/javascript.jsx.scm +++ b/queries/javascript.jsx.scm @@ -31,56 +31,28 @@ (#allow-multiple! @xmlBothTags) ) @_.domain -;;!! -(jsx_self_closing_element) @xmlElement - -;; ======== JSX fragments, eg <>foo ========== - -;;!! <>foo -;;! ^^^^^^^^ -;;! ### -;;! *** -( - (jsx_fragment) @xmlElement @_.interior @_.iteration - (#child-range! @_.interior 1 -3 true true) - (#child-range! @_.iteration 1 -3 true true) -) - -;;!! <>foo -;;! *** -( - (jsx_fragment) @xmlStartTag.iteration @xmlEndTag.iteration @xmlBothTags.iteration - (#child-range! @xmlStartTag.iteration 1 -3 true true) - (#child-range! @xmlEndTag.iteration 1 -3 true true) - (#child-range! @xmlBothTags.iteration 1 -3 true true) -) - -;;!! <>foo -;;! ^^------ -( - (jsx_fragment) @xmlStartTag @xmlBothTags @_.domain - (#child-range! @xmlStartTag 0 1) - (#child-range! @xmlBothTags 0 1) - (#allow-multiple! @xmlBothTags) -) +;; Defines `name` scope for JSX fragment opening element +;;!! <> +;;! {} +;;! -- +(jsx_opening_element + "<" @name.start.endOf + . + ">" @name.end.startOf +) @_.domain -;;!! <>foo -;;! -----^^^ -( - (jsx_fragment) @xmlEndTag @xmlBothTags @_.domain - (#child-range! @xmlEndTag -3) - (#child-range! @xmlBothTags -3) - (#allow-multiple! @xmlBothTags) -) +;; Defines `name` scope for JSX fragment closing element +;;!! <> +;;! {} +;;! --- +(jsx_closing_element + "" @name.end.startOf +) @_.domain -;; Sets `name` to be empty range inside the fragment tag: -;;!! <>foo -;;! {} {} -;;! -- --- -(jsx_fragment - "<" @_.domain.start - ">" @name.startOf @_.domain.end -) +;;!! +(jsx_self_closing_element) @xmlElement ;;!! ;;! ^^^^^^^^^ @@ -106,7 +78,7 @@ ;;! ^^^^ (jsx_self_closing_element "<" @attribute.iteration.start.endOf @collectionKey.iteration.start.endOf @value.iteration.start.endOf - "/" @attribute.iteration.end.startOf @collectionKey.iteration.end.startOf @value.iteration.end.startOf + "/>" @attribute.iteration.end.startOf @collectionKey.iteration.end.startOf @value.iteration.end.startOf ) ;;!! diff --git a/queries/javascript.scm b/queries/javascript.scm index bc0e80d126..2a5e0618a7 100644 --- a/queries/javascript.scm +++ b/queries/javascript.scm @@ -18,7 +18,7 @@ (field_definition property: (_) @functionName value: [ - (function + (function_expression !name ) (generator_function diff --git a/queries/php.scm b/queries/php.scm index 6de382a5b4..18847739cc 100644 --- a/queries/php.scm +++ b/queries/php.scm @@ -33,9 +33,31 @@ ] @statement [ - (string) (shell_command_expression) -] @string @textFragment + (string) + (encapsed_string) +] @string + +(string + . + "'" @textFragment.start.endOf + "'" @textFragment.end.startOf + . +) + +(encapsed_string + . + "\"" @textFragment.start.endOf + "\"" @textFragment.end.startOf + . +) + +(shell_command_expression + . + "`" @textFragment.start.endOf + "`" @textFragment.end.startOf + . +) (comment) @comment @textFragment diff --git a/queries/python.scm b/queries/python.scm index 6fcd1c6659..4c0f412465 100644 --- a/queries/python.scm +++ b/queries/python.scm @@ -262,8 +262,8 @@ (comment) @comment @textFragment (string - _ @textFragment.start.endOf - _ @textFragment.end.startOf + (string_start) @textFragment.start.endOf + (string_end) @textFragment.end.startOf ) @string [ @@ -387,10 +387,10 @@ condition: (_) @condition ) @_.domain -;;!! match value: +;;!! case value: ;;! ^^^^^ (case_clause - pattern: (_) @condition.start + (case_pattern) @condition.start guard: (_)? @condition.end ) @_.domain @@ -477,7 +477,10 @@ ;;!! except: pass ;;! ^^^^^^^^^^^^ -(except_clause) @branch +[ + (except_clause) + (except_group_clause) +] @branch ;;!! finally: pass ;;! ^^^^^^^^^^^^^ diff --git a/queries/ruby.scm b/queries/ruby.scm index bcd45123e9..d9a83ed8c1 100644 --- a/queries/ruby.scm +++ b/queries/ruby.scm @@ -13,22 +13,22 @@ (if) @ifStatement ) @_.iteration -(_ - [ - (method) - (singleton_method) - ] @namedFunction -) @_.iteration +[ + (method) + (singleton_method) +] @namedFunction -(_ - (class) @class -) @_.iteration +(class) @class -(_ - (class - name: (_) @className - ) @_.domain -) @_.iteration +(class) @namedFunction.iteration @class.iteration +(program) @namedFunction.iteration @class.iteration @className.iteration + +(class) @functionName.iteration @name.iteration +(program) @functionName.iteration @name.iteration + +(class + name: (_) @className @name +) @_.domain (string) @string @@ -37,10 +37,6 @@ (heredoc_content) ] @textFragment -(class - name: (_) @name -) @_.domain - (method name: (_) @functionName @name ) @_.domain diff --git a/queries/typescript.core.scm b/queries/typescript.core.scm index 91eacbba6b..d7614aea7b 100644 --- a/queries/typescript.core.scm +++ b/queries/typescript.core.scm @@ -44,7 +44,7 @@ (public_field_definition name: (_) @functionName value: [ - (function + (function_expression !name ) (generator_function @@ -257,6 +257,15 @@ (_) @type ) @_.domain +;;!! aaa as const +;;! ^^^ +;;! xxxxxxx +;;! ---------- +(as_expression + (_) @_.leading.endOf + "const" @type +) @_.domain + ;;!! aaa satisfies Bbb ;;! ^^^ ;;! xxxxxxxxxxxxxx diff --git a/typings/treeSitter.d.ts b/typings/treeSitter.d.ts index 598ce2edba..6199d33508 100644 --- a/typings/treeSitter.d.ts +++ b/typings/treeSitter.d.ts @@ -1,21 +1,28 @@ -// From https://github.com/tree-sitter/tree-sitter/blob/2923c9cb62c964371ed7d6995ca1238356b00b45/lib/binding_web/tree-sitter-web.d.ts -// License https://github.com/tree-sitter/tree-sitter/blob/2923c9cb62c964371ed7d6995ca1238356b00b45/LICENSE +// From https://github.com/tree-sitter/tree-sitter/blob/604d38e6b327ed33877e1285680b505b9484a71c/lib/binding_web/tree-sitter-web.d.ts +// License https://github.com/tree-sitter/tree-sitter/blob/604d38e6b327ed33877e1285680b505b9484a71c/LICENSE declare module "web-tree-sitter" { class Parser { - static init(): Promise; + /** + * + * @param moduleOptions Optional emscripten module-object, see https://emscripten.org/docs/api_reference/module.html + */ + static init(moduleOptions?: object): Promise; delete(): void; parse( input: string | Parser.Input, - previousTree?: Parser.Tree, + oldTree?: Parser.Tree, options?: Parser.Options, ): Parser.Tree; - getLanguage(): any; - setLanguage(language: any): void; + getIncludedRanges(): Parser.Range[]; + getTimeoutMicros(): number; + setTimeoutMicros(timeout: number): void; + reset(): void; + getLanguage(): Parser.Language; + setLanguage(language?: Parser.Language | null): void; getLogger(): Parser.Logger; - setLogger(logFunc: Parser.Logger): void; + setLogger(logFunc?: Parser.Logger | false | null): void; } - // eslint-disable-next-line @typescript-eslint/no-namespace namespace Parser { export type Options = { includedRanges?: Range[]; @@ -27,10 +34,10 @@ declare module "web-tree-sitter" { }; export type Range = { - startPosition: Point; - endPosition: Point; startIndex: number; endIndex: number; + startPosition: Point; + endPosition: Point; }; export type Edit = { @@ -48,17 +55,26 @@ declare module "web-tree-sitter" { type: "parse" | "lex", ) => void; - export type Input = ( - startIndex: number, - startPoint?: Point, - endIndex?: number, - ) => string | null; + export interface Input { + (index: number, position?: Point): string | null; + } export interface SyntaxNode { - id: number; tree: Tree; + id: number; + typeId: number; + grammarId: number; type: string; + grammarType: string; + isNamed: boolean; + isMissing: boolean; + isExtra: boolean; + hasChanges: boolean; + hasError: boolean; + isError: boolean; text: string; + parseState: number; + nextParseState: number; startPosition: Point; endPosition: Point; startIndex: number; @@ -76,25 +92,22 @@ declare module "web-tree-sitter" { nextNamedSibling: SyntaxNode | null; previousSibling: SyntaxNode | null; previousNamedSibling: SyntaxNode | null; + descendantCount: number; - hasChanges(): boolean; - hasError(): boolean; equals(other: SyntaxNode): boolean; - isMissing(): boolean; - isNamed(): boolean; toString(): string; child(index: number): SyntaxNode | null; namedChild(index: number): SyntaxNode | null; - childForFieldId(fieldId: number): SyntaxNode | null; childForFieldName(fieldName: string): SyntaxNode | null; + childForFieldId(fieldId: number): SyntaxNode | null; + fieldNameForChild(childIndex: number): string | null; + childrenForFieldName(fieldName: string): Array; + childrenForFieldId(fieldId: number): Array; + firstChildForIndex(index: number): SyntaxNode | null; + firstNamedChildForIndex(index: number): SyntaxNode | null; descendantForIndex(index: number): SyntaxNode; descendantForIndex(startIndex: number, endIndex: number): SyntaxNode; - descendantsOfType( - type: string | Array, - startPosition?: Point, - endPosition?: Point, - ): Array; namedDescendantForIndex(index: number): SyntaxNode; namedDescendantForIndex(startIndex: number, endIndex: number): SyntaxNode; descendantForPosition(position: Point): SyntaxNode; @@ -107,69 +120,83 @@ declare module "web-tree-sitter" { startPosition: Point, endPosition: Point, ): SyntaxNode; + descendantsOfType( + types: string | Array, + startPosition?: Point, + endPosition?: Point, + ): Array; walk(): TreeCursor; } export interface TreeCursor { nodeType: string; + nodeTypeId: number; + nodeStateId: number; nodeText: string; + nodeId: number; nodeIsNamed: boolean; + nodeIsMissing: boolean; startPosition: Point; endPosition: Point; startIndex: number; endIndex: number; + readonly currentNode: SyntaxNode; + readonly currentFieldName: string; + readonly currentFieldId: number; + readonly currentDepth: number; + readonly currentDescendantIndex: number; reset(node: SyntaxNode): void; + resetTo(cursor: TreeCursor): void; delete(): void; - currentNode(): SyntaxNode; - currentFieldId(): number; - currentFieldName(): string; gotoParent(): boolean; gotoFirstChild(): boolean; - gotoFirstChildForIndex(index: number): boolean; + gotoLastChild(): boolean; + gotoFirstChildForIndex(goalIndex: number): boolean; + gotoFirstChildForPosition(goalPosition: Point): boolean; gotoNextSibling(): boolean; + gotoPreviousSibling(): boolean; + gotoDescendant(goalDescendantIndex: number): void; } export interface Tree { readonly rootNode: SyntaxNode; + rootNodeWithOffset(offsetBytes: number, offsetExtent: Point): SyntaxNode; copy(): Tree; delete(): void; - edit(delta: Edit): Tree; + edit(edit: Edit): Tree; walk(): TreeCursor; getChangedRanges(other: Tree): Range[]; + getIncludedRanges(): Range[]; getEditedRange(other: Tree): Range; getLanguage(): Language; } - class Language { - static load(input: string | Uint8Array): Promise; - - readonly version: number; - readonly fieldCount: number; - readonly nodeTypeCount: number; - - fieldNameForId(fieldId: number): string | null; - fieldIdForName(fieldName: string): number | null; - idForNodeType(type: string, named: boolean): number; - nodeTypeForId(typeId: number): string | null; - nodeTypeIsNamed(typeId: number): boolean; - nodeTypeIsVisible(typeId: number): boolean; - query(source: string): Query; - } - export interface QueryCapture { name: string; + text?: string; node: SyntaxNode; + setProperties?: { [prop: string]: string | null }; + assertedProperties?: { [prop: string]: string | null }; + refutedProperties?: { [prop: string]: string | null }; } - interface QueryMatch { + export interface QueryMatch { pattern: number; captures: QueryCapture[]; - setProperties?: Record; } + export type QueryOptions = { + startPosition?: Point; + endPosition?: Point; + startIndex?: number; + endIndex?: number; + matchLimit?: number; + maxStartDepth?: number; + }; + interface PredicateResult { operator: string; operands: PredicateOperand[]; @@ -187,22 +214,55 @@ declare module "web-tree-sitter" { type PredicateOperand = PredicateCaptureOperand | PredicateStringOperand; - class Query { + export class Query { captureNames: string[]; + readonly predicates: PredicateResult[][]; + readonly setProperties: any[]; + readonly assertedProperties: any[]; + readonly refutedProperties: any[]; + readonly matchLimit: number; delete(): void; - matches( - node: SyntaxNode, - startPosition?: Point, - endPosition?: Point, - ): QueryMatch[]; - captures( - node: SyntaxNode, - startPosition?: Point, - endPosition?: Point, - ): QueryCapture[]; + captures(node: SyntaxNode, options?: QueryOptions): QueryCapture[]; + matches(node: SyntaxNode, options?: QueryOptions): QueryMatch[]; predicatesForPattern(patternIndex: number): PredicateResult[]; - predicates: PredicateResult[][]; + disableCapture(captureName: string): void; + disablePattern(patternIndex: number): void; + isPatternGuaranteedAtStep(byteOffset: number): boolean; + isPatternRooted(patternIndex: number): boolean; + isPatternNonLocal(patternIndex: number): boolean; + startIndexForPattern(patternIndex: number): number; + didExceedMatchLimit(): boolean; + } + + class Language { + static load(input: string | Uint8Array): Promise; + + readonly version: number; + readonly fieldCount: number; + readonly stateCount: number; + readonly nodeTypeCount: number; + + fieldNameForId(fieldId: number): string | null; + fieldIdForName(fieldName: string): number | null; + idForNodeType(type: string, named: boolean): number; + nodeTypeForId(typeId: number): string | null; + nodeTypeIsNamed(typeId: number): boolean; + nodeTypeIsVisible(typeId: number): boolean; + nextState(stateId: number, typeId: number): number; + query(source: string): Query; + lookaheadIterator(stateId: number): LookaheadIterable | null; + } + + export class LookaheadIterable { + readonly language: Language; + readonly currentTypeId: number; + readonly currentType: string; + + delete(): void; + reset(language: Language, stateId: number): boolean; + resetState(stateId: number): boolean; + [Symbol.iterator](): Iterator; } }