Only allow shebangs in the beginning of a module (#1126)

This commit is contained in:
Islon Scherer
2025-07-18 11:18:45 +02:00
committed by GitHub
parent decb4ea66e
commit ba82c5c6d6
6 changed files with 20 additions and 4 deletions
@@ -0,0 +1,2 @@
foo = 1
#!/usr/bin/env pkl eval
@@ -0,0 +1,2 @@
#!/usr/bin/env pkl eval
foo = 1
@@ -0,0 +1,6 @@
–– Pkl Error ––
Invalid token at position. Expected a class, typealias, method, or property.
x | #!/usr/bin/env pkl eval
^^^^^^^^^^^^^^^^^^^^^^^
at shebang (file:///$snippetsDir/input/errors/shebang.pkl)
@@ -0,0 +1 @@
foo = 1
@@ -18,6 +18,7 @@ package org.pkl.parser;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.pkl.parser.syntax.Annotation; import org.pkl.parser.syntax.Annotation;
@@ -112,6 +113,7 @@ public class Parser {
if (lookahead == Token.EOF) { if (lookahead == Token.EOF) {
return new Module(Collections.singletonList(null), new Span(0, 0)); return new Module(Collections.singletonList(null), new Span(0, 0));
} }
if (lookahead == Token.SHEBANG) next();
var start = spanLookahead; var start = spanLookahead;
Span end = null; Span end = null;
ModuleDecl moduleDecl; ModuleDecl moduleDecl;
@@ -1787,16 +1789,16 @@ public class Parser {
private FullToken forceNext() { private FullToken forceNext() {
var tk = lexer.next(); var tk = lexer.next();
precededBySemicolon = false; precededBySemicolon = false;
while (tk == Token.LINE_COMMENT while (AFFIXES.contains(tk)) {
|| tk == Token.BLOCK_COMMENT
|| tk == Token.SEMICOLON
|| tk == Token.SHEBANG) {
precededBySemicolon = precededBySemicolon || tk == Token.SEMICOLON; precededBySemicolon = precededBySemicolon || tk == Token.SEMICOLON;
tk = lexer.next(); tk = lexer.next();
} }
return new FullToken(tk, lexer.span(), lexer.newLinesBetween); return new FullToken(tk, lexer.span(), lexer.newLinesBetween);
} }
private static final EnumSet<Token> AFFIXES =
EnumSet.of(Token.LINE_COMMENT, Token.BLOCK_COMMENT, Token.SEMICOLON);
// Like next, but don't ignore comments // Like next, but don't ignore comments
private FullToken nextComment() { private FullToken nextComment() {
prev = _lookahead; prev = _lookahead;
@@ -95,3 +95,6 @@ danglingDocComment=\
Dangling documentation comment.\n\ Dangling documentation comment.\n\
\n\ \n\
Documentation comments must be attached to modules, classes, typealiases, methods, or properties. Documentation comments must be attached to modules, classes, typealiases, methods, or properties.
wrongShebangPosition=\
Shebangs are only allowed at the very beginning of a file.