diff --git a/src/org/ntlab/traceDebugger/VariableViewRelatedDelta.java b/src/org/ntlab/traceDebugger/VariableViewRelatedDelta.java index 7a92308..78b0af8 100644 --- a/src/org/ntlab/traceDebugger/VariableViewRelatedDelta.java +++ b/src/org/ntlab/traceDebugger/VariableViewRelatedDelta.java @@ -59,30 +59,11 @@ super.createActions(); jumpAction = new Action() { public void run() { - TracePoint tp = null; TracePoint before = DebuggingController.getInstance().getCurrentTp(); - VariableType variableType = selectedVariable.getVariableType(); - if (variableType.equals(VariableType.USE_VALUE)) { - String containerId = selectedVariable.getContainerId(); - String fieldName = selectedVariable.getFullyQualifiedVariableName(); - tp = VariableUpdatePointFinder.getInstance().getPoint(containerId, fieldName, before); - } else if (variableType.equals(VariableType.USE_RETURN)) { - String receiverId = selectedVariable.getContainerId(); - String valueId = selectedVariable.getValueId(); - String receiverClassName = selectedVariable.getContainerClassName(); - VariableUpdatePointFinder finder = VariableUpdatePointFinder.getInstance(); - if (receiverClassName.contains("Iterator") || receiverClassName.contains("Itr") - || receiverClassName.contains("Collections$UnmodifiableCollection$1")) { - tp = finder.getIteratorPoint(receiverId); - if (tp == null) return; - MethodInvocation mi = ((MethodInvocation)tp.getStatement()); - receiverId = mi.getCalledMethodExecution().getThisObjId(); - } - tp = finder.getDefinitionInvocationPoint(receiverId, valueId, before); - } - if (tp == null) return; + TracePoint jumpPoint = findJumpPoint(selectedVariable, before); + if (jumpPoint == null) return; DebuggingController controller = DebuggingController.getInstance(); - controller.jumpToTheTracePoint(tp, false); + controller.jumpToTheTracePoint(jumpPoint, false); } }; jumpAction.setText("Jump to Definition"); @@ -121,6 +102,54 @@ deltaActionForThisToAnother.setToolTipText("Extract Delta"); } + private TracePoint findJumpPoint(Variable variable, TracePoint before) { + VariableType variableType = selectedVariable.getVariableType(); + if (variableType.equals(VariableType.USE_VALUE)) { + String containerId = selectedVariable.getContainerId(); + String fieldName = selectedVariable.getFullyQualifiedVariableName(); + return VariableUpdatePointFinder.getInstance().getPoint(containerId, fieldName, before); + } else if (variableType.equals(VariableType.USE_RETURN)) { + return findJumpPointWithReturnValue(variable, before); + } + return null; + } + + private TracePoint findJumpPointWithReturnValue(Variable variable, TracePoint before) { + TracePoint tp = null; + String receiverId = selectedVariable.getContainerId(); + String valueId = selectedVariable.getValueId(); + String receiverClassName = selectedVariable.getContainerClassName(); + VariableUpdatePointFinder finder = VariableUpdatePointFinder.getInstance(); + + // note: �C�e���[�^�̏ꍇ�͂��̃C�e���[�^�̎擾���̃R���N�V������ID�����ɂ��� + if (receiverClassName.contains("Iterator") || receiverClassName.contains("Itr") + || receiverClassName.contains("Collections$UnmodifiableCollection$1")) { + tp = finder.getIteratorPoint(receiverId); // �C�e���[�^�擾���̃|�C���g���擾 + if (tp == null) return null; + MethodInvocation mi = ((MethodInvocation)tp.getStatement()); + receiverId = mi.getCalledMethodExecution().getThisObjId(); // �C�e���[�^�̎擾���̃R���N�V������ID + receiverClassName = mi.getCalledMethodExecution().getThisClassName(); // �C�e���[�^�̎擾���̃R���N�V�����̃N���X�� + } + + // note: �W�����v��ƂȂ� �I�u�W�F�N�g�̑���|�C���g�������̓R���N�V�����ւ̒lj��|�C���g���擾 + tp = finder.getDefinitionInvocationPoint(receiverId, valueId, before); + + // note: �W�����v��̃|�C���g�����‚���Ȃ������ꍇ�ŁA���ƒR���N�V�����ւ̒lj��|�C���g��T���Ă���ꍇ�̓R���N�V�����̏悹�������Œlj����Ă��Ȃ�����T���ɍs�� + if (tp == null && receiverClassName.startsWith("java.util.")) { + String afterCollectionId = receiverId; + while (true) { + tp = finder.getTransferCollectionPoint(afterCollectionId, before); + if (tp == null) break; // �R���N�V�����̏悹������������ȏ�Ȃ��ꍇ + MethodInvocation mi = ((MethodInvocation)tp.getStatement()); + String fromCollectionId = mi.getCalledMethodExecution().getArguments().get(0).getId(); + tp = finder.getDefinitionInvocationPoint(fromCollectionId, valueId, before); + if (tp != null) break; // �R���N�V�����̏悹�������ŃI�u�W�F�N�g�̒lj������‚������ꍇ + afterCollectionId = fromCollectionId; + } + } + return tp; + } + @Override protected void createPopupMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); @@ -183,20 +212,6 @@ deltaActionForContainerToComponent.setText(""); deltaActionForContainerToComponent.setToolTipText(""); return false; - -// String containerId = selectedVariable.getContainerId(); -// String containerClassName = selectedVariable.getContainerClassName(); -// if (containerId != null && containerClassName != null) { -// containerClassName = containerClassName.substring(containerClassName.lastIndexOf(".") + 1); -// String textForContainerToComponent = String.format("Extract Delta [ %s (id = %s) -> %s (id = %s) ]", containerClassName, containerId, valueClassName, valueId); -// deltaActionForContainerToComponent.setText(textForContainerToComponent); -// deltaActionForContainerToComponent.setToolTipText(textForContainerToComponent); -// return true; -// } else { -// deltaActionForContainerToComponent.setText(""); -// deltaActionForContainerToComponent.setToolTipText(""); -// return false; -// } } private boolean updateDeltaActionForThisToAnotherTexts(Variable variable) { diff --git a/src/org/ntlab/traceDebugger/analyzerProvider/VariableUpdatePointFinder.java b/src/org/ntlab/traceDebugger/analyzerProvider/VariableUpdatePointFinder.java index d431199..b6e2660 100644 --- a/src/org/ntlab/traceDebugger/analyzerProvider/VariableUpdatePointFinder.java +++ b/src/org/ntlab/traceDebugger/analyzerProvider/VariableUpdatePointFinder.java @@ -22,6 +22,7 @@ private Map>> updatePoints = new HashMap<>(); // �R���e�iID�ƃt�B�[���h�����L�[�ɂ����ϐ��X�V�|�C���g private Map>> definitionInvocationPoints = new HashMap<>(); // ���V�[�oID�ƈ���ID���L�[�ɂ����R���N�V�����ւ̒lj��|�C���g private Map gettingIteratorPoints = new HashMap<>(); // �C�e���[�^��ID���L�[�ɂ�����擾�����|�C���g + private Map> changeOtherCollectionPoints = new HashMap<>(); // �悹������̃R���N�V����ID���L�[�ɂ�����悹�������n�_�̃|�C���g public void setTrace(Trace trace) { this.trace = trace; @@ -54,12 +55,22 @@ } else if (statement instanceof MethodInvocation) { MethodInvocation mi = (MethodInvocation)statement; MethodExecution calledME = mi.getCalledMethodExecution(); - String methodName = calledME.getSignature(); + String methodName = calledME.getSignature(); + List args = calledME.getArguments(); if (methodName.contains(".add(") || methodName.contains(".addElement(")) { registerdefinitionInvocationPoint(start, calledME); } else if (methodName.contains(".iterator(") || methodName.contains("Iterator(")) { registerIteratorPoint(start, calledME); - } + } else if (args.size() == 1 && args.get(0).getActualType().startsWith("java.util.")) { + ObjectReference returnValue = calledME.getReturnValue(); + if (calledME.getThisClassName().startsWith("java.util.") && !(calledME.getThisObjId().equals("0"))) { + String toCollectionId = calledME.getThisObjId(); + registerChangeOtherCollectionPoint(start, toCollectionId); + } else if (returnValue != null && returnValue.getActualType().startsWith("java.util.")) { + String toCollectionId = returnValue.getId(); + registerChangeOtherCollectionPoint(start, toCollectionId); + } + } } } } @@ -71,19 +82,6 @@ String fieldName = fu.getFieldName(); register(updatePoints, objectId, fieldName, tp); } - -// private void registerdefinitionInvocationPoints(TracePoint tp, MethodInvocation mi) { -// MethodExecution calledME = mi.getCalledMethodExecution(); -// String methodName = calledME.getSignature(); -// List args = calledME.getArguments(); -// if (methodName.contains(".add(") || methodName.contains(".addElement(")) { -// if (args.size() == 1) { -// String receiverId = calledME.getThisObjId(); -// String argId = args.get(0).getId(); -// register(definitionInvocationPoints, receiverId, argId, tp); -// } -// } -// } private void registerdefinitionInvocationPoint(TracePoint tp, MethodExecution calledME) { List args = calledME.getArguments(); @@ -100,6 +98,15 @@ gettingIteratorPoints.put(iteratorId, tp.duplicate()); } + private void registerChangeOtherCollectionPoint(TracePoint tp, String toCollectionId) { + List tracePoints = changeOtherCollectionPoints.get(toCollectionId); + if (tracePoints == null) { + tracePoints = new ArrayList(); + changeOtherCollectionPoints.put(toCollectionId, tracePoints); + } + tracePoints.add(tp.duplicate()); + } + private void register(Map>> map, String key1, String key2, TracePoint tp) { Map> innerMap = map.get(key1); if (innerMap == null) { @@ -141,6 +148,18 @@ return gettingIteratorPoints.get(iteratorId); } + public TracePoint getTransferCollectionPoint(String toCollectionId, TracePoint before) { + List tracePoints = changeOtherCollectionPoints.get(toCollectionId); + long beforeTime = before.getStatement().getTimeStamp(); + TracePoint tmp = null; + for (TracePoint tp : tracePoints) { + long time = tp.getStatement().getTimeStamp(); + if (time >= beforeTime) return tmp; + tmp = tp; + } + return tmp; + } + private TracePoint getPoint(Map>> map, String key1, String key2, TracePoint before) { Map> innerMap = map.get(key1); if (innerMap == null) return null;