switch文内のコメントからimportの整理バグを発動

とあるソースを改修することになった際に
import文がなぜかメソッドの中にあったり、それを削るとエラーになったりで
意味不明のままずっと謎だった記述の発生原因がわかりました。

簡単に説明するとswitch文の中に/** */ 形式でコメントを記述し
その状態でimport の整理をすると一部のimportが削除される現象が発生します。

実際にサンプルソースで説明します。

まずはswitch文とimportを必要とするクラスを入れたソースを記述
(サンプルは、条件によって描画の色を変更する簡単なクラス)

package
{
  import flash.display.Graphics;
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

次に上記のswitch文の中に/** */の形式でコメントを記述します。

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;

この状態でimportの整理(Ctrl+Shit+O)をすると、、

package
{
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

ソースからGraphicsクラスのimportが消えます!

そして、仕方なくこの状態でGraphicsクラスを定義している箇所(g:Graphics)で
コンテンツアシスト(Ctrl+Space)からGraphicsクラスを選択してimportしようとすると

package
{
  import flash.display.Sprite;

  public class SwitchTest extends Sprite
  {
    public function SwitchTest()
    {
      var hoge:uint = 0;

      switch (hoge)
      {
        /**
         * このコメントは危険です。
         */
        case 0:
          draw(this.graphics, 0xff0000);
          break;
        case 1:
          draw(this.graphics, 0xffff00);
          break;
      }
import flash.display.Graphics;

    }

    private function draw(g:Graphics, color:uint):void
    {
      g.clear();
      g.beginFill(color);
      g.drawRect(0, 0, 100, 100);
      g.endFill();
    }
  }
}

今度はGraphicsクラスのimportがメソッドの中に記述されます!!

これを発見したときはかなりの衝撃でした。

今回のサンプルでコンパイルするとエラーになってしまいますが、
エラーにならないこともあるようです。。
(実際自分が触ったソースはコンパイルとおってました。。。)

FlashBuilderのバグと言っていいとは思いますが、
メソッド内ではswitch文に限らず、クラスの説明などで使用する/** */形式での
コメントは避けるべきだと思われます。

ちなみに、
// 形式のコメントや、 /* */ 形式のコメントは問題ありませんでした。

Leave a Reply