From 0b1999b8edd9570b5b35b649a81ff48c1583bb81 Mon Sep 17 00:00:00 2001 From: Hugo van Rijswijk Date: Wed, 19 Aug 2026 16:30:07 +0200 Subject: [PATCH] Accept a comment at the end of a file The comment parser required a line terminator after the comment text. A comment at the end of the file has none, so the whole document failed to parse. The terminator is now `charIn('\n', '\r') | Parser.end`. --- modules/core/src/main/scala/parser.scala | 6 ++++-- modules/core/src/test/scala/parser/ParserSuite.scala | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/core/src/main/scala/parser.scala b/modules/core/src/main/scala/parser.scala index ee9d0146..cf9e15b3 100644 --- a/modules/core/src/main/scala/parser.scala +++ b/modules/core/src/main/scala/parser.scala @@ -505,11 +505,13 @@ object GraphQLParser { /** * Parser that consumes a comment + * + * A comment ends at a line terminator or at the end of the file. */ val comment: Parser[Unit] = - (char('#') *> charWhere(c => c != '\n' && c != '\r').rep0 <* charIn( + (char('#') *> charWhere(c => c != '\n' && c != '\r').rep0 <* (charIn( '\n', - '\r') <* skipWhitespace).void + '\r').void | Parser.end) <* skipWhitespace).void /** * Turns a parser into one that skips trailing whitespace and comments diff --git a/modules/core/src/test/scala/parser/ParserSuite.scala b/modules/core/src/test/scala/parser/ParserSuite.scala index 384c5fa8..7697f8aa 100644 --- a/modules/core/src/test/scala/parser/ParserSuite.scala +++ b/modules/core/src/test/scala/parser/ParserSuite.scala @@ -971,6 +971,15 @@ final class ParserSuite extends CatsEffectSuite { assertEquals(resFail, Result.failure(expectedFail)) } + test("comment at end of file without a line terminator") { + val expected = + List(Operation(Query, None, Nil, Nil, List(Field(None, Name("x"), Nil, Nil, Nil)))) + + assertEquals(parser.parseText("query { x } # done"), Result(expected)) + assertEquals(parser.parseText("query { x } #"), Result(expected)) + assertEquals(parser.parseText("query { # inner\n x } # a\n# b"), Result(expected)) + } + def mkParser( maxSelectionDepth: Int = GraphQLParser.defaultConfig.maxSelectionDepth, maxSelectionWidth: Int = GraphQLParser.defaultConfig.maxSelectionWidth,