kusumotolab / kGenProg

A High-performance, High-extensibility and High-portability APR System
MIT License
48 stars 13 forks source link

一部の Windows10 環境で PatchSerializerTest に失敗する #797

Closed hrtwt closed 3 years ago

hrtwt commented 4 years ago

起こっていること

CI と @hrtwt の使用しているPC3台の win10 環境で PatchSerializerTest#testPatch に失敗する. @hrtwt の環境では master(v1.7.4) でも失敗する.

失敗のフロー (手元で調べた,CIはどうなってるか不明)

試したこと

tt-kuma commented 3 years ago

intellijからテスト実行したら成功したが,gradle testでテストしたら失敗した.

ty-v1 commented 3 years ago

自分のWindows環境での調査

エンコーディングの確認

windows環境によってテスト結果が異なるのは,テストの実行方法の違いが原因でよさそう

ty-v1 commented 3 years ago

原因

実行環境の文字コードがUTF-8以外かつマルチバイト文字が修正対象に含まれるときに,ASTの操作に失敗するため.

詳細

kGPはソースコードとASTを保持している. https://github.com/kusumotolab/kGenProg/blob/32f06b8e23f126e763887fe95968a85b21e9f55d/src/main/java/jp/kusumotolab/kgenprog/project/jdt/GeneratedJDTAST.java#L22-L25

753によってソースコードは,UTF-8で保持される.一方で,ASTはデフォルトのエンコーディングとして読み込まれたソースコードから作られる.

https://github.com/kusumotolab/kGenProg/blob/32f06b8e23f126e763887fe95968a85b21e9f55d/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTASTConstruction.java#L75

UTF-8のファイルをwindows-31jとして読み込んだため,AST側のソースコードとkGP側のソースコードでノードと位置の対応がとれなくなる.そのため,ASTへの操作をkGP側のソースコードに適用できなくなり,パッチが生成できずテストが落ちる.

https://github.com/kusumotolab/kGenProg/blob/7871b21e7cc4e6408b34d048393f7aff53b45ae2/src/main/java/jp/kusumotolab/kgenprog/project/jdt/JDTOperation.java#L52-L58

ty-v1 commented 3 years ago

下のコードのメソッドの最後にa++を挿入する時を考える.  

public class Sample {

  /**
   * Java学習用のサンプル
   * 変数宣言と単項演算子のサンプルである
   */
  method() {
    int a = 0;
  }
}

windows環境で実行すると,JDTは上のコードをwindows-31jとして読み込みASTを作る.

public class Sample {

  /**
   * Java蟄ヲ鄙堤畑縺ョ繧オ繝ウ繝励Ν
   * 螟画焚螳」險?縺ィ蜊倬??シ皮ョ怜ュ舌?繧オ繝ウ繝励Ν縺ァ縺ゅk
   */
  method() {
    int a = 0;
  }
}

windows-31jとして読み込んだコードから生成されるAST image

このASTにa++を挿入すると以下のASTができる. image

public class Sample {

  /**
   * Java蟄ヲ鄙堤畑縺ョ繧オ繝ウ繝励Ν
   * 螟画焚螳」險?縺ィ蜊倬??シ皮ョ怜ュ舌?繧オ繝ウ繝励Ν縺ァ縺ゅk
   */
  method() {
    int a = 0;
    a++;
  }
}

一方で,UTF-8として読み込んだコードから以下のASTが生成される. image

UTF-8として読み込んだコードは109文字であるため,このASTに対して操作を適用,つまり126文字目にa++を挿入することはできない.そのため,MalformedTreeExceptionが発生する.