2010-12-01 13 views

答えて

0

LocalVariablesSorter.visitLocalVariable方法でそれを拾います。私は以下のコードを使用しています

+0

私は以前visiLocalVariableを使用して試してみましたが、私は、変数へのすべてのアクセスを監視したいとvisitLocalVariableは、ローカル変数は – tomermes

+0

右宣言されたときにのみ呼ばれていました。これをビジターパターンで使用する場合は、indexから変数名へのマップを自分で保守する必要があります(visitLocalvariableへの呼び出しに基づいて)。もちろん、 – aioobe

+0

です。ありがとう。 – tomermes

2

private LocalVariableNode getLocalVariableNode(VarInsnNode varInsnNode, MethodNode methodNode) { 
     int varIdx = varInsnNode.var; 
     int instrIdx = getInstrIndex(varInsnNode); 
     List<?> localVariables = methodNode.localVariables; 
     for (int idx = 0; idx < localVariables.size(); idx++) { 
      LocalVariableNode localVariableNode = (LocalVariableNode) localVariables.get(idx); 
      if (localVariableNode.index == varIdx) { 
       int scopeEndInstrIndex = getInstrIndex(localVariableNode.end); 
       if (scopeEndInstrIndex >= instrIdx) { 
        // still valid for current line 
        return localVariableNode; 
       } 
      } 
     } 
     throw new RuntimeException("Variable with index " + varIdx + " and scope end >= " + instrIdx 
       + " not found for method " + methodNode.name + "!"); 
    } 

一般的な問題は、ローカル変数のインデックスを再利用することができるということです。したがって、特定のインデックスに対して正しいLocalVariableNodeを取得していることを確認する必要があります。これを行うには、指定された変数が使用されているコード位置で有効であることを確認する必要があります。

  1. 開始位置は、変数が定義された後に次のコード行であるため、問題は、あなたが行番号を使用することができないということです。空行とコメントは無視されるため、これは後続の行になります。しかし、コードは既存の変数を再利用できるので、これは現在の行の前の任意の行でもかまいません。

  2. 終了位置は、開始位置の直前(例えば、ループ内)にすることができる。

  3. コードが行情報なしでコンパイルされている可能性があります。

したがって、常に正しい命令インデックスを使用する必要があります。しかし、外部からアクセスできないAbstractInsnNodeの内部情報です。この問題を回避するために、次のコードを使用します。これは明らかにカプセル化を破るもので、さまざまな理由で推奨できません。あなたが何か良いことを考え出すなら、私に知らせてください!一方で、この作品:

private int getInstrIndex(AbstractInsnNode insnNode) { 
     try { 
      Field indexField = AbstractInsnNode.class.getDeclaredField("index"); 
      indexField.setAccessible(true); 
      Object indexValue = indexField.get(insnNode); 
      return ((Integer) indexValue).intValue(); 
     } catch (Exception exc) { 
      throw new RuntimeException(exc); 
     } 
    } 
関連する問題