dsherret / ts-morph

TypeScript Compiler API wrapper for static analysis and programmatic code changes.
https://ts-morph.com
MIT License
5.03k stars 196 forks source link

getBodyText() doesn't work as would be expected #1559

Closed jmyrick02 closed 1 month ago

jmyrick02 commented 4 months ago

Describe the bug

There are two issues I'd like to discuss here. One is objectively a bug, while the other is more opinionated.

The first issue (the definite bug) is how getBodyTextWithoutLeadingIndentation() handles a line that only contains indentation (spaces/tabs). It will cause bad output as I will outline below.

The second issue (more opinionated) is that empty lines in a method body cause getBodyText() to not remove any indentation at all. This is how I found this issue, since I'm trying to print method bodies at a standard indentation level, but whenever the body contains an empty line, it causes the method to be displayed much more indented than otherwise. I'll give an example below.

I do have a fix for these two issues working locally with tests, so I'll contribute those in a PR after submitting this issue.

Version: 23.0.0

To Reproduce

In the section Issue 1, the output log statement has the two console.log() statements at differing indentation levels, when they should be at the same indentation level. I have a fix for this issue that I will submit a PR for.

The section Issue 2, the output is the same, but I would prefer empty lines to be ignored. I think this makes sense since a single empty line in a method body shouldn't affect the whole indentation level of the body text in my opinion. I also have a fix for this behavior in the PR I will submit.

import { Project } from "ts-morph";

// Issue #1

const project = new Project();
let sourceFile = project.createSourceFile("test.ts", `function foo() {\n  console.log()\n  \n  console.log()\n}`);

// reproduce the problem here
let foo = sourceFile.getFunction("foo");
// we expect the two console.log() statements to be at the same indentation level
console.log(foo?.getBodyText());

// Issue #2
sourceFile = project.createSourceFile("test2.ts", `function foo() {\n  console.log()\n\n  console.log()\n}`);

// reproduce the problem here
foo = sourceFile.getFunction("foo");
// my preference for behavior would be for the new line without any indentation to not affect the output and remove the indentation as if the line didn't exist in the method
console.log(foo?.getBodyText());

Expected behavior

In case 1, I expect the two console log statements to have the same indentation level, that of 0 since the minimum indentation level in the method body is 1 and all lines have that indentation level.

In case 2, I would prefer an empty line to be ignored, though this is more opinionated, but I think it makes sense for use cases I can imagine, and especially for my use case.