From e16782c208320138d77b88f2ff359e3e9e059e76 Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Sat, 11 Jul 2026 19:57:02 +0900 Subject: fix: レビュー指摘事項の修正(エラー戻り値統一、タイ延長、ネストリピート、専用エラーコード) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit High severity: - compose action エラー戻り値の validation キー統一(server.py) - ppmck/pyxel タイ & の duration 延長修正(_tie_pending フラグ導入) - pyxel ネストリピート対応(RepeatFrame + イベントスナップショット方式) Medium severity: - 専用エラーコード追加: VALIDATION_MISSING_PARAMETER, VALIDATION_INVALID_MODE, VALIDATION_INVALID_ACTION - SYSTEM_INTERNAL_ERROR キャッチ範囲拡大(compose/validate全体をtry/except) Low severity: - 設計書 line/column を1始まりに明記、APIレベルエラーコード追記 テスト: 129 passed, ruff: All checks passed --- src/mml_composemusic_mcp/parser_ppmck.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/mml_composemusic_mcp/parser_ppmck.py') diff --git a/src/mml_composemusic_mcp/parser_ppmck.py b/src/mml_composemusic_mcp/parser_ppmck.py index 34a7dd2..db91950 100644 --- a/src/mml_composemusic_mcp/parser_ppmck.py +++ b/src/mml_composemusic_mcp/parser_ppmck.py @@ -41,6 +41,7 @@ class PpmckParser: self.headers: list[tuple[str, str]] = [] self.loop_start: int | None = None self.tracks_seen: set[str] = set() + self._tie_pending: bool = False def _context_line(self, token: Token) -> str: lines = self.source.splitlines() @@ -202,6 +203,13 @@ class PpmckParser: else: break + if self._tie_pending: + # Tie: extend the last note/rest's duration instead of creating a new event + self._extend_last_note(ticks) + self.tick_position += ticks + self._tie_pending = False + return + if self.current_channel == "Noise": self.ctx.add_error( code=ErrorCode.SYNTAX_CHANNEL_MISMATCH, @@ -242,6 +250,11 @@ class PpmckParser: self.ctx.advance() length, dots = self._read_length() ticks = length_value_to_ticks(length, dots) + if self._tie_pending: + self._extend_last_note(ticks) + self.tick_position += ticks + self._tie_pending = False + return event = RestEvent(tick_position=self.tick_position, duration=ticks) self._add_event(event) self.tick_position += ticks @@ -372,11 +385,11 @@ class PpmckParser: self._extend_last_note(ticks) self.tick_position += ticks return - # For note/rest, parser will create next event; we just note that previous - # event should be merged. Simple approach: reduce tick_position and mark. - # Here we just allow the next note to overwrite position and merge later. - # Implementation: back up tick position so next note duration adds to previous. + # For note/rest: back up tick_position so the next event starts at the + # end of the last note/rest. The next note's duration will be added + # to the previous note's duration via _tie_pending flag. self.tick_position = self._last_note_end() + self._tie_pending = True def _last_note_end(self) -> int: ch = self.note_sequence.channels[self.current_channel] # type: ignore[index] -- cgit v1.2.3