Skip to content

Commit

Permalink
Fix finding path to node for import and if-else (#4483)
Browse files Browse the repository at this point in the history
  • Loading branch information
jtran authored Nov 17, 2024
1 parent 05f4f34 commit b2e895e
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 1 deletion.
83 changes: 82 additions & 1 deletion src/lang/queryAst.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { parse, recast, initPromise, PathToNode } from './wasm'
import { parse, recast, initPromise, PathToNode, Identifier } from './wasm'
import {
findAllPreviousVariables,
isNodeSafeToReplace,
Expand All @@ -10,6 +10,7 @@ import {
hasSketchPipeBeenExtruded,
doesSceneHaveSweepableSketch,
traverse,
getNodeFromPath,
} from './queryAst'
import { enginelessExecutor } from '../lib/testHelpers'
import {
Expand Down Expand Up @@ -266,6 +267,86 @@ describe('testing getNodePathFromSourceRange', () => {
])
expect(selectWholeThing).toEqual(expected)
})

it('finds the node in if-else condition', () => {
const code = `y = 0
x = if x > y {
x + 1
} else {
y
}`
const searchLn = `x > y`
const sourceIndex = code.indexOf(searchLn)
const ast = parse(code)
if (err(ast)) throw ast

const result = getNodePathFromSourceRange(ast, [sourceIndex, sourceIndex])
expect(result).toEqual([
['body', ''],
[1, 'index'],
['declarations', 'VariableDeclaration'],
[0, 'index'],
['init', ''],
['cond', 'IfExpression'],
['left', 'BinaryExpression'],
])
const _node = getNodeFromPath<Identifier>(ast, result)
if (err(_node)) throw _node
expect(_node.node.type).toEqual('Identifier')
expect(_node.node.name).toEqual('x')
})

it('finds the node in if-else then', () => {
const code = `y = 0
x = if x > y {
x + 1
} else {
y
}`
const searchLn = `x + 1`
const sourceIndex = code.indexOf(searchLn)
const ast = parse(code)
if (err(ast)) throw ast

const result = getNodePathFromSourceRange(ast, [sourceIndex, sourceIndex])
expect(result).toEqual([
['body', ''],
[1, 'index'],
['declarations', 'VariableDeclaration'],
[0, 'index'],
['init', ''],
['then_val', 'IfExpression'],
['body', 'IfExpression'],
[0, 'index'],
['expression', 'ExpressionStatement'],
['left', 'BinaryExpression'],
])
const _node = getNodeFromPath<Identifier>(ast, result)
if (err(_node)) throw _node
expect(_node.node.type).toEqual('Identifier')
expect(_node.node.name).toEqual('x')
})

it('finds the node in import statement item', () => {
const code = `import foo, bar as baz from 'thing.kcl'`
const searchLn = `bar`
const sourceIndex = code.indexOf(searchLn)
const ast = parse(code)
if (err(ast)) throw ast

const result = getNodePathFromSourceRange(ast, [sourceIndex, sourceIndex])
expect(result).toEqual([
['body', ''],
[0, 'index'],
['items', 'ImportStatement'],
[1, 'index'],
['name', 'ImportItem'],
])
const _node = getNodeFromPath<Identifier>(ast, result)
if (err(_node)) throw _node
expect(_node.node.type).toEqual('Identifier')
expect(_node.node.name).toEqual('bar')
})
})

describe('testing doesPipeHave', () => {
Expand Down
56 changes: 56 additions & 0 deletions src/lang/queryAst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,62 @@ function moreNodePathFromSourceRange(
}

if (_node.type === 'PipeSubstitution' && isInRange) return path

if (_node.type === 'IfExpression' && isInRange) {
const { cond, then_val, else_ifs, final_else } = _node
if (cond.start <= start && cond.end >= end) {
path.push(['cond', 'IfExpression'])
return moreNodePathFromSourceRange(cond, sourceRange, path)
}
if (then_val.start <= start && then_val.end >= end) {
path.push(['then_val', 'IfExpression'])
path.push(['body', 'IfExpression'])
return getNodePathFromSourceRange(then_val, sourceRange, path)
}
for (let i = 0; i < else_ifs.length; i++) {
const else_if = else_ifs[i]
if (else_if.start <= start && else_if.end >= end) {
path.push(['else_ifs', 'IfExpression'])
path.push([i, 'index'])
const { cond, then_val } = else_if
if (cond.start <= start && cond.end >= end) {
path.push(['cond', 'IfExpression'])
return moreNodePathFromSourceRange(cond, sourceRange, path)
}
path.push(['then_val', 'IfExpression'])
path.push(['body', 'IfExpression'])
return getNodePathFromSourceRange(then_val, sourceRange, path)
}
}
if (final_else.start <= start && final_else.end >= end) {
path.push(['final_else', 'IfExpression'])
path.push(['body', 'IfExpression'])
return getNodePathFromSourceRange(final_else, sourceRange, path)
}
return path
}

if (_node.type === 'ImportStatement' && isInRange) {
const { items } = _node
for (let i = 0; i < items.length; i++) {
const item = items[i]
if (item.start <= start && item.end >= end) {
path.push(['items', 'ImportStatement'])
path.push([i, 'index'])
if (item.name.start <= start && item.name.end >= end) {
path.push(['name', 'ImportItem'])
return path
}
if (item.alias && item.alias.start <= start && item.alias.end >= end) {
path.push(['alias', 'ImportItem'])
return path
}
return path
}
}
return path
}

console.error('not implemented: ' + node.type)

return path
Expand Down

0 comments on commit b2e895e

Please sign in to comment.