From b54ac4a6943361adcc3e141fd3a0c8aee0f004a2 Mon Sep 17 00:00:00 2001 From: Kurt Hutten Date: Thu, 21 Sep 2023 15:40:41 +1000 Subject: [PATCH] improve getNodePathFromSourceRange and therefore the ast explorer aswell (#683) improve getNodePathFromSourceRange and therefore the ast explorer as well --- src/lang/getNodePathFromSourceRange.test.ts | 78 +++++++++++++++++++++ src/lang/queryAst.ts | 24 ++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/lang/getNodePathFromSourceRange.test.ts b/src/lang/getNodePathFromSourceRange.test.ts index 4ec6b78d4..0e837ab0e 100644 --- a/src/lang/getNodePathFromSourceRange.test.ts +++ b/src/lang/getNodePathFromSourceRange.test.ts @@ -1,6 +1,7 @@ import { getNodePathFromSourceRange, getNodeFromPath } from './queryAst' import { parser_wasm } from './abstractSyntaxTree' import { initPromise } from './rust' +import { Identifier } from './abstractSyntaxTreeTypes' beforeAll(() => initPromise) @@ -27,4 +28,81 @@ const sk3 = startSketchAt([0, 0]) expect([node.start, node.end]).toEqual(sourceRange) expect(node.type).toBe('CallExpression') }) + it('gets path right for function definition params', () => { + const code = `fn cube = (pos, scale) => { + const sg = startSketchAt(pos) + |> line([0, scale], %) + |> line([scale, 0], %) + |> line([0, -scale], %) + + return sg +} + +const b1 = cube([0,0], 10)` + const subStr = 'pos, scale' + const subStrIndex = code.indexOf(subStr) + const sourceRange: [number, number] = [ + subStrIndex, + subStrIndex + 'pos'.length, + ] + + const ast = parser_wasm(code) + const nodePath = getNodePathFromSourceRange(ast, sourceRange) + const node = getNodeFromPath(ast, nodePath).node + + expect(nodePath).toEqual([ + ['body', ''], + [0, 'index'], + ['declarations', 'VariableDeclaration'], + [0, 'index'], + ['init', ''], + ['params', 'FunctionExpression'], + [0, 'index'], + ]) + expect(node.type).toBe('Identifier') + expect(node.name).toBe('pos') + }) + it('gets path right for deep within function definition body', () => { + const code = `fn cube = (pos, scale) => { + const sg = startSketchAt(pos) + |> line([0, scale], %) + |> line([scale, 0], %) + |> line([0, -scale], %) + + return sg +} + +const b1 = cube([0,0], 10)` + const subStr = 'scale, 0' + const subStrIndex = code.indexOf(subStr) + const sourceRange: [number, number] = [ + subStrIndex, + subStrIndex + 'scale'.length, + ] + + const ast = parser_wasm(code) + const nodePath = getNodePathFromSourceRange(ast, sourceRange) + const node = getNodeFromPath(ast, nodePath).node + expect(nodePath).toEqual([ + ['body', ''], + [0, 'index'], + ['declarations', 'VariableDeclaration'], + [0, 'index'], + ['init', ''], + ['body', 'FunctionExpression'], + ['body', 'FunctionExpression'], + [0, 'index'], + ['declarations', 'VariableDeclaration'], + [0, 'index'], + ['init', ''], + ['body', 'PipeExpression'], + [2, 'index'], + ['arguments', 'CallExpression'], + [0, 'index'], + ['elements', 'ArrayExpression'], + [0, 'index'], + ]) + expect(node.type).toBe('Identifier') + expect(node.name).toBe('scale') + }) }) diff --git a/src/lang/queryAst.ts b/src/lang/queryAst.ts index b86797a14..65de21fb4 100644 --- a/src/lang/queryAst.ts +++ b/src/lang/queryAst.ts @@ -239,7 +239,29 @@ function moreNodePathFromSourceRange( } return path } - console.error('not implemented') + if (_node.type === 'FunctionExpression' && isInRange) { + for (let i = 0; i < _node.params.length; i++) { + const param = _node.params[i] + if (param.start <= start && param.end >= end) { + path.push(['params', 'FunctionExpression']) + path.push([i, 'index']) + return moreNodePathFromSourceRange(param, sourceRange, path) + } + } + if (_node.body.start <= start && _node.body.end >= end) { + path.push(['body', 'FunctionExpression']) + const fnBody = _node.body.body + for (let i = 0; i < fnBody.length; i++) { + const statement = fnBody[i] + if (statement.start <= start && statement.end >= end) { + path.push(['body', 'FunctionExpression']) + path.push([i, 'index']) + return moreNodePathFromSourceRange(statement, sourceRange, path) + } + } + } + } + console.error('not implemented: ' + node.type) return path }