printObjectFlowメソッド中のコード追加と, バグ修正.
printObjectFlowメソッド中に, 取得したエイリアスリストの中身を確認するコードと,
各エイリアスに記録されたメソッドのソースコードを対象Eclipse側で開かせる処理の呼び出しを追加.

parseFQCNParametersメソッドにおいて,
IMethodから取得した各引数の型のクラスがデフォルトパッケージに属している場合にも, .が型名の前に入ってしまうバグを修正.
1 parent 7da03b6 commit ec12feeefbafe627a0dc3aad06b353559a794341
r-isitani authored on 22 Jul 2018
Showing 1 changed file
View
75
org.ntlab.reverseDebugger/src/org/ntlab/debuggingControl/DebuggingControlAction.java
String methodName = "getCurrentMethodExecution";
Value methodExecution = callInstanceMethod(vm, thread, methodName, (ObjectReference)threadInstance);
Scanner scanner = new Scanner(System.in);
 
// curMethodExecutionの最終ステートメントを取得
// curMethodExecutionの指定したステートメントを取得
methodName = "getStatements";
Value statements = callInstanceMethod(vm, thread, methodName, (ObjectReference)methodExecution);
methodName = "size";
int statementsSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)statements)).value();
int order = scanner.nextInt();
Value statementOrder = vm.mirrorOf((order >= 0 && order < statementsSize) ? order : statementsSize - 1);
methodName = "get";
Value statement = callInstanceMethod(vm, thread, methodName, (ObjectReference)statements, statementOrder);
 
// エイリアス生成に用いるobjIdとtpを取得
String packageName = "org.ntlab.traceCollector.tracer.trace";
String className = "TraceJSON";
methodName = "findValueObjId";
Value valueObjId = callStaticMethod(vm, thread, packageName, className, methodName, statement, occurrenceEXP);
methodName = "getTracePoint";
Value tp = callInstanceMethod(vm, thread, methodName, (ObjectReference)methodExecution, statementOrder);
// スタートとなるエイリアスを生成
// スタートとなるエイリアスを生成してgetObjectFlowを実行
methodName = "getAlias";
Value alias = callStaticMethod(vm, thread, packageName, className, methodName, valueObjId, tp, occurrenceEXP);
Value startAlias = callStaticMethod(vm, thread, packageName, className, methodName, valueObjId, tp, occurrenceEXP);
methodName = "toString";
Value str = callInstanceMethod(vm, thread, methodName, (ObjectReference)alias);
Value str = callInstanceMethod(vm, thread, methodName, (ObjectReference)startAlias);
printValue("", "", str, true);
methodName = "getObjectFlow";
Value aliasLists = callStaticMethod(vm, thread, packageName, className, methodName, startAlias);
System.out.println();
// getObjectFlowを実行
methodName = "getObjectFlow";
Value result = callStaticMethod(vm, thread, packageName, className, methodName, alias);
System.out.println();
System.out.println(result);
}
// 取得したリストの中身をループで回しながら確認し, ついでに当該ソースファイルを対象Eclipseで開かせてみる
methodName = "size";
int aliasListsSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasLists)).value();
for (int i = 0; i < aliasListsSize; i++) {
System.out.println("---------------------------------------------");
System.out.println("リスト" + i);
methodName = "get";
Value aliasList = callInstanceMethod(vm, thread, methodName,(ObjectReference)aliasLists, vm.mirrorOf(i));
methodName = "size";
int aliasListSize = ((IntegerValue)callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList)).value();
for (int j = 0; j < aliasListSize; j++) {
methodName = "get";
Value alias = callInstanceMethod(vm, thread, methodName, (ObjectReference)aliasList, vm.mirrorOf(j));
methodName = "toString";
Value str2 = callInstanceMethod(vm, thread, methodName, (ObjectReference)alias);
printValue("", "", str2, true);
methodName = "getMethodExecution";
Value aliasMethodExecution = callInstanceMethod(vm ,thread, methodName, (ObjectReference)alias);
openSrcFileOfMethodExecution(vm, thread, aliasMethodExecution);
}
}
}
/**
* 引数で渡したthreadInstanceの呼び出しスタック上のメソッドについての各種データを取得して表示する
* @param vm
if (type != null && method != null) {
IEditorPart editor = JavaUI.openInEditor(type);
if (!type.isLocal() && !type.isMember()) {
JavaUI.revealInEditor(editor, (IJavaElement)method);
System.out.println("JavaUI.revealInEditor() を呼び出したよ!");
}
}
} catch (PartInitException | JavaModelException e) {
e.printStackTrace();
String fqcn = type.getFullyQualifiedName();
try {
StringBuilder jdtMethodSignature = new StringBuilder();
jdtMethodSignature.append((method.isConstructor()) ? (fqcn + "(") : (fqcn + "." + method.getElementName() + "("));
System.out.println(jdtMethodSignature);
if (methodSignature.contains(jdtMethodSignature)) {
// 部分一致していた場合に限り、引数リストを加えた上でも一致するかどうかを判定 (オーバーロードによる誤判定を避ける)
jdtMethodSignature.append(String.join(",", parseFQCNParameters(type, method)) + ")"); // 全引数のシグネチャを完全限定名に変換して,で区切った文字列
System.out.println(jdtMethodSignature);
jdtMethodSignature.append(String.join(",", parseFQCNParameters(type, method)) + ")"); // 全引数のシグネチャを完全限定クラス名に変換して,で区切った文字列
return methodSignature.contains(jdtMethodSignature);
}
} catch (JavaModelException e) {
e.printStackTrace();
return false;
}
 
/**
* IMethodから取得できる全引数のシグネチャを完全限定名に置き換えて格納したリストを返す
* IMethodから取得できる全引数のシグネチャを完全限定クラス名に置き換えて格納したリストを返す
* @param type
* @param method
* @return
* @throws JavaModelException
*/
private List<String> parseFQCNParameters(IType type, IMethod method) throws JavaModelException {
List<String> parameters = new ArrayList<>();
for (String parameterType : method.getParameterTypes()) {
readableTypeSplit[1] = readableType.substring(firstBracketIndex); // 型名の後ろの[]全て
}
String[][] resolveType = type.resolveType(readableTypeSplit[0]); // パッケージ名とクラス名の組み合わせを取得
if (resolveType != null) {
readableTypeSplit[0] = (resolveType[0][0] + "." + resolveType[0][1]); // 完全限定名
if (resolveType[0][0].isEmpty()) {
readableTypeSplit[0] = (resolveType[0][1]); // デフォルトパッケージの場合はパッケージ名と.は入れない
} else {
readableTypeSplit[0] = (resolveType[0][0] + "." + resolveType[0][1]); // 完全限定クラス名
}
}
parameters.add(readableTypeSplit[0] + readableTypeSplit[1]);
}
return parameters;