Fix finding path to node for import and if-else (#4483)
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
import { parse, recast, initPromise, PathToNode } from './wasm'
|
import { parse, recast, initPromise, PathToNode, Identifier } from './wasm'
|
||||||
import {
|
import {
|
||||||
findAllPreviousVariables,
|
findAllPreviousVariables,
|
||||||
isNodeSafeToReplace,
|
isNodeSafeToReplace,
|
||||||
@ -10,6 +10,7 @@ import {
|
|||||||
hasSketchPipeBeenExtruded,
|
hasSketchPipeBeenExtruded,
|
||||||
doesSceneHaveSweepableSketch,
|
doesSceneHaveSweepableSketch,
|
||||||
traverse,
|
traverse,
|
||||||
|
getNodeFromPath,
|
||||||
} from './queryAst'
|
} from './queryAst'
|
||||||
import { enginelessExecutor } from '../lib/testHelpers'
|
import { enginelessExecutor } from '../lib/testHelpers'
|
||||||
import {
|
import {
|
||||||
@ -266,6 +267,86 @@ describe('testing getNodePathFromSourceRange', () => {
|
|||||||
])
|
])
|
||||||
expect(selectWholeThing).toEqual(expected)
|
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', () => {
|
describe('testing doesPipeHave', () => {
|
||||||
|
@ -317,6 +317,62 @@ function moreNodePathFromSourceRange(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_node.type === 'PipeSubstitution' && isInRange) return path
|
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)
|
console.error('not implemented: ' + node.type)
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
Reference in New Issue
Block a user