Repository: aiscript-dev/aiscript (ts)

Issue:
複数行コメントの途中でEOFになってもエラーにならない
以下のように、複数行コメントの途中でEOFとなるコードが文法エラーにならない。
```js
/* comment
```

ただし、EOFの直前が`*`である場合は、「end of stream」エラーが出る。
```js
/* *
```

Pull request description:
fix: 複数行コメントの*/がないと文法エラーが出るように
<!-- ℹ お読みください
PRありがとうございます！ PRを作成する前に、以下をご確認ください:
- 可能であればタイトルに、以下で示すようなPRの種類が分かるキーワードをプリフィクスしてください。
  - fix / refactor / feat / enhance / perf / chore
  - また、PRの粒度が適切であることを確認してください。ひとつのPRに複数の種類の変更や関心を含めることは避けてください。
- このPRによって解決されるIssueがある場合は、そのIssueへの参照を本文内に含めてください。
- unreleasedディレクトリ以下にファイルを新規に作成し、変更点を記してください。リファクタリングなど、利用者に影響を与えない変更についてはこの限りではありません。
- この変更により新たに作成、もしくは更新すべきドキュメントがないか確認してください。
- 機能追加やバグ修正をした場合は、可能であればテストケースを追加してください。
- テスト、Lintが通っていることを予め確認してください。
  - `npm run test`、`npm run lint`でぞれぞれ実施可能です
- `npm run api`を実行してAPIレポートを更新し、差分がある場合はコミットしてください。
ご協力ありがとうございます🤗
-->
<!-- ℹ README
Thank you for your PR! Before creating a PR, please check the following:
- If possible, prefix the title with a keyword that identifies the type of this PR, as shown below.
  - fix / refactor / feat / enhance / perf / chore
  - Also, make sure that the granularity of this PR is appropriate. Please do not include more than one type of change or interest in a single PR.
- If there is an Issue which will be resolved by this PR, please include a reference to the Issue in the text.
- Please create a new file under the `unreleased` directory and write down the summary of your changes. However, this is not necessary for changes that do not affect the users, such as refactoring.
- Check if there are any documents that need to be created or updated due to this change.
- If you have added a feature or fixed a bug, please add a test case if possible.
- Please make sure that tests and Lint are passed in advance.
  - You can run it with `npm run test` and `npm run lint`.
- Run `npm run api` to update the API report and commit it if there are any diffs.
Thanks for your cooperation 🤗
-->

# What
<!-- このPRで何をしたのか？ どう変わるのか？ -->
<!-- What did you do with this PR? How will it change things? -->
複数行コメントを`*/`で閉じないと「unexpected EOF」の文法エラーが出るようにします。

# Why
<!-- なぜそうするのか？ どういう意図なのか？ 何が困っているのか？ -->
<!-- Why do you do it? What are your intentions? What is the problem? -->
- Resolve #876

# Additional info (optional)
<!-- テスト観点など -->
<!-- Test perspective, etc -->


Patch:
diff --git a/package-lock.json b/package-lock.json
index b3f0339..ebe5441 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,7 +19,6 @@
 				"@types/eslint__js": "8.42.3",
 				"@types/node": "22.10.2",
 				"@types/seedrandom": "3.0.8",
-				"@types/uuid": "10.0.0",
 				"@vitest/coverage-v8": "2.1.8",
 				"chalk": "5.4.1",
 				"eslint": "9.17.0",
@@ -1394,13 +1393,6 @@
 			"dev": true,
 			"license": "MIT"
 		},
-		"node_modules/@types/uuid": {
-			"version": "10.0.0",
-			"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz",
-			"integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==",
-			"dev": true,
-			"license": "MIT"
-		},
 		"node_modules/@typescript-eslint/eslint-plugin": {
 			"version": "8.18.2",
 			"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.2.tgz",
diff --git a/package.json b/package.json
index b48f1d1..0edba85 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,6 @@
 		"@types/eslint__js": "8.42.3",
 		"@types/node": "22.10.2",
 		"@types/seedrandom": "3.0.8",
-		"@types/uuid": "10.0.0",
 		"@vitest/coverage-v8": "2.1.8",
 		"chalk": "5.4.1",
 		"eslint": "9.17.0",
diff --git a/playground/package-lock.json b/playground/package-lock.json
index 0d7c797..9487ea1 100644
--- a/playground/package-lock.json
+++ b/playground/package-lock.json
@@ -29,21 +29,20 @@
         "uuid": "11.0.3"
       },
       "devDependencies": {
-        "@eslint/js": "9.15.0",
-        "@microsoft/api-extractor": "7.48.0",
+        "@eslint/js": "9.17.0",
+        "@microsoft/api-extractor": "7.48.1",
         "@types/eslint__js": "8.42.3",
-        "@types/node": "22.10.1",
+        "@types/node": "22.10.2",
         "@types/seedrandom": "3.0.8",
-        "@types/uuid": "10.0.0",
-        "@vitest/coverage-v8": "2.1.6",
-        "chalk": "5.3.0",
-        "eslint": "9.15.0",
+        "@vitest/coverage-v8": "2.1.8",
+        "chalk": "5.4.1",
+        "eslint": "9.17.0",
         "eslint-plugin-import": "2.31.0",
         "semver": "7.6.3",
         "ts-node": "10.9.2",
         "typescript": "5.7.2",
-        "typescript-eslint": "8.16.0",
-        "vitest": "2.1.6"
+        "typescript-eslint": "8.18.2",
+        "vitest": "2.1.8"
       }
     },
     "node_modules/@babel/helper-string-parser": {
diff --git a/src/parser/scanner.ts b/src/parser/scanner.ts
index 5cab470..2802b06 100644
--- a/src/parser/scanner.ts
+++ b/src/parser/scanner.ts
@@ -628,10 +628,13 @@ export class Scanner implements ITokenStream {
 	private skipCommentRange(): void {
 		while (true) {
 			if (this.stream.eof) {
-				break;
+				throw new AiScriptUnexpectedEOFError(this.stream.getPos());
 			}
 			if (this.stream.char === '*') {
 				this.stream.next();
+				if (this.stream.eof) {
+					throw new AiScriptUnexpectedEOFError(this.stream.getPos());
+				}
 				if ((this.stream.char as string) === '/') {
 					this.stream.next();
 					break;


Test patch:
diff --git a/test/syntax.ts b/test/syntax.ts
index e6b3b93..f837929 100644
--- a/test/syntax.ts
+++ b/test/syntax.ts
@@ -2,7 +2,7 @@ import * as assert from 'assert';
 import { describe, test } from 'vitest';
 import { utils } from '../src';
 import { NUM, STR, NULL, ARR, OBJ, BOOL, TRUE, FALSE, ERROR ,FN_NATIVE } from '../src/interpreter/value';
-import { AiScriptRuntimeError } from '../src/error';
+import { AiScriptRuntimeError, AiScriptUnexpectedEOFError } from '../src/error';
 import { exe, getMeta, eq } from './testutils';
 
 /*
@@ -514,6 +514,16 @@ describe('Comment', () => {
 		`);
 		eq(res, STR('a'));
 	});
+
+	test.concurrent('invalid EOF in multi line comment', async () => {
+		await assert.rejects(() => exe(`
+		/* comment
+		`), AiScriptUnexpectedEOFError);
+	});
+
+	test.concurrent('invalid EOF in multi line comment 2', async () => {
+		await assert.rejects(() => exe('/* comment *'), AiScriptUnexpectedEOFError);
+	});
 });
 
 describe('lang version', () => {