diff --git a/src/tree.ts b/src/tree.ts index 8e6d027..26ca82a 100644 --- a/src/tree.ts +++ b/src/tree.ts @@ -815,7 +815,7 @@ abstract class BaseNode implements SyntaxNode { } matchContext(context: readonly string[]): boolean { - return matchNodeContext(this, context) + return matchNodeContext(this.parent, context) } enterUnfinishedNodesBefore(pos: number) { @@ -935,8 +935,8 @@ function getChildren(node: SyntaxNode, type: string | number, before: string | n } } -function matchNodeContext(node: SyntaxNode, context: readonly string[], i = context.length - 1): boolean { - for (let p: SyntaxNode | null = node.parent; i >= 0; p = p.parent) { +function matchNodeContext(node: SyntaxNode | null, context: readonly string[], i = context.length - 1): boolean { + for (let p = node; i >= 0; p = p.parent) { if (!p) return false if (!p.type.isAnonymous) { if (context[i] && context[i] != p.name) return false @@ -1331,10 +1331,10 @@ export class TreeCursor implements SyntaxNodeRef { /// of direct parent node names. Empty strings in the context array /// are treated as wildcards. matchContext(context: readonly string[]): boolean { - if (!this.buffer) return matchNodeContext(this.node, context) + if (!this.buffer) return matchNodeContext(this.node.parent, context) let {buffer} = this.buffer, {types} = buffer.set for (let i = context.length - 1, d = this.stack.length - 1; i >= 0; d--) { - if (d < 0) return matchNodeContext(this.node, context, i) + if (d < 0) return matchNodeContext(this._tree, context, i) let type = types[buffer.buffer[this.stack[d]]] if (!type.isAnonymous) { if (context[i] && context[i] != type.name) return false diff --git a/test/test-tree.ts b/test/test-tree.ts index bd5618d..77656c1 100644 --- a/test/test-tree.ts +++ b/test/test-tree.ts @@ -324,3 +324,23 @@ describe("TreeCursor", () => { ist(c.type, NodeType.none) }) }) + +describe("matchContext", () => { + it("can match on nodes", () => { + ist(simple().resolve(10, 1).matchContext(["T", "Pa", "Br"])) + }) + + it("can match wildcards", () => { + ist(simple().resolve(10, 1).matchContext(["T", "", "Br"])) + }) + + it("can mismatch on nodes", () => { + ist(!simple().resolve(10, 1).matchContext(["Q", "Br"])) + }) + + it("can match on cursor", () => { + let c = simple().cursor() + for (let i = 0; i < 3; i++) c.enter(15, -1) + ist(c.matchContext(["T", "Pa", "Br"])) + }) +})