Repository: domluna/JuliaFormatter.jl
Pull request #572 (2022-05-02 03:33:58)

Multiline comment corner case + better error message on formatted text error
Unfortunately it looks like the the position the error occurred is hard
to derive from CSTParser's ParseState so for now we'll at least number the
formatted output. Although without accurate line info I'm not sure how
helpful that actually is.

Example:

```julia
ERROR: Error while PARSING formatted text:

1 arraycopy_common(false, LLVM.Builder(B), orig, origops[1], gutils)#=fwd=#
2 return nothing

...

Error occurred on line 2, offset 1 of formatted text.

```

In slightly better news we've added a temporary measure to handle a
corner case of multi line comments being moved to the end of the Lines
which can apparently cause havoc for CSTParser. Luckily this can be
alleviated by prepending a single space prior to the comment. It's
pretty hacky but better than throwing an error for no good reason!

#571 


Patch:
diff --git a/Project.toml b/Project.toml
index 07d51d8f..3d320a66 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,7 +1,7 @@
 name = "JuliaFormatter"
 uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899"
 authors = ["Dominique Luna <dluna132@gmail.com>"]
-version = "0.22.8"
+version = "0.22.9"
 
 [deps]
 CSTParser = "00ebfdb7-1f24-5e51-bd34-a7502290713f"
diff --git a/src/JuliaFormatter.jl b/src/JuliaFormatter.jl
index 1751a7c5..e0d4b645 100644
--- a/src/JuliaFormatter.jl
+++ b/src/JuliaFormatter.jl
@@ -586,10 +586,26 @@ function format_text(cst::CSTParser.EXPR, style::AbstractStyle, s::State)
     text = normalize_line_ending(text, replacer)
 
     _, ps = CSTParser.parse(CSTParser.ParseState(text), true)
-    line, offset = ps.lt.endpos
-    ps.errored && error(
-        "Parsing error for formatted text:\n\n$text\n\n Error occurred on line $line, offset $offset.",
-    )
+    # TODO: This line info is not correct since it doesn't stop at the error.
+    # At the moment it doesn't seem there's a way to get the error line info.
+    # https://github.com/julia-vscode/CSTParser.jl/issues/335
+    line, offset = ps.lt.startpos
+    if ps.errored
+        buf = IOBuffer()
+        lines = split(text, '\n')
+        padding = ndigits(length(lines))
+        for (i, l) in enumerate(lines)
+            write(buf, "$i", repeat(" ", (padding - ndigits(i) + 1)), l, "\n")
+            if i == line
+                write(buf, "\n...")
+                break
+            end
+        end
+        error_text = String(take!(buf))
+        error(
+            "Error while PARSING formatted text:\n\n$error_text\n\nError occurred on line $line, offset $offset of formatted text.\n\nThe error might not be precisely on this line but it should be in the region of the code block. Try commenting the region out and see if that removes the error.",
+        )
+    end
     return text
 end
 
diff --git a/src/print.jl b/src/print.jl
index 38456a3b..511d1c96 100644
--- a/src/print.jl
+++ b/src/print.jl
@@ -144,6 +144,12 @@ function print_inlinecomment(io::IOBuffer, fst::FST, s::State)
     ws, v = get(s.doc.comments, fst.startline, (0, ""))
     isempty(v) && return
     v = v[end] == '\n' ? v[nextind(v, 1):prevind(v, end)] : v
-    ws > 0 && write(io, repeat(" ", ws))
+    if ws > 0
+        write(io, repeat(" ", ws))
+    elseif startswith(v, "#=") && endswith(v, "=#")
+        # hack to overcome the bug noticed in https://github.com/domluna/JuliaFormatter.jl/issues/571#issuecomment-1114446297
+        # until multiline comments aren't moved to the end of the line.
+        write(io, " ")
+    end
     write(io, v)
 end


Test patch:
diff --git a/test/issues.jl b/test/issues.jl
index 286e64ba..e661d250 100644
--- a/test/issues.jl
+++ b/test/issues.jl
@@ -1407,4 +1407,16 @@
             whitespace_in_kwargs = false,
         ) == str_
     end
+
+    @testset "571" begin
+        s = """
+        arraycopy_common(false#=fwd=#, LLVM.Builder(B), orig, origops[1], gutils)
+        return nothing
+        """
+        s_ = """
+        arraycopy_common(false, LLVM.Builder(B), orig, origops[1], gutils) #=fwd=#
+        return nothing
+        """
+        @test format_text(s) == s_
+    end
 end