Skip to content

fix: preserve class inheritance (superclass) during Ruby round-trip #289

@takaokouji

Description

@takaokouji

Goal

Ruby タブで class Sprite1 < ::Smalruby3::Sprite, class Sprite1 < Smalruby3::Sprite, class Sprite1 < Foo と記述した場合、コードタブへの遷移(Ruby→ブロック変換)と Ruby タブへの復帰(ブロック→Ruby生成)のラウンドトリップで、継承の指定が消えずに保持されるようにする。

現状の問題

  1. コンバータ (index.js:403): superclass を「読み飛ばし」 — コメントにも classInfo にも保存しない
  2. コメント形式: @ruby:class:attr1,attr2,... に superclass フィールドがない
  3. ジェネレータ (index.js:327): forFileOutput 時に ' < ::Smalruby3::Sprite' をハードコード

コメント形式

@ruby:class コメントに <= プレフィックスで superclass を記録する。::: がコメント区切り文字と衝突するため / に置き換える。

Ruby コメント
class Sprite1 < ::Smalruby3::Sprite @ruby:class:<=//Smalruby3/Sprite
class Sprite1 < Smalruby3::Sprite @ruby:class:<=Smalruby3/Sprite
class Sprite1 < Sprite @ruby:class:<=Sprite
class Sprite1 < Foo @ruby:class:<=Foo
class Sprite1(継承なし) @ruby:class<= フィールドなし)

他属性との組み合わせ例: @ruby:class:<=//Smalruby3/Sprite,name=MySprite,x,y

Stage の制約

Stage クラスは以下のみ受け付ける(それ以外の superclass はエラー):

  • 継承なし: class Stage
  • class Stage < ::Smalruby3::Stage
  • class Stage < Smalruby3::Stage

Affected Files

  • packages/scratch-gui/src/lib/ruby-to-blocks-converter/index.jsvisitClassNode() で superclass をパースして <=X をコメントに追加
  • packages/scratch-gui/src/lib/ruby-generator/index.js_wrapWithClass()<=X をパースして継承文字列を生成
  • packages/scratch-gui/test/unit/lib/ruby-to-blocks-converter/class.test.js — superclass 保持テスト追加
  • packages/scratch-gui/test/unit/lib/ruby-generator/class.test.js — superclass 出力テスト追加
  • packages/scratch-gui/test/unit/lib/ruby-roundtrip-class-*.test.js — ラウンドトリップテスト追加

Implementation Steps

  • Phase 1: コンバータに superclass 保存を追加

    • [RED] converter class.test.js に superclass 保持テスト追加(::Smalruby3::Sprite, Smalruby3::Sprite, Foo, Sprite, 継承なし、Stage の受理/拒否)
    • [GREEN] visitClassNode() で superclass をパースし <=X コメントに保存
    • [PASS] lint + affected tests
    • [COMMIT & PUSH] + [MAKE PR]
  • Phase 2: ジェネレータで superclass を出力

    • [RED] generator class.test.js に superclass 出力テスト追加
    • [GREEN] _wrapWithClass()<=X をパースして出力
    • [PASS] lint + affected tests
    • [COMMIT & PUSH] + [UPDATE PR]
  • Phase 3: ラウンドトリップテスト

    • 3パターン以上のラウンドトリップテスト追加
    • [COMMIT & PUSH] + [UPDATE PR]

Test Plan

Type Timing Target
Unit tests (TDD) Phase 1, 2 converter の superclass パース、generator の superclass 出力
Round-trip tests Phase 3 ::Smalruby3::Sprite, Smalruby3::Sprite, Sprite, Foo, 継承なし

Risks & Open Questions

  • class Sprite1 < FooFoo は将来、別スプライトのクラス名となる予定。現時点ではコメントに保存するのみで VM 側の動作変更は不要

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions