dsherret / dsherret/ts-morph

ts-morph incorrectly transforms nodes which begin with whitespace

Open
#1,591 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
6.2k
Forks
238
Avg merge
2m
Merged PRs (30d)
1

Description

if you have a node such as:

```
Foo is great
```

and you do a transform:

```
node.transform((traversal) => {
if (ts.isJsxText(traversal.currentNode) && traversal.currentNode.text != 'Foo'){
return traversal.factory.createJsxText(' is NOT great', false);
} else {
return traversal.visitChildren();
}
});
```

the result should be:

```
Foo is NOT great
```

but it is:

```
Foo is NOT great
```

instead. Notice how an extra space was added. This is due to the following error in the code:

```
function handleTransformation(oldNode, newNode) {
if (oldNode === newNode && newNode.emitNode == null)
return;
const start = oldNode.getStart(compilerSourceFile, true); //This is the error: start should be oldNode.pos which correctly accounts for whitespace
const end = oldNode.end;
let lastTransformation;
while ((lastTransformation = transformations[transformations.length - 1]) && lastTransformation.start > start)
transformations.pop();
const wrappedNode = compilerFactory.getExistingNodeFromCompilerNode(oldNode);
transformations.push({
start,
end,
compilerNode: newNode,
});
if (wrappedNode != null) {
if (oldNode.kind !== newNode.kind)
wrappedNode.forget();
else
wrappedNode.forgetDescendants();
}
}
```

As I noted in the comment, it is using an incorrect way of getting the start of the node and should be using .pos.

Contributor guide

Open the contributing guide

Research direction

Locate the handleTransformation function in the ts-morph transformation code and inspect how it calculates the node start when leading whitespace is present. Update the start position handling as described, then verify that transforming the nested JSX example produces one space before "is NOT great" rather than two.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
tooling
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.