Correctly handle EOF after unmatched backtick (#1187)

This commit is contained in:
Jen Basch
2025-08-25 14:31:26 -07:00
committed by GitHub
parent b32039a4f1
commit a8806416b9
5 changed files with 31 additions and 2 deletions
@@ -1,5 +1,5 @@
/* /*
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved. * Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -64,4 +64,11 @@ class ReplMessagesTest {
startIndex = examples.indexOf("```", endIndex + 3) startIndex = examples.indexOf("```", endIndex + 3)
} }
} }
@Test
fun `handle single backtick`() {
val responses = server.handleRequest(ReplRequest.Eval("1", "`", true, true))
assertThat(responses.size).isEqualTo(1)
assertThat(responses).hasOnlyElementsOfType(ReplResponse.EvalError::class.java)
}
} }
@@ -0,0 +1 @@
`
@@ -0,0 +1,7 @@
–– Pkl Error ––
Unexpected character `
`. Did you mean `backquote`?
x | `
^
at singleBacktick (file:///$snippetsDir/input/errors/singleBacktick.pkl)
@@ -489,7 +489,7 @@ public class Lexer {
} }
private void lexQuotedIdentifier() { private void lexQuotedIdentifier() {
while (lookahead != '`' && lookahead != '\n' && lookahead != '\r') { while (lookahead != '`' && lookahead != '\n' && lookahead != '\r' && lookahead != EOF) {
nextChar(); nextChar();
} }
if (lookahead == '`') { if (lookahead == '`') {
@@ -705,6 +705,13 @@ public class Lexer {
} }
private ParserError unexpectedChar(char got, String didYouMean) { private ParserError unexpectedChar(char got, String didYouMean) {
if (got == EOF) {
return unexpectedChar("EOF", didYouMean);
}
return lexError("unexpectedCharacter", got, didYouMean);
}
private ParserError unexpectedChar(String got, String didYouMean) {
return lexError("unexpectedCharacter", got, didYouMean); return lexError("unexpectedCharacter", got, didYouMean);
} }
@@ -17,6 +17,7 @@ package org.pkl.parser
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
class LexerTest { class LexerTest {
@@ -46,4 +47,10 @@ class LexerTest {
assertThat(Lexer.maybeQuoteIdentifier("this")).isEqualTo("`this`") assertThat(Lexer.maybeQuoteIdentifier("this")).isEqualTo("`this`")
assertThat(Lexer.maybeQuoteIdentifier("😀")).isEqualTo("`😀`") assertThat(Lexer.maybeQuoteIdentifier("😀")).isEqualTo("`😀`")
} }
@Test
fun lexSingleBacktick() {
val thrown = assertThrows<ParserError> { Lexer("`").next() }
assertThat(thrown).hasMessageContaining("Unexpected character `EOF`")
}
} }