summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibJS/Lexer.cpp4
-rw-r--r--Userland/Libraries/LibJS/Tests/comments-basic.js9
-rw-r--r--Userland/Utilities/js.cpp29
3 files changed, 14 insertions, 28 deletions
diff --git a/Userland/Libraries/LibJS/Lexer.cpp b/Userland/Libraries/LibJS/Lexer.cpp
index cf4c052072..1245817d5b 100644
--- a/Userland/Libraries/LibJS/Lexer.cpp
+++ b/Userland/Libraries/LibJS/Lexer.cpp
@@ -308,7 +308,9 @@ bool Lexer::is_line_comment_start(bool line_has_token_yet) const
// "-->" is considered a line comment start if the current line is only whitespace and/or
// other block comment(s); or in other words: the current line does not have a token or
// ongoing line comment yet
- || (match('-', '-', '>') && !line_has_token_yet);
+ || (match('-', '-', '>') && !line_has_token_yet)
+ // https://tc39.es/proposal-hashbang/out.html#sec-updated-syntax
+ || (match('#', '!') && m_position == 1);
}
bool Lexer::is_block_comment_start() const
diff --git a/Userland/Libraries/LibJS/Tests/comments-basic.js b/Userland/Libraries/LibJS/Tests/comments-basic.js
index 101e520a29..7ad452bf29 100644
--- a/Userland/Libraries/LibJS/Tests/comments-basic.js
+++ b/Userland/Libraries/LibJS/Tests/comments-basic.js
@@ -33,3 +33,12 @@ test("unterminated multi-line comment", () => {
expect("/* foo").not.toEval();
expect("foo /*").not.toEval();
});
+
+test("hashbang comments", () => {
+ expect("#!").toEvalTo(undefined);
+ expect("#!/bin/js").toEvalTo(undefined);
+ expect("#!\n1").toEvalTo(1);
+ expect(" #!").not.toEval();
+ expect("\n#!").not.toEval();
+ expect("#!\n#!").not.toEval();
+});
diff --git a/Userland/Utilities/js.cpp b/Userland/Utilities/js.cpp
index 6e2e617a00..69e45a178d 100644
--- a/Userland/Utilities/js.cpp
+++ b/Userland/Utilities/js.cpp
@@ -508,23 +508,6 @@ static void print(JS::Value value)
outln();
}
-static bool file_has_shebang(ByteBuffer const& file_contents)
-{
- if (file_contents.size() >= 2 && file_contents[0] == '#' && file_contents[1] == '!')
- return true;
- return false;
-}
-
-static StringView strip_shebang(ByteBuffer const& file_contents)
-{
- size_t i = 0;
- for (i = 2; i < file_contents.size(); ++i) {
- if (file_contents[i] == '\n')
- break;
- }
- return StringView((const char*)file_contents.data() + i, file_contents.size() - i);
-}
-
static bool write_to_file(const String& path)
{
int fd = open(path.characters(), O_WRONLY | O_CREAT | O_TRUNC, 0666);
@@ -650,9 +633,7 @@ static JS::Value load_file_impl(JS::VM& vm, JS::GlobalObject& global_object)
return {};
}
auto file_contents = file->read_all();
- auto source = file_has_shebang(file_contents)
- ? strip_shebang(file_contents)
- : StringView { file_contents };
+ auto source = StringView { file_contents };
auto parser = JS::Parser(JS::Lexer(source));
auto program = parser.parse_program();
if (parser.has_errors()) {
@@ -1099,13 +1080,7 @@ int main(int argc, char** argv)
return 1;
}
auto file_contents = file->read_all();
-
- StringView source;
- if (file_has_shebang(file_contents)) {
- source = strip_shebang(file_contents);
- } else {
- source = file_contents;
- }
+ auto source = StringView { file_contents };
builder.append(source);
}