Correctly handle EOF after unmatched backtick (#1187)

This commit is contained in:
Jen Basch
2025-08-25 14:31:26 -07:00
committed by Jen Basch
parent 1b49ec9422
commit f7951510b9
5 changed files with 31 additions and 2 deletions

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -64,4 +64,11 @@ class ReplMessagesTest {
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)
}
}

View File

@@ -0,0 +1 @@
`

View File

@@ -0,0 +1,7 @@
Pkl Error
Unexpected character `
`. Did you mean `backquote`?
x | `
^
at singleBacktick (file:///$snippetsDir/input/errors/singleBacktick.pkl)

View File

@@ -489,7 +489,7 @@ public class Lexer {
}
private void lexQuotedIdentifier() {
while (lookahead != '`' && lookahead != '\n' && lookahead != '\r') {
while (lookahead != '`' && lookahead != '\n' && lookahead != '\r' && lookahead != EOF) {
nextChar();
}
if (lookahead == '`') {
@@ -705,6 +705,13 @@ public class Lexer {
}
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);
}

View File

@@ -17,6 +17,7 @@ package org.pkl.parser
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
class LexerTest {
@@ -46,4 +47,10 @@ class LexerTest {
assertThat(Lexer.maybeQuoteIdentifier("this")).isEqualTo("`this`")
assertThat(Lexer.maybeQuoteIdentifier("😀")).isEqualTo("`😀`")
}
@Test
fun lexSingleBacktick() {
val thrown = assertThrows<ParserError> { Lexer("`").next() }
assertThat(thrown).hasMessageContaining("Unexpected character `EOF`")
}
}