rewrite icon indicating copy to clipboard operation
rewrite copied to clipboard

HCL Parser loses newlines in empty object values

Open rmadamanchi opened this issue 3 years ago • 1 comments

Below is a test case to demonstrate the issue:

import org.junit.jupiter.api.Test
import org.openrewrite.InMemoryExecutionContext
import org.openrewrite.hcl.HclParser
import org.openrewrite.hcl.tree.Hcl.ConfigFile
import java.util.function.Consumer
import kotlin.test.assertEquals

class ParserTest {
    @Test
    fun test() {
        val parser = HclParser.builder().build()

        val source = """
            locals {
              myvar = {
            
              }
            }
        """.trimIndent()

        val ctx = InMemoryExecutionContext(Consumer { t: Throwable -> throw t })
        val sources = parser.parse(ctx, source)
        assertEquals(source, (sources[0] as ConfigFile).printAll())
    }
}

The printed output loses the newlines in empty object value:

locals {
  myvar = {}
}

rmadamanchi avatar Jul 28 '22 18:07 rmadamanchi

Hi. I noticed similar behavior for a multiline empty array declaration. Please see example below:

import org.junit.jupiter.api.Test;
import org.openrewrite.ExecutionContext;
import org.openrewrite.InMemoryExecutionContext;
import org.openrewrite.ParseExceptionResult;
import org.openrewrite.Parser;
import org.openrewrite.SourceFile;
import org.openrewrite.hcl.HclParser;
import org.openrewrite.marker.Marker;

import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class HclParserTest {
    @Test
    void test() {
        Parser parser = HclParser.builder().build();

        String source = """
              myvar = [
              ]
        """;

        ExecutionContext ctx = new InMemoryExecutionContext();
        Optional<SourceFile> possibleParseResult = parser.parse(ctx, source).findFirst();
        assertTrue(possibleParseResult.isPresent());
        SourceFile parseResult = possibleParseResult.get();
        List<Marker> markers = parseResult.getMarkers().getMarkers();
        assertEquals(1, markers.size());
        Marker marker = markers.get(0);
        assertTrue(marker instanceof ParseExceptionResult);
        String message = ((ParseExceptionResult)marker).getMessage();
        assertTrue(message.contains("java.lang.IllegalStateException"));
        assertTrue(message.contains("is not print idempotent."));
        assertTrue(message.contains("-      myvar = [\n-      ]\n+      myvar = []"));

        assertEquals(source, parseResult.printAll());
    }
}

In my case, it also causes java.lang.IllegalStateException: terraform/<filename>.tfvars is not print idempotent being thrown while validating tree before transformation.

knaumchuk avatar Apr 08 '25 10:04 knaumchuk

Potential fix in

  • https://github.com/openrewrite/rewrite/pull/5854

timtebeek avatar Aug 04 '25 10:08 timtebeek