Skip to content

Commit

Permalink
Move replaceNode(s) to source/parser/util.civet
Browse files Browse the repository at this point in the history
  • Loading branch information
edemaine authored and zoodogood committed Nov 4, 2024
1 parent 675145a commit d5dddfd
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 67 deletions.
5 changes: 1 addition & 4 deletions source/parser/function.civet
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,6 @@ import {
getHelperRef
} from ./helper.civet

import {
replaceNode
} from ./lib.civet

import {
findAncestor
findChildIndex
Expand Down Expand Up @@ -74,6 +70,7 @@ import {
isWhitespaceOrEmpty
makeLeftHandSideExpression
makeNode
replaceNode
startsWithPredicate
trimFirstSpace
updateParentPointers
Expand Down
58 changes: 3 additions & 55 deletions source/parser/lib.civet
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ import {
inplaceInsertTrimmingSpace
inplacePrepend
insertTrimmingSpace
isASTNodeObject
isComma
isEmptyBareBlock
isFunction
Expand All @@ -77,6 +76,8 @@ import {
maybeUnwrap
parenthesizeType
prepend
replaceNode
replaceNodes
stripTrailingImplicitComma
trimFirstSpace
wrapIIFE
Expand Down Expand Up @@ -722,36 +723,6 @@ function processCallMemberExpression(node: CallExpression | MemberExpression): A
}
return node

/**
* Replace this node with another, by modifying its parent's children.
*/
function replaceNode(node: ASTNodeObject, newNode: ASTNode, parent?: ASTNodeParent): void
parent ??= node.parent
unless parent?
throw new Error "replaceNode failed: node has no parent"

function recurse(children: ASTNode[]): boolean
for each child, i of children
if child is node
children[i] = newNode
return true
else if Array.isArray child
return true if recurse child
return false

unless recurse parent.children
throw new Error "replaceNode failed: didn't find child node in parent"

// Adjust 'expression' etc. alias pointers
for key, value in parent
if value is node
parent[key] = newNode

if isASTNodeObject newNode
newNode.parent = parent
// Don't destroy node's parent, as we often include it within newNode
//node.parent = undefined

// Wrap expression in parentheses to make into a statement when:
// * object literal expression
// * anonymous function expression
Expand Down Expand Up @@ -1689,29 +1660,6 @@ function reorderBindingRestProperty(props)

return { children, names }

/**
* Replace all nodes that match predicate with replacer(node)
*/
function replaceNodes(root, predicate, replacer)
return root unless root?

array := Array.isArray(root) ? root : root.children

unless array
if predicate root
return replacer root, root
else
return root

for each node, i of array
return unless node?
if predicate node
array[i] = replacer node, root
else
replaceNodes node, predicate, replacer

return root

function typeOfJSX(node, config) {
switch (node.type) {
case "JSXElement":
Expand Down Expand Up @@ -1845,8 +1793,8 @@ export {
processUnaryExpression
processUnaryNestedExpression
quoteString
replaceNode
reorderBindingRestProperty
replaceNode
replaceNodes
skipImplicitArguments
stripTrailingImplicitComma
Expand Down
1 change: 1 addition & 0 deletions source/parser/op.civet
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {

import {
makeLeftHandSideExpression
replaceNode
trimFirstSpace
} from ./util.civet

Expand Down
5 changes: 1 addition & 4 deletions source/parser/pattern-matching.civet
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ import type {
SwitchStatement
} from ./types.civet

import {
replaceNode
} from ./lib.civet

import {
gatherRecursiveAll
} from ./traversal.civet
Expand All @@ -27,6 +23,7 @@ import {
isExit
makeLeftHandSideExpression
makeNode
replaceNode
updateParentPointers
} from ./util.civet

Expand Down
59 changes: 55 additions & 4 deletions source/parser/util.civet
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ import type {
StatementTuple
} from ./types.civet

import {
replaceNode
} from ./lib.civet

import {
gatherRecursiveWithinFunction
type Predicate
Expand Down Expand Up @@ -457,6 +453,59 @@ function deepCopy<T extends ASTNode>(root: T): T

copied.get node

/**
* Replace this node with another, by modifying its parent's children.
*/
function replaceNode(node: ASTNodeObject, newNode: ASTNode, parent?: ASTNodeParent): void
parent ??= node.parent
unless parent?
throw new Error "replaceNode failed: node has no parent"

function recurse(children: ASTNode[]): boolean
for each child, i of children
if child is node
children[i] = newNode
return true
else if Array.isArray child
return true if recurse child
return false

unless recurse parent.children
throw new Error "replaceNode failed: didn't find child node in parent"

// Adjust 'expression' etc. alias pointers
for key, value in parent
if value is node
parent[key] = newNode

if isASTNodeObject newNode
newNode.parent = parent
// Don't destroy node's parent, as we often include it within newNode
//node.parent = undefined

/**
* Replace all nodes that match predicate with replacer(node)
*/
function replaceNodes(root, predicate, replacer)
return root unless root?

array := Array.isArray(root) ? root : root.children

unless array
if predicate root
return replacer root, root
else
return root

for each node, i of array
return unless node?
if predicate node
array[i] = replacer node, root
else
replaceNodes node, predicate, replacer

return root

/**
* When cloning subtrees sometimes we need to remove hoistDecs
*/
Expand Down Expand Up @@ -786,6 +835,8 @@ export {
prepend
removeHoistDecs
removeParentPointers
replaceNode
replaceNodes
skipIfOnlyWS
startsWith
startsWithPredicate
Expand Down

0 comments on commit d5dddfd

Please sign in to comment.